From 19175e9b75234647963c84247db653f53c8c936a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 5 Dec 2022 05:44:24 +0000 Subject: [PATCH 1/2] Synthesize generics for bad auto traits in dyn types --- compiler/rustc_middle/src/ty/sty.rs | 24 +++++++++++++++++-- .../ui/auto-traits/bad-generics-on-dyn.rs | 11 +++++++++ .../ui/auto-traits/bad-generics-on-dyn.stderr | 11 +++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/auto-traits/bad-generics-on-dyn.rs create mode 100644 src/test/ui/auto-traits/bad-generics-on-dyn.stderr diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 5984686044b..8e69824e6c7 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -722,8 +722,28 @@ 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::for_item(tcx, did, |def, substs| { + if def.index == 0 { + self_ty.into() + } else { + match &def.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(def.def_id).subst(tcx, substs)) + .into(), + } + } + }); + tcx.mk_trait_ref(did, err_substs) + }; + self.rebind(trait_ref).without_const().to_predicate(tcx) } } } diff --git a/src/test/ui/auto-traits/bad-generics-on-dyn.rs b/src/test/ui/auto-traits/bad-generics-on-dyn.rs new file mode 100644 index 00000000000..3f8ac14c72d --- /dev/null +++ b/src/test/ui/auto-traits/bad-generics-on-dyn.rs @@ -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); +} diff --git a/src/test/ui/auto-traits/bad-generics-on-dyn.stderr b/src/test/ui/auto-traits/bad-generics-on-dyn.stderr new file mode 100644 index 00000000000..ade69ced606 --- /dev/null +++ b/src/test/ui/auto-traits/bad-generics-on-dyn.stderr @@ -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`. From 6dc2aa26759578f09974041f19767a75b8c6320e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 Dec 2022 01:52:02 +0000 Subject: [PATCH 2/2] Add GenericParamDef::to_error and InternalSubsts::extend_with_error --- compiler/rustc_middle/src/ty/generics.rs | 14 ++++++++++++++ compiler/rustc_middle/src/ty/sty.rs | 15 ++------------- compiler/rustc_middle/src/ty/subst.rs | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index a8da93e4c69..48329da3e63 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -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)] diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8e69824e6c7..1eec119616e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -728,19 +728,8 @@ pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicat } else { // If this is an ill-formed auto trait, then synthesize // new error substs for the missing generics. - let err_substs = ty::InternalSubsts::for_item(tcx, did, |def, substs| { - if def.index == 0 { - self_ty.into() - } else { - match &def.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(def.def_id).subst(tcx, substs)) - .into(), - } - } - }); + 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) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 141c8354c18..23507d28045 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -352,6 +352,22 @@ pub fn fill_single( } } + // 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> + 'tcx { self.iter()