From 67a30d2d7038f5a2667d93205ba5341ca7566dff Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 20 Dec 2018 18:38:55 +0000 Subject: [PATCH] Fixed ICE when type arguments are specified on `Self` type. --- src/librustc_typeck/astconv.rs | 8 +- src/librustc_typeck/check/mod.rs | 10 ++- src/test/ui/enum-variant-generic-args.rs | 5 +- src/test/ui/enum-variant-generic-args.stderr | 79 +++++++++++++------- 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>(&self, segments: T) { + pub fn prohibit_generics<'a, T: IntoIterator>( + &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::method` and `>::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 Enum { 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 Enum { 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`.