Skip to content

Commit 2239f1c

Browse files
Validate ExistentialPredicate args
1 parent 9368b9f commit 2239f1c

10 files changed

Lines changed: 103 additions & 32 deletions

File tree

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
250250
}
251251
})
252252
.collect();
253-
let args = tcx.mk_args(&args);
254253

255254
let span = i.bottom().1;
256255
let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| {
@@ -283,7 +282,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
283282
.emit();
284283
}
285284

286-
ty::ExistentialTraitRef{def_id: trait_ref.def_id, args}
285+
ty::ExistentialTraitRef::new(tcx, trait_ref.def_id, args)
287286
})
288287
});
289288

‎compiler/rustc_middle/src/ty/context.rs‎

Lines changed: 20 additions & 0 deletions
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+
fndebug_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+
ifcfg!(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
fnmk_type_list_from_iter<I,T>(self,args:I) -> T::Output
283303
where
284304
I:Iterator<Item = T>,

‎compiler/rustc_passes/src/reachable.rs‎

Lines changed: 1 addition & 1 deletion
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
ifletSome(trait_ref) = dyn_ty.principal(){
325-
letExistentialTraitRef{ def_id, args } = trait_ref.skip_binder();
325+
letExistentialTraitRef{ 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‎

Lines changed: 4 additions & 4 deletions
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::PrintTraitRefExtas _;
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‎

Lines changed: 13 additions & 8 deletions
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 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‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,12 @@ impl RustcInternal for ExistentialProjection {
380380
typeT<'tcx> = rustc_ty::ExistentialProjection<'tcx>;
381381

382382
fninternal<'tcx>(&self,tables:&mutTables<'_>,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
typeT<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>;
404405

405406
fninternal<'tcx>(&self,tables:&mutTables<'_>,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‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
6868
typeT = stable_mir::ty::ExistentialTraitRef;
6969

7070
fnstable(&self,tables:&mutTables<'_>) -> 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
typeT = stable_mir::ty::ExistentialProjection;
9696

9797
fnstable(&self,tables:&mutTables<'_>) -> 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‎

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

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

174172
fndebug_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+
fndebug_assert_existential_args_compatible(self,def_id:Self::DefId,args:Self::GenericArgs);
177+
176178
fnmk_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‎

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,34 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
289289
pubstructExistentialTraitRef<I:Interner>{
290290
pubdef_id:I::DefId,
291291
pubargs: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+
pubfnnew_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+
pubfnnew(
304+
interner:I,
305+
trait_def_id:I::DefId,
306+
args:implIntoIterator<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
pubfnerase_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
pubdef_id:I::DefId,
337355
pubargs:I::GenericArgs,
338356
pubterm: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+
pubfnnew_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+
pubfnnew(
375+
interner:I,
376+
def_id:I::DefId,
377+
args:implIntoIterator<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
pubfnwith_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‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
308308
a.args,
309309
b.args,
310310
)?;
311-
Ok(ty::ExistentialProjection{def_id: a.def_id, args, term})
311+
Ok(ty::ExistentialProjection::new_from_args(relation.cx(), a.def_id, args, term))
312312
}
313313
}
314314
}
@@ -348,7 +348,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialTraitRef<I> {
348348
}))
349349
}else{
350350
let args = relate_args_invariantly(relation, a.args, b.args)?;
351-
Ok(ty::ExistentialTraitRef{def_id: a.def_id, args})
351+
Ok(ty::ExistentialTraitRef::new_from_args(relation.cx(), a.def_id, args))
352352
}
353353
}
354354
}

0 commit comments

Comments
 (0)