Skip to content

Commit 3f15d29

Browse files
authored
Rollup merge of #131049 - compiler-errors:more-validation, r=spastorino
Validate args are correct for `UnevaluatedConst`, `ExistentialTraitRef`/`ExistentialProjection` For the `Existential*` ones, we have to do some adjustment to the args list to deal with the missing `Self` type, so we introduce a `debug_assert_existential_args_compatible` function to the interner as well.
2 parents 4d378f2 + 2239f1c commit 3f15d29

File tree

11 files changed

+104
-32
lines changed

11 files changed

+104
-32
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
259259
}
260260
})
261261
.collect();
262-
let args = tcx.mk_args(&args);
263262

264263
let span = i.bottom().1;
265264
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
@@ -292,7 +291,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
292291
.emit();
293292
}
294293

295-
ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
294+
ty::ExistentialTraitRef::new(tcx, trait_ref.def_id, args)
296295
})
297296
});
298297

compiler/rustc_middle/src/ty/consts.rs

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ impl<'tcx> Const<'tcx> {
109109

110110
#[inline]
111111
pub fn new_unevaluated(tcx: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Const<'tcx> {
112+
tcx.debug_assert_args_compatible(uv.def, uv.args);
112113
Const::new(tcx, ty::ConstKind::Unevaluated(uv))
113114
}
114115

compiler/rustc_middle/src/ty/context.rs

+20
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,26 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
279279
self.debug_assert_args_compatible(def_id, args);
280280
}
281281

282+
/// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
283+
/// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
284+
/// a dummy self type and forward to `debug_assert_args_compatible`.
285+
fn debug_assert_existential_args_compatible(
286+
self,
287+
def_id: Self::DefId,
288+
args: Self::GenericArgs,
289+
) {
290+
// FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
291+
// to avoid needing to reintern the set of args...
292+
if cfg!(debug_assertions) {
293+
self.debug_assert_args_compatible(
294+
def_id,
295+
self.mk_args_from_iter(
296+
[self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
297+
),
298+
);
299+
}
300+
}
301+
282302
fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
283303
where
284304
I: Iterator<Item = T>,

compiler/rustc_passes/src/reachable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ impl<'tcx> ReachableContext<'tcx> {
322322
self.visit(ty);
323323
// Manually visit to actually see the trait's `DefId`. Type visitors won't see it
324324
if let Some(trait_ref) = dyn_ty.principal() {
325-
let ExistentialTraitRef { def_id, args } = trait_ref.skip_binder();
325+
let ExistentialTraitRef { def_id, args, .. } = trait_ref.skip_binder();
326326
self.visit_def_id(def_id, "", &"");
327327
self.visit(args);
328328
}

compiler/rustc_privacy/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility,
3232
use rustc_middle::query::Providers;
3333
use rustc_middle::ty::print::PrintTraitRefExt as _;
3434
use rustc_middle::ty::{
35-
self, Const, GenericArgs, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
36-
TypeVisitable, TypeVisitor,
35+
self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
36+
TypeVisitor,
3737
};
3838
use rustc_middle::{bug, span_bug};
3939
use rustc_session::lint;
@@ -246,10 +246,10 @@ where
246246
ty::ExistentialPredicate::Trait(trait_ref) => trait_ref,
247247
ty::ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
248248
ty::ExistentialPredicate::AutoTrait(def_id) => {
249-
ty::ExistentialTraitRef { def_id, args: GenericArgs::empty() }
249+
ty::ExistentialTraitRef::new(tcx, def_id, ty::GenericArgs::empty())
250250
}
251251
};
252-
let ty::ExistentialTraitRef { def_id, args: _ } = trait_ref;
252+
let ty::ExistentialTraitRef { def_id, .. } = trait_ref;
253253
try_visit!(self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref));
254254
}
255255
}

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,15 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
245245
alias_ty.to_ty(tcx),
246246
);
247247
debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx));
248-
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
249-
def_id: assoc_ty.def_id,
250-
args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args,
251-
term: resolved.into(),
252-
})
248+
ty::ExistentialPredicate::Projection(
249+
ty::ExistentialProjection::erase_self_ty(
250+
tcx,
251+
ty::ProjectionPredicate {
252+
projection_term: alias_ty.into(),
253+
term: resolved.into(),
254+
},
255+
),
256+
)
253257
})
254258
})
255259
})
@@ -318,10 +322,11 @@ pub(crate) fn transform_instance<'tcx>(
318322
.lang_items()
319323
.drop_trait()
320324
.unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item"));
321-
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef {
325+
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new_from_args(
326+
tcx,
322327
def_id,
323-
args: List::empty(),
324-
});
328+
ty::List::empty(),
329+
));
325330
let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
326331
let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
327332
instance.args = tcx.mk_args_trait(self_ty, List::empty());

compiler/rustc_smir/src/rustc_internal/internal.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,12 @@ impl RustcInternal for ExistentialProjection {
380380
type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>;
381381

382382
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
383-
rustc_ty::ExistentialProjection {
384-
def_id: self.def_id.0.internal(tables, tcx),
385-
args: self.generic_args.internal(tables, tcx),
386-
term: self.term.internal(tables, tcx),
387-
}
383+
rustc_ty::ExistentialProjection::new_from_args(
384+
tcx,
385+
self.def_id.0.internal(tables, tcx),
386+
self.generic_args.internal(tables, tcx),
387+
self.term.internal(tables, tcx),
388+
)
388389
}
389390
}
390391

@@ -403,10 +404,11 @@ impl RustcInternal for ExistentialTraitRef {
403404
type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>;
404405

405406
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
406-
rustc_ty::ExistentialTraitRef {
407-
def_id: self.def_id.0.internal(tables, tcx),
408-
args: self.generic_args.internal(tables, tcx),
409-
}
407+
rustc_ty::ExistentialTraitRef::new_from_args(
408+
tcx,
409+
self.def_id.0.internal(tables, tcx),
410+
self.generic_args.internal(tables, tcx),
411+
)
410412
}
411413
}
412414

compiler/rustc_smir/src/rustc_smir/convert/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
6868
type T = stable_mir::ty::ExistentialTraitRef;
6969

7070
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
71-
let ty::ExistentialTraitRef { def_id, args } = self;
71+
let ty::ExistentialTraitRef { def_id, args, .. } = self;
7272
stable_mir::ty::ExistentialTraitRef {
7373
def_id: tables.trait_def(*def_id),
7474
generic_args: args.stable(tables),
@@ -95,7 +95,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
9595
type T = stable_mir::ty::ExistentialProjection;
9696

9797
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
98-
let ty::ExistentialProjection { def_id, args, term } = self;
98+
let ty::ExistentialProjection { def_id, args, term, .. } = self;
9999
stable_mir::ty::ExistentialProjection {
100100
def_id: tables.trait_def(*def_id),
101101
generic_args: args.stable(tables),

compiler/rustc_type_ir/src/interner.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ use crate::solve::{
1515
CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult, SolverMode,
1616
};
1717
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
18-
use crate::{
19-
search_graph, {self as ty},
20-
};
18+
use crate::{self as ty, search_graph};
2119

2220
pub trait Interner:
2321
Sized
@@ -173,6 +171,10 @@ pub trait Interner:
173171

174172
fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
175173

174+
/// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
175+
/// are compatible with the `DefId`.
176+
fn debug_assert_existential_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
177+
176178
fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
177179
where
178180
I: Iterator<Item = T>,

compiler/rustc_type_ir/src/predicate.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,34 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
289289
pub struct ExistentialTraitRef<I: Interner> {
290290
pub def_id: I::DefId,
291291
pub args: I::GenericArgs,
292+
/// This field exists to prevent the creation of `ExistentialTraitRef` without
293+
/// calling [`ExistentialTraitRef::new_from_args`].
294+
_use_existential_trait_ref_new_instead: (),
292295
}
293296

294297
impl<I: Interner> ExistentialTraitRef<I> {
298+
pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
299+
interner.debug_assert_existential_args_compatible(trait_def_id, args);
300+
Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
301+
}
302+
303+
pub fn new(
304+
interner: I,
305+
trait_def_id: I::DefId,
306+
args: impl IntoIterator<Item: Into<I::GenericArg>>,
307+
) -> Self {
308+
let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
309+
Self::new_from_args(interner, trait_def_id, args)
310+
}
311+
295312
pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
296313
// Assert there is a Self.
297314
trait_ref.args.type_at(0);
298315

299316
ExistentialTraitRef {
300317
def_id: trait_ref.def_id,
301318
args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
319+
_use_existential_trait_ref_new_instead: (),
302320
}
303321
}
304322

@@ -336,9 +354,33 @@ pub struct ExistentialProjection<I: Interner> {
336354
pub def_id: I::DefId,
337355
pub args: I::GenericArgs,
338356
pub term: I::Term,
357+
358+
/// This field exists to prevent the creation of `ExistentialProjection`
359+
/// without using [`ExistentialProjection::new_from_args`].
360+
use_existential_projection_new_instead: (),
339361
}
340362

341363
impl<I: Interner> ExistentialProjection<I> {
364+
pub fn new_from_args(
365+
interner: I,
366+
def_id: I::DefId,
367+
args: I::GenericArgs,
368+
term: I::Term,
369+
) -> ExistentialProjection<I> {
370+
interner.debug_assert_existential_args_compatible(def_id, args);
371+
Self { def_id, args, term, use_existential_projection_new_instead: () }
372+
}
373+
374+
pub fn new(
375+
interner: I,
376+
def_id: I::DefId,
377+
args: impl IntoIterator<Item: Into<I::GenericArg>>,
378+
term: I::Term,
379+
) -> ExistentialProjection<I> {
380+
let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
381+
Self::new_from_args(interner, def_id, args, term)
382+
}
383+
342384
/// Extracts the underlying existential trait reference from this projection.
343385
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
344386
/// then this function would return an `exists T. T: Iterator` existential trait
@@ -347,7 +389,7 @@ impl<I: Interner> ExistentialProjection<I> {
347389
let def_id = interner.parent(self.def_id);
348390
let args_count = interner.generics_of(def_id).count() - 1;
349391
let args = interner.mk_args(&self.args.as_slice()[..args_count]);
350-
ExistentialTraitRef { def_id, args }
392+
ExistentialTraitRef { def_id, args, _use_existential_trait_ref_new_instead: () }
351393
}
352394

353395
pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
@@ -372,6 +414,7 @@ impl<I: Interner> ExistentialProjection<I> {
372414
def_id: projection_predicate.projection_term.def_id,
373415
args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
374416
term: projection_predicate.term,
417+
use_existential_projection_new_instead: (),
375418
}
376419
}
377420
}

compiler/rustc_type_ir/src/relate.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
333333
a.args,
334334
b.args,
335335
)?;
336-
Ok(ty::ExistentialProjection { def_id: a.def_id, args, term })
336+
Ok(ty::ExistentialProjection::new_from_args(relation.cx(), a.def_id, args, term))
337337
}
338338
}
339339
}
@@ -373,7 +373,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialTraitRef<I> {
373373
}))
374374
} else {
375375
let args = relate_args_invariantly(relation, a.args, b.args)?;
376-
Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
376+
Ok(ty::ExistentialTraitRef::new_from_args(relation.cx(), a.def_id, args))
377377
}
378378
}
379379
}

0 commit comments

Comments
 (0)