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
This commit is contained in:
commit
0a07ffe4ad
@ -101,6 +101,20 @@ pub fn default_value<'tcx>(
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_error<'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
preceding_substs: &[ty::GenericArg<'tcx>],
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
match &self.kind {
|
||||
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
|
||||
ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(),
|
||||
ty::GenericParamDefKind::Const { .. } => {
|
||||
tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -722,8 +722,17 @@ pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicat
|
||||
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
||||
}
|
||||
ExistentialPredicate::AutoTrait(did) => {
|
||||
let trait_ref = self.rebind(tcx.mk_trait_ref(did, [self_ty]));
|
||||
trait_ref.without_const().to_predicate(tcx)
|
||||
let generics = tcx.generics_of(did);
|
||||
let trait_ref = if generics.params.len() == 1 {
|
||||
tcx.mk_trait_ref(did, [self_ty])
|
||||
} else {
|
||||
// If this is an ill-formed auto trait, then synthesize
|
||||
// new error substs for the missing generics.
|
||||
let err_substs =
|
||||
ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]);
|
||||
tcx.mk_trait_ref(did, err_substs)
|
||||
};
|
||||
self.rebind(trait_ref).without_const().to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,6 +352,22 @@ pub fn fill_single<F>(
|
||||
}
|
||||
}
|
||||
|
||||
// Extend an `original_substs` list to the full number of substs expected by `def_id`,
|
||||
// filling in the missing parameters with error ty/ct or 'static regions.
|
||||
pub fn extend_with_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
original_substs: &[GenericArg<'tcx>],
|
||||
) -> SubstsRef<'tcx> {
|
||||
ty::InternalSubsts::for_item(tcx, def_id, |def, substs| {
|
||||
if let Some(subst) = original_substs.get(def.index as usize) {
|
||||
*subst
|
||||
} else {
|
||||
def.to_error(tcx, substs)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx {
|
||||
self.iter()
|
||||
|
11
src/test/ui/auto-traits/bad-generics-on-dyn.rs
Normal file
11
src/test/ui/auto-traits/bad-generics-on-dyn.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![feature(auto_traits)]
|
||||
|
||||
auto trait Trait1<'a> {}
|
||||
//~^ ERROR auto traits cannot have generic parameters
|
||||
|
||||
fn f<'a>(x: &dyn Trait1<'a>)
|
||||
{}
|
||||
|
||||
fn main() {
|
||||
f(&1);
|
||||
}
|
11
src/test/ui/auto-traits/bad-generics-on-dyn.stderr
Normal file
11
src/test/ui/auto-traits/bad-generics-on-dyn.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0567]: auto traits cannot have generic parameters
|
||||
--> $DIR/bad-generics-on-dyn.rs:3:18
|
||||
|
|
||||
LL | auto trait Trait1<'a> {}
|
||||
| ------^^^^ help: remove the parameters
|
||||
| |
|
||||
| auto trait cannot have generic parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0567`.
|
Loading…
Reference in New Issue
Block a user