Skip to content

Commit 0a07ffe

Browse files
authored
Rollup merge of #105287 - compiler-errors:issue-105275, r=eholk
Synthesize substitutions for bad auto traits in dyn types Auto traits are stored as just `DefId`s inside a `dyn Trait`'s existential predicates list. This is usually fine, since auto traits are forbidden to have generics -- but this becomes a problem for an ill-formed auto trait. But since this will always result in an error, just synthesize some dummy (error) substitutions which are used at least to keep trait selection code happy about the number of substs in a trait ref. Fixes #104808
2 parents ddb98e0 + 6dc2aa2 commit 0a07ffe

File tree

5 files changed

+63
-2
lines changed

5 files changed

+63
-2
lines changed

compiler/rustc_middle/src/ty/generics.rs

+14
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@ impl GenericParamDef {
101101
_ => None,
102102
}
103103
}
104+
105+
pub fn to_error<'tcx>(
106+
&self,
107+
tcx: TyCtxt<'tcx>,
108+
preceding_substs: &[ty::GenericArg<'tcx>],
109+
) -> ty::GenericArg<'tcx> {
110+
match &self.kind {
111+
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
112+
ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(),
113+
ty::GenericParamDefKind::Const { .. } => {
114+
tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into()
115+
}
116+
}
117+
}
104118
}
105119

106120
#[derive(Default)]

compiler/rustc_middle/src/ty/sty.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,17 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
722722
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
723723
}
724724
ExistentialPredicate::AutoTrait(did) => {
725-
let trait_ref = self.rebind(tcx.mk_trait_ref(did, [self_ty]));
726-
trait_ref.without_const().to_predicate(tcx)
725+
let generics = tcx.generics_of(did);
726+
let trait_ref = if generics.params.len() == 1 {
727+
tcx.mk_trait_ref(did, [self_ty])
728+
} else {
729+
// If this is an ill-formed auto trait, then synthesize
730+
// new error substs for the missing generics.
731+
let err_substs =
732+
ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]);
733+
tcx.mk_trait_ref(did, err_substs)
734+
};
735+
self.rebind(trait_ref).without_const().to_predicate(tcx)
727736
}
728737
}
729738
}

compiler/rustc_middle/src/ty/subst.rs

+16
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,22 @@ impl<'tcx> InternalSubsts<'tcx> {
352352
}
353353
}
354354

355+
// Extend an `original_substs` list to the full number of substs expected by `def_id`,
356+
// filling in the missing parameters with error ty/ct or 'static regions.
357+
pub fn extend_with_error(
358+
tcx: TyCtxt<'tcx>,
359+
def_id: DefId,
360+
original_substs: &[GenericArg<'tcx>],
361+
) -> SubstsRef<'tcx> {
362+
ty::InternalSubsts::for_item(tcx, def_id, |def, substs| {
363+
if let Some(subst) = original_substs.get(def.index as usize) {
364+
*subst
365+
} else {
366+
def.to_error(tcx, substs)
367+
}
368+
})
369+
}
370+
355371
#[inline]
356372
pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx {
357373
self.iter()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(auto_traits)]
2+
3+
auto trait Trait1<'a> {}
4+
//~^ ERROR auto traits cannot have generic parameters
5+
6+
fn f<'a>(x: &dyn Trait1<'a>)
7+
{}
8+
9+
fn main() {
10+
f(&1);
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0567]: auto traits cannot have generic parameters
2+
--> $DIR/bad-generics-on-dyn.rs:3:18
3+
|
4+
LL | auto trait Trait1<'a> {}
5+
| ------^^^^ help: remove the parameters
6+
| |
7+
| auto trait cannot have generic parameters
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0567`.

0 commit comments

Comments
 (0)