about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs24
-rw-r--r--src/test/ui/auto-traits/bad-generics-on-dyn.rs11
-rw-r--r--src/test/ui/auto-traits/bad-generics-on-dyn.stderr11
3 files changed, 44 insertions, 2 deletions
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 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
                 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`.