about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/astconv.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs10
-rw-r--r--src/test/ui/enum-variant-generic-args.rs5
-rw-r--r--src/test/ui/enum-variant-generic-args.stderr79
4 files changed, 71 insertions, 31 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index a68148515c4..f819a5f642f 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1431,7 +1431,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
         self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs))
     }
 
-    pub fn prohibit_generics<'a, T: IntoIterator<Item = &'a hir::PathSegment>>(&self, segments: T) {
+    pub fn prohibit_generics<'a, T: IntoIterator<Item = &'a hir::PathSegment>>(
+            &self, segments: T) -> bool {
+        let mut has_err = false;
         for segment in segments {
             segment.with_generic_args(|generic_args| {
                 let (mut err_for_lt, mut err_for_ty) = (false, false);
@@ -1440,6 +1442,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                         hir::GenericArg::Lifetime(lt) => {
                             if err_for_lt { continue }
                             err_for_lt = true;
+                            has_err = true;
                             (struct_span_err!(self.tcx().sess, lt.span, E0110,
                                               "lifetime arguments are not allowed on this entity"),
                              lt.span,
@@ -1448,6 +1451,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                         hir::GenericArg::Type(ty) => {
                             if err_for_ty { continue }
                             err_for_ty = true;
+                            has_err = true;
                             (struct_span_err!(self.tcx().sess, ty.span, E0109,
                                               "type arguments are not allowed on this entity"),
                              ty.span,
@@ -1461,11 +1465,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                     }
                 }
                 for binding in &generic_args.bindings {
+                    has_err = true;
                     Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
                     break;
                 }
             })
         }
+        has_err
     }
 
     pub fn prohibit_assoc_ty_binding(tcx: TyCtxt, span: Span) {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e2eb7fab0f7..c2b4078e91f 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5123,13 +5123,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // errors if type parameters are provided in an inappropriate place.
 
         let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
-        AstConv::prohibit_generics(self, segments.iter().enumerate().filter_map(|(index, seg)| {
+        let generics_has_err = AstConv::prohibit_generics(
+                self, segments.iter().enumerate().filter_map(|(index, seg)| {
             if !generic_segs.contains(&index) || is_alias_variant_ctor {
                 Some(seg)
             } else {
                 None
             }
         }));
+        if generics_has_err {
+            // Don't try to infer type parameters when prohibited generic arguments were given.
+            user_self_ty = None;
+        }
 
         match def {
             Def::Local(nid) | Def::Upvar(nid, ..) => {
@@ -5301,9 +5306,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
             // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
-            // is inherent, there is no `Self` parameter, instead, the impl needs
+            // is inherent, there is no `Self` parameter; instead, the impl needs
             // type parameters, which we can infer by unifying the provided `Self`
             // with the substituted impl type.
+            // This also occurs for an enum variant on a type alias.
             let ty = tcx.type_of(impl_def_id);
 
             let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs
index ad821344e21..6eddd709645 100644
--- a/src/test/ui/enum-variant-generic-args.rs
+++ b/src/test/ui/enum-variant-generic-args.rs
@@ -7,11 +7,12 @@ type AliasFixed = Enum<()>;
 impl<T> Enum<T> {
     fn ts_variant() {
         Self::TSVariant(());
-        //~^ ERROR type parameters are not allowed on this name [E0109]
+        //~^ ERROR mismatched types [E0308]
         Self::TSVariant::<()>(());
         //~^ ERROR type arguments are not allowed on this entity [E0109]
         Self::<()>::TSVariant(());
         //~^ ERROR type arguments are not allowed on this entity [E0109]
+        //~^^ ERROR mismatched types [E0308]
         Self::<()>::TSVariant::<()>(());
         //~^ ERROR type arguments are not allowed on this entity [E0109]
         //~^^ ERROR type arguments are not allowed on this entity [E0109]
@@ -19,7 +20,7 @@ impl<T> Enum<T> {
 
     fn s_variant() {
         Self::SVariant { v: () };
-        //~^ ERROR type parameters are not allowed on this name [E0109]
+        //~^ ERROR mismatched types [E0308]
         Self::SVariant::<()> { v: () };
         //~^ ERROR type arguments are not allowed on this entity [E0109]
         //~^^ ERROR mismatched types [E0308]
diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr
index 4228a807bad..4d3b5767346 100644
--- a/src/test/ui/enum-variant-generic-args.stderr
+++ b/src/test/ui/enum-variant-generic-args.stderr
@@ -1,35 +1,62 @@
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:9:25
+   |
+LL |         Self::TSVariant(());
+   |                         ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:9:27
+  --> $DIR/enum-variant-generic-args.rs:11:27
    |
 LL |         Self::TSVariant::<()>(());
    |                           ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:11:16
+  --> $DIR/enum-variant-generic-args.rs:13:16
    |
 LL |         Self::<()>::TSVariant(());
    |                ^^ type argument not allowed
 
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:13:31
+   |
+LL |         Self::<()>::TSVariant(());
+   |                               ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:13:16
+  --> $DIR/enum-variant-generic-args.rs:16:16
    |
 LL |         Self::<()>::TSVariant::<()>(());
    |                ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:13:33
+  --> $DIR/enum-variant-generic-args.rs:16:33
    |
 LL |         Self::<()>::TSVariant::<()>(());
    |                                 ^^ type argument not allowed
 
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:22:29
+   |
+LL |         Self::SVariant { v: () };
+   |                             ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:19:26
+  --> $DIR/enum-variant-generic-args.rs:24:26
    |
 LL |         Self::SVariant::<()> { v: () };
    |                          ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:19:35
+  --> $DIR/enum-variant-generic-args.rs:24:35
    |
 LL |         Self::SVariant::<()> { v: () };
    |                                   ^^ expected type parameter, found ()
@@ -38,13 +65,13 @@ LL |         Self::SVariant::<()> { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:22:16
+  --> $DIR/enum-variant-generic-args.rs:27:16
    |
 LL |         Self::<()>::SVariant { v: () };
    |                ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:22:35
+  --> $DIR/enum-variant-generic-args.rs:27:35
    |
 LL |         Self::<()>::SVariant { v: () };
    |                                   ^^ expected type parameter, found ()
@@ -53,19 +80,19 @@ LL |         Self::<()>::SVariant { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:25:16
+  --> $DIR/enum-variant-generic-args.rs:30:16
    |
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:25:32
+  --> $DIR/enum-variant-generic-args.rs:30:32
    |
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                                ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:25:41
+  --> $DIR/enum-variant-generic-args.rs:30:41
    |
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                                         ^^ expected type parameter, found ()
@@ -74,90 +101,90 @@ LL |         Self::<()>::SVariant::<()> { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:35:29
+  --> $DIR/enum-variant-generic-args.rs:40:29
    |
 LL |     Enum::<()>::TSVariant::<()>(());
    |                             ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:38:24
+  --> $DIR/enum-variant-generic-args.rs:43:24
    |
 LL |     Alias::TSVariant::<()>(());
    |                        ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:40:30
+  --> $DIR/enum-variant-generic-args.rs:45:30
    |
 LL |     Alias::<()>::TSVariant::<()>(());
    |                              ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:43:29
+  --> $DIR/enum-variant-generic-args.rs:48:29
    |
 LL |     AliasFixed::TSVariant::<()>(());
    |                             ^^ type argument not allowed
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:45:18
+  --> $DIR/enum-variant-generic-args.rs:50:18
    |
 LL |     AliasFixed::<()>::TSVariant(());
    |                  ^^ unexpected type argument
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:47:18
+  --> $DIR/enum-variant-generic-args.rs:52:18
    |
 LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                  ^^ unexpected type argument
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:47:35
+  --> $DIR/enum-variant-generic-args.rs:52:35
    |
 LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                                   ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:53:28
+  --> $DIR/enum-variant-generic-args.rs:58:28
    |
 LL |     Enum::<()>::SVariant::<()> { v: () };
    |                            ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:56:23
+  --> $DIR/enum-variant-generic-args.rs:61:23
    |
 LL |     Alias::SVariant::<()> { v: () };
    |                       ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:58:29
+  --> $DIR/enum-variant-generic-args.rs:63:29
    |
 LL |     Alias::<()>::SVariant::<()> { v: () };
    |                             ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:61:28
+  --> $DIR/enum-variant-generic-args.rs:66:28
    |
 LL |     AliasFixed::SVariant::<()> { v: () };
    |                            ^^ type argument not allowed
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:63:18
+  --> $DIR/enum-variant-generic-args.rs:68:18
    |
 LL |     AliasFixed::<()>::SVariant { v: () };
    |                  ^^ unexpected type argument
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:65:18
+  --> $DIR/enum-variant-generic-args.rs:70:18
    |
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
    |                  ^^ unexpected type argument
 
 error[E0109]: type arguments are not allowed on this entity
-  --> $DIR/enum-variant-generic-args.rs:65:34
+  --> $DIR/enum-variant-generic-args.rs:70:34
    |
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
    |                                  ^^ type argument not allowed
 
-error: aborting due to 25 previous errors
+error: aborting due to 28 previous errors
 
 Some errors occurred: E0107, E0109, E0308.
 For more information about an error, try `rustc --explain E0107`.