diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index ac4ca30382fee..77ec0aa0b6090 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1977,6 +1977,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { args: &[], bindings: arena_vec![self; self.output_ty_binding(span, output_ty)], parenthesized: false, + span, }); // ::std::future::Future @@ -2655,11 +2656,12 @@ impl<'hir> GenericArgsCtor<'hir> { self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized } - fn into_generic_args(self, arena: &'hir Arena<'hir>) -> hir::GenericArgs<'hir> { + fn into_generic_args(self, arena: &'hir Arena<'hir>, span: Span) -> hir::GenericArgs<'hir> { hir::GenericArgs { args: arena.alloc_from_iter(self.args), bindings: self.bindings, parenthesized: self.parenthesized, + span, } } } diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index b45a06e1c1d2a..fb5c809b9f052 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -31,6 +31,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); let proj_start = p.segments.len() - partial_res.unresolved_segments(); + let mut type_param_in_enum = false; let path = self.arena.alloc(hir::Path { res: self.lower_res(partial_res.base_res()), segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map( @@ -55,7 +56,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => { Some(parent_def_id(self, def_id)) } - Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => { + Res::Def(DefKind::Variant, def_id) + if i + 2 == proj_start && segment.args.is_some() => + { + // Handle `Enum::::Variant {}`. + // We need to choose one here so that the method `res_to_ty` in + // `astconv` works correctly, but it has to be *only* one, so track + // whether we've already set the `DefId` in the previous segment. + type_param_in_enum = true; + Some(parent_def_id(self, def_id)) + } + Res::Def(DefKind::Variant, def_id) + if i + 1 == proj_start + && (segment.args.is_some() || !type_param_in_enum) => + { + // Handle `Enum::Variant:: {}`. Some(parent_def_id(self, def_id)) } Res::Def(DefKind::Struct, def_id) @@ -345,6 +360,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment.ident, segment.id, id, ); + let param_sp = + segment.args.as_ref().map_or(segment.ident.span.shrink_to_hi(), |args| args.span()); hir::PathSegment { ident: segment.ident, hir_id: Some(id), @@ -353,7 +370,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { args: if generic_args.is_empty() { None } else { - Some(self.arena.alloc(generic_args.into_generic_args(self.arena))) + Some(self.arena.alloc(generic_args.into_generic_args(self.arena, param_sp))) }, } } diff --git a/src/librustc_error_codes/error_codes/E0109.md b/src/librustc_error_codes/error_codes/E0109.md index 2eab9725a6f59..18538affdd7d6 100644 --- a/src/librustc_error_codes/error_codes/E0109.md +++ b/src/librustc_error_codes/error_codes/E0109.md @@ -17,6 +17,6 @@ type X = u32; // ok! type Y = bool; // ok! ``` -Note that generic arguments for enum variant constructors go after the variant, -not after the enum. For example, you would write `Option::None::`, -rather than `Option::::None`. +Note that generic arguments for enum variant constructors can go after the +variant or after the enum. For example, you can write `Option::None::`, +rather than `Option::::None`, but the later style is preferred. diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 8496a6ed23b8c..90d5676ac26e2 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -311,11 +311,13 @@ pub struct GenericArgs<'hir> { /// This is required mostly for pretty-printing and diagnostics, /// but also for changing lifetime elision rules to be "function-like". pub parenthesized: bool, + /// The `Span` encompassing the entirety of the parameters `` or `(A, B)`. + pub span: Span, } impl GenericArgs<'_> { pub const fn none() -> Self { - Self { args: &[], bindings: &[], parenthesized: false } + Self { args: &[], bindings: &[], parenthesized: false, span: DUMMY_SP } } pub fn is_empty(&self) -> bool { diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 603ed4640a0cf..d856b89b136d5 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -256,6 +256,13 @@ declare_lint! { }; } +declare_lint! { + pub TYPE_PARAM_ON_VARIANT_CTOR, + Allow, + "detects generic arguments in path segments corresponding to an enum variant instead of the \ + enum itself", +} + declare_lint! { pub ORDER_DEPENDENT_TRAIT_OBJECTS, Deny, @@ -531,6 +538,7 @@ declare_lint_pass! { PATTERNS_IN_FNS_WITHOUT_BODY, MISSING_FRAGMENT_SPECIFIER, LATE_BOUND_LIFETIME_ARGUMENTS, + TYPE_PARAM_ON_VARIANT_CTOR, ORDER_DEPENDENT_TRAIT_OBJECTS, COHERENCE_LEAK_CHECK, DEPRECATED, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 78c05a51e4fbd..8030bd7bc245a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -125,8 +125,8 @@ enum ConvertedBindingKind<'a, 'tcx> { Constraint(&'a [hir::GenericBound<'a>]), } -#[derive(PartialEq)] -enum GenericArgPosition { +#[derive(PartialEq, Debug)] +pub enum GenericArgPosition { Type, Value, // e.g., functions MethodCall, @@ -195,6 +195,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span: Span, def_id: DefId, item_segment: &hir::PathSegment<'_>, + generic_arg_position: GenericArgPosition, ) -> SubstsRef<'tcx> { let (substs, assoc_bindings, _) = self.create_substs_for_ast_path( span, @@ -203,6 +204,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.generic_args(), item_segment.infer_args, None, + generic_arg_position, ); assoc_bindings.first().map(|b| Self::prohibit_assoc_ty_binding(self.tcx(), b.span)); @@ -630,6 +632,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option>, + generic_arg_position: GenericArgPosition, ) -> (SubstsRef<'tcx>, Vec>, Option>) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -661,7 +664,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, &generic_params, &generic_args, - GenericArgPosition::Type, + generic_arg_position, self_ty.is_some(), infer_args, ); @@ -804,6 +807,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_def_id: DefId, item_segment: &hir::PathSegment<'_>, parent_substs: SubstsRef<'tcx>, + generic_arg_position: GenericArgPosition, ) -> SubstsRef<'tcx> { if tcx.generics_of(item_def_id).params.is_empty() { self.prohibit_generics(slice::from_ref(item_segment)); @@ -817,6 +821,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.generic_args(), item_segment.infer_args, None, + generic_arg_position, ) .0 } @@ -1100,6 +1105,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_segment.generic_args(), trait_segment.infer_args, Some(self_ty), + GenericArgPosition::Type, ) } @@ -1416,8 +1422,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span: Span, did: DefId, item_segment: &hir::PathSegment<'_>, + generic_arg_position: GenericArgPosition, ) -> Ty<'tcx> { - let substs = self.ast_path_substs_for_ty(span, did, item_segment); + let substs = self.ast_path_substs_for_ty(span, did, item_segment, generic_arg_position); self.normalize_ty(span, self.tcx().at(span).type_of(did).subst(self.tcx(), substs)) } @@ -2253,6 +2260,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_def_id: DefId, trait_segment: &hir::PathSegment<'_>, item_segment: &hir::PathSegment<'_>, + generic_arg_position: GenericArgPosition, ) -> Ty<'tcx> { let tcx = self.tcx(); @@ -2305,6 +2313,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_def_id, item_segment, trait_ref.substs, + generic_arg_position, ); debug!("qpath_to_ty: trait_ref={:?}", trait_ref); @@ -2312,6 +2321,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.normalize_ty(span, tcx.mk_projection(item_def_id, item_substs)) } + pub fn prohibit_multiple_params<'a, T: IntoIterator>>( + &self, + segments: T, + ) -> bool { + let segments_with_params = segments + .into_iter() + .filter_map(|segment| segment.args.map(|arg| arg.span)) + .collect::>(); + if segments_with_params.len() <= 1 { + return false; + } + self.tcx() + .sess + .struct_span_err( + segments_with_params, + "multiple segments with type parameters are not allowed", + ) + .note("only a single path segment can specify type parameters") + .emit(); + true + } + pub fn prohibit_generics<'a, T: IntoIterator>>( &self, segments: T, @@ -2469,8 +2500,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let enum_def_id = tcx.parent(def_id).unwrap(); (enum_def_id, last - 1) } else { - // FIXME: lint here recommending `Enum::<...>::Variant` form - // instead of `Enum::Variant::<...>` form. + self.lint_type_param_on_variant_ctor(segments); // Everything but the final segment should have no // parameters at all. @@ -2504,18 +2534,51 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { path_segs } + fn lint_type_param_on_variant_ctor(&self, segments: &[hir::PathSegment<'_>]) { + // Doing this to get around rustfmt-caused line too long. + use hir::PathSegment as P; + if let [.., prev, P { ident, hir_id: Some(hir_id), args: Some(args), .. }] = segments { + let sp = args.span; + if sp.hi() == sp.lo() || sp == DUMMY_SP || sp.parent().is_some() { + // The params were not written by the user, but rather derived. These are expected. + // `Enum::Variant` where `Variant` has inferred lifetimes. + return; + } + let span = sp.with_lo(ident.span.hi()); // Account for `::` + self.tcx().struct_span_lint_hir( + lint::builtin::TYPE_PARAM_ON_VARIANT_CTOR, + *hir_id, + sp, + |lint| { + let mut err = lint.build("type parameter on variant"); + let sugg_span = prev.ident.span.shrink_to_hi(); + let msg = "set the type parameter on the enum"; + match self.tcx().sess.source_map().span_to_snippet(span) { + Ok(snippet) => err.multipart_suggestion( + msg, + vec![(sugg_span, snippet), (span, "".to_string())], + Applicability::MachineApplicable, + ), + Err(_) => err.span_label(sugg_span, msg), + }; + err.emit(); + }, + ); + } + } + // Check a type `Path` and convert it to a `Ty`. pub fn res_to_ty( &self, opt_self_ty: Option>, path: &hir::Path<'_>, - permit_variants: bool, + generic_arg_position: GenericArgPosition, ) -> Ty<'tcx> { let tcx = self.tcx(); debug!( - "res_to_ty(res={:?}, opt_self_ty={:?}, path_segments={:?})", - path.res, opt_self_ty, path.segments + "res_to_ty(res={:?}, opt_self_ty={:?}, path_segments={:?} generic_arg_pos={:?})", + path.res, opt_self_ty, path.segments, generic_arg_position ); let span = path.span; @@ -2525,7 +2588,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert!(ty::is_impl_trait_defn(tcx, did).is_none()); let item_segment = path.segments.split_last().unwrap(); self.prohibit_generics(item_segment.1); - let substs = self.ast_path_substs_for_ty(span, did, item_segment.0); + let substs = + self.ast_path_substs_for_ty(span, did, item_segment.0, generic_arg_position); self.normalize_ty(span, tcx.mk_opaque(did, substs)) } Res::Def(DefKind::Enum, did) @@ -2535,9 +2599,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { | Res::Def(DefKind::ForeignTy, did) => { assert_eq!(opt_self_ty, None); self.prohibit_generics(path.segments.split_last().unwrap().1); - self.ast_path_to_ty(span, did, path.segments.last().unwrap()) + self.ast_path_to_ty(span, did, path.segments.last().unwrap(), generic_arg_position) } - Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => { + Res::Def(kind @ DefKind::Variant, def_id) + if generic_arg_position == GenericArgPosition::Value => + { // Convert "variant type" as if it were a real type. // The resulting `Ty` is type of the variant's enum for now. assert_eq!(opt_self_ty, None); @@ -2546,14 +2612,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.def_ids_for_value_path_segments(&path.segments, None, kind, def_id); let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); - self.prohibit_generics(path.segments.iter().enumerate().filter_map( - |(index, seg)| { - if !generic_segs.contains(&index) { Some(seg) } else { None } - }, - )); + + if !self.prohibit_multiple_params(path.segments.iter()) { + self.prohibit_generics(path.segments.iter().enumerate().filter_map( + |(index, seg)| { + if !generic_segs.contains(&index) { Some(seg) } else { None } + }, + )); + } let PathSeg(def_id, index) = path_segs.last().unwrap(); - self.ast_path_to_ty(span, *def_id, &path.segments[*index]) + self.ast_path_to_ty(span, *def_id, &path.segments[*index], generic_arg_position) } Res::Def(DefKind::TyParam, def_id) => { assert_eq!(opt_self_ty, None); @@ -2588,6 +2657,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { def_id, &path.segments[path.segments.len() - 2], path.segments.last().unwrap(), + generic_arg_position, ) } Res::PrimTy(prim_ty) => { @@ -2642,7 +2712,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => { debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself)); - self.res_to_ty(opt_self_ty, path, false) + self.res_to_ty(opt_self_ty, path, GenericArgPosition::Type) } hir::TyKind::Def(item_id, ref lifetimes) => { let did = tcx.hir().local_def_id(item_id.id); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4f6eb20e6ebbd..1f86ddb9c97b4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -87,7 +87,7 @@ mod upvar; mod wfcheck; pub mod writeback; -use crate::astconv::{AstConv, PathSeg}; +use crate::astconv::{AstConv, GenericArgPosition, PathSeg}; use crate::middle::lang_items; use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::map::Map; @@ -2787,6 +2787,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { item_def_id, item_segment, trait_ref.substs, + GenericArgPosition::Type, ); self.tcx().mk_projection(item_def_id, item_substs) @@ -4381,7 +4382,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *qpath { QPath::Resolved(ref maybe_qself, ref path) => { let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself)); - let ty = AstConv::res_to_ty(self, self_ty, path, true); + let ty = AstConv::res_to_ty(self, self_ty, path, GenericArgPosition::Value); (path.res, ty) } QPath::TypeRelative(ref qself, ref segment) => { @@ -5377,8 +5378,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut user_self_ty = None; let mut is_alias_variant_ctor = false; + let mut is_variant = false; match res { Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => { + is_variant = true; if let Some(self_ty) = self_ty { let adt_def = self_ty.ty_adt_def().unwrap(); user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty }); @@ -5414,16 +5417,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // errors if type parameters are provided in an inappropriate place. let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); - 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 - } - }), - ); + let generics_has_err = (is_variant && AstConv::prohibit_multiple_params(self, segments)) + || 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 let Res::Local(hid) = res { let ty = self.local_ty(span, hid).decl_ty; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 70586be0d0433..8fd4fc8556c8f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -14,7 +14,7 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. -use crate::astconv::{AstConv, Bounds, SizedByDefault}; +use crate::astconv::{AstConv, Bounds, GenericArgPosition, SizedByDefault}; use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::constrained_generic_params as cgp; use crate::lint; @@ -349,6 +349,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { item_def_id, item_segment, trait_ref.substs, + GenericArgPosition::Type, ); self.tcx().mk_projection(item_def_id, item_substs) } else { diff --git a/src/test/ui/binding/simple-generic-match.rs b/src/test/ui/binding/simple-generic-match.rs index 50cfe19fef48d..c3ab5384f55d8 100644 --- a/src/test/ui/binding/simple-generic-match.rs +++ b/src/test/ui/binding/simple-generic-match.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(non_camel_case_types)] +#![allow(non_camel_case_types, type_param_on_variant_ctor)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/binding/use-uninit-match.rs b/src/test/ui/binding/use-uninit-match.rs index 9250dbf0c43b4..5b8cde8a99fba 100644 --- a/src/test/ui/binding/use-uninit-match.rs +++ b/src/test/ui/binding/use-uninit-match.rs @@ -1,13 +1,15 @@ // run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - +#![allow(dead_code, non_camel_case_types, type_param_on_variant_ctor)] fn foo(o: myoption) -> isize { let mut x: isize = 5; match o { myoption::none:: => { } - myoption::some::(_t) => { x += 1; } + myoption::some::(_) => { x += 1; } + } + match o { + myoption::::none => { } + myoption::::some(_t) => { x += 1; } } return x; } diff --git a/src/test/ui/binding/use-uninit-match2.rs b/src/test/ui/binding/use-uninit-match2.rs index 9102730629b98..60a8c0864ee0f 100644 --- a/src/test/ui/binding/use-uninit-match2.rs +++ b/src/test/ui/binding/use-uninit-match2.rs @@ -1,14 +1,17 @@ // run-pass -#![allow(dead_code)] -#![allow(unused_mut)] -#![allow(non_camel_case_types)] +#![allow(dead_code, unused_mut, non_camel_case_types, type_param_on_variant_ctor)] fn foo(o: myoption) -> isize { let mut x: isize; match o { myoption::none:: => { panic!(); } - myoption::some::(_t) => { x = 5; } + myoption::some::(_) => { x = 5; } + } + let _ = x; + match o { + myoption::::none => { panic!(); } + myoption::::some(_t) => { x = 5; } } return x; } diff --git a/src/test/ui/constructor-lifetime-args.rs b/src/test/ui/constructor-lifetime-args.rs index 6af5f6d56e7f6..87d408fda3605 100644 --- a/src/test/ui/constructor-lifetime-args.rs +++ b/src/test/ui/constructor-lifetime-args.rs @@ -1,3 +1,4 @@ +#![deny(type_param_on_variant_ctor)] // All lifetime parameters in struct constructors are currently considered early bound, // i.e., `S::` is interpreted kinda like an associated item `S::::ctor`. // This behavior is a bit weird, because if equivalent constructor were written manually @@ -21,6 +22,12 @@ fn main() { E::V(&0); // OK E::V::<'static>(&0); //~^ ERROR wrong number of lifetime arguments: expected 2, found 1 + //~| ERROR type parameter on variant E::V::<'static, 'static, 'static>(&0); //~^ ERROR wrong number of lifetime arguments: expected 2, found 3 + //~| ERROR type parameter on variant + E::<'static>::V(&0); + //~^ ERROR wrong number of lifetime arguments: expected 2, found 1 + E::<'static, 'static, 'static>::V(&0); + //~^ ERROR wrong number of lifetime arguments: expected 2, found 3 } diff --git a/src/test/ui/constructor-lifetime-args.stderr b/src/test/ui/constructor-lifetime-args.stderr index ec8ed9288cced..b19bfda9af4b0 100644 --- a/src/test/ui/constructor-lifetime-args.stderr +++ b/src/test/ui/constructor-lifetime-args.stderr @@ -1,27 +1,66 @@ error[E0107]: wrong number of lifetime arguments: expected 2, found 1 - --> $DIR/constructor-lifetime-args.rs:17:5 + --> $DIR/constructor-lifetime-args.rs:18:5 | LL | S::<'static>(&0, &0); | ^^^^^^^^^^^^ expected 2 lifetime arguments error[E0107]: wrong number of lifetime arguments: expected 2, found 3 - --> $DIR/constructor-lifetime-args.rs:19:27 + --> $DIR/constructor-lifetime-args.rs:20:27 | LL | S::<'static, 'static, 'static>(&0, &0); | ^^^^^^^ unexpected lifetime argument +error: type parameter on variant + --> $DIR/constructor-lifetime-args.rs:23:11 + | +LL | E::V::<'static>(&0); + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/constructor-lifetime-args.rs:1:9 + | +LL | #![deny(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | E::<'static>::V(&0); + | ^^^^^^^^^^^ -- + error[E0107]: wrong number of lifetime arguments: expected 2, found 1 - --> $DIR/constructor-lifetime-args.rs:22:5 + --> $DIR/constructor-lifetime-args.rs:23:5 | LL | E::V::<'static>(&0); | ^^^^^^^^^^^^^^^ expected 2 lifetime arguments +error: type parameter on variant + --> $DIR/constructor-lifetime-args.rs:26:11 + | +LL | E::V::<'static, 'static, 'static>(&0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | E::<'static, 'static, 'static>::V(&0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- + error[E0107]: wrong number of lifetime arguments: expected 2, found 3 - --> $DIR/constructor-lifetime-args.rs:24:30 + --> $DIR/constructor-lifetime-args.rs:26:30 | LL | E::V::<'static, 'static, 'static>(&0); | ^^^^^^^ unexpected lifetime argument -error: aborting due to 4 previous errors +error[E0107]: wrong number of lifetime arguments: expected 2, found 1 + --> $DIR/constructor-lifetime-args.rs:29:5 + | +LL | E::<'static>::V(&0); + | ^^^^^^^^^^^^^^^ expected 2 lifetime arguments + +error[E0107]: wrong number of lifetime arguments: expected 2, found 3 + --> $DIR/constructor-lifetime-args.rs:31:27 + | +LL | E::<'static, 'static, 'static>::V(&0); + | ^^^^^^^ unexpected lifetime argument + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/deriving/deriving-associated-types.rs b/src/test/ui/deriving/deriving-associated-types.rs index 4b1cbe80c506d..069074a6409eb 100644 --- a/src/test/ui/deriving/deriving-associated-types.rs +++ b/src/test/ui/deriving/deriving-associated-types.rs @@ -1,4 +1,5 @@ // run-pass +#![allow(type_param_on_variant_ctor)] pub trait DeclaredTrait { type Type; } diff --git a/src/test/ui/deriving/deriving-clone-generic-enum.rs b/src/test/ui/deriving/deriving-clone-generic-enum.rs index a344d7fc43a2e..10dfd08ced6f3 100644 --- a/src/test/ui/deriving/deriving-clone-generic-enum.rs +++ b/src/test/ui/deriving/deriving-clone-generic-enum.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(dead_code)] +#![allow(dead_code, type_param_on_variant_ctor)] // pretty-expanded FIXME #23616 #[derive(Clone)] diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs index e2e600b17f21e..b4522c261462a 100644 --- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs +++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs @@ -1,3 +1,4 @@ +#![warn(type_param_on_variant_ctor)] // Issue 22443: Reject code using non-regular types that would // otherwise cause dropck to loop infinitely. // @@ -33,4 +34,9 @@ fn main() { Some(Wrapper::Simple::); //~^ ERROR overflow while adding drop-check rules for std::option::Option //~| ERROR overflow while adding drop-check rules for Wrapper + //~| WARNING type parameter on variant + let v = //~ ERROR overflow while adding drop-check rules for std::option + Some(Wrapper::::Simple); + //~^ ERROR overflow while adding drop-check rules for std::option::Option + //~| ERROR overflow while adding drop-check rules for Wrapper } diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr index de8afdcc7cdab..b211239031d42 100644 --- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr +++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr @@ -1,5 +1,21 @@ +warning: type parameter on variant + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:34:31 + | +LL | Some(Wrapper::Simple::); + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:1:9 + | +LL | #![warn(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | Some(Wrapper::::Simple); + | ^^^^^^^ -- + error[E0320]: overflow while adding drop-check rules for std::option::Option> - --> $DIR/dropck_no_diverge_on_nonregular_3.rs:32:9 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:9 | LL | let w = | ^ @@ -7,7 +23,7 @@ LL | let w = = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> error[E0320]: overflow while adding drop-check rules for std::option::Option> - --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:9 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:34:9 | LL | Some(Wrapper::Simple::); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,12 +31,36 @@ LL | Some(Wrapper::Simple::); = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> error[E0320]: overflow while adding drop-check rules for Wrapper - --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:14 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:34:14 | LL | Some(Wrapper::Simple::); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -error: aborting due to 3 previous errors +error[E0320]: overflow while adding drop-check rules for std::option::Option> + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:38:9 + | +LL | let v = + | ^ + | + = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +error[E0320]: overflow while adding drop-check rules for std::option::Option> + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:39:9 + | +LL | Some(Wrapper::::Simple); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +error[E0320]: overflow while adding drop-check rules for Wrapper + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:39:14 + | +LL | Some(Wrapper::::Simple); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +error: aborting due to 6 previous errors diff --git a/src/test/ui/enum-discriminant/niche.rs b/src/test/ui/enum-discriminant/niche.rs index 8d2cdf34f373e..aeac6723bf2bd 100644 --- a/src/test/ui/enum-discriminant/niche.rs +++ b/src/test/ui/enum-discriminant/niche.rs @@ -2,6 +2,7 @@ #![feature(const_panic)] #![feature(const_if_match)] +#![allow(type_param_on_variant_ctor)] //! Make sure that we read and write enum discriminants correctly for corner cases caused //! by layout optimizations. diff --git a/src/test/ui/enum/forbid-many-type-params.rs b/src/test/ui/enum/forbid-many-type-params.rs new file mode 100644 index 0000000000000..88cd9497be936 --- /dev/null +++ b/src/test/ui/enum/forbid-many-type-params.rs @@ -0,0 +1,21 @@ +pub enum Foo<'a, T: 'a> { + Struct {}, + Tuple(), + Unit, + Usage(&'a T), +} + +pub fn main() { + let _ = Foo::::Unit::; //~ ERROR multiple segments with type parameters + let _ = Foo::::Tuple::(); //~ ERROR multiple segments with type parameters + let _ = Foo::::Struct:: {}; //~ ERROR multiple segments with type parameters + if let Foo::::Unit:: = Foo::::Unit:: {} + //~^ ERROR multiple segments with type parameters are not allowed + //~| ERROR multiple segments with type parameters are not allowed + if let Foo::::Tuple::() = Foo::::Tuple::() {} + //~^ ERROR multiple segments with type parameters are not allowed + //~| ERROR multiple segments with type parameters are not allowed + if let Foo::::Struct:: {} = (Foo::::Struct:: {}) {} + //~^ ERROR multiple segments with type parameters are not allowed + //~| ERROR multiple segments with type parameters are not allowed +} diff --git a/src/test/ui/enum/forbid-many-type-params.stderr b/src/test/ui/enum/forbid-many-type-params.stderr new file mode 100644 index 0000000000000..f7e803742bfea --- /dev/null +++ b/src/test/ui/enum/forbid-many-type-params.stderr @@ -0,0 +1,74 @@ +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:9:18 + | +LL | let _ = Foo::::Unit::; + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:10:18 + | +LL | let _ = Foo::::Tuple::(); + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:11:18 + | +LL | let _ = Foo::::Struct:: {}; + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:12:49 + | +LL | if let Foo::::Unit:: = Foo::::Unit:: {} + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:12:17 + | +LL | if let Foo::::Unit:: = Foo::::Unit:: {} + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:15:52 + | +LL | if let Foo::::Tuple::() = Foo::::Tuple::() {} + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:15:17 + | +LL | if let Foo::::Tuple::() = Foo::::Tuple::() {} + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:18:55 + | +LL | if let Foo::::Struct:: {} = (Foo::::Struct:: {}) {} + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: multiple segments with type parameters are not allowed + --> $DIR/forbid-many-type-params.rs:18:17 + | +LL | if let Foo::::Struct:: {} = (Foo::::Struct:: {}) {} + | ^^^^^^^^ ^^^^^^^^ + | + = note: only a single path segment can specify type parameters + +error: aborting due to 9 previous errors + diff --git a/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.rs b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.rs new file mode 100644 index 0000000000000..8bab651b46557 --- /dev/null +++ b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.rs @@ -0,0 +1,31 @@ +// check-pass +#![warn(type_param_on_variant_ctor)] + +pub enum Foo<'a, T: 'a> { + Struct {}, + Tuple(), + Unit, + Usage(&'a T), +} + +pub fn main() { + let _ = Foo::::Unit; + let _ = Foo::::Tuple(); + let _ = Foo::::Struct {}; + if let Foo::::Unit = Foo::::Unit {} + if let Foo::::Tuple() = Foo::::Tuple() {} + if let Foo::::Struct {} = (Foo::::Struct {}) {} + + let _ = Foo::Unit::; //~ WARNING type parameter on variant + let _ = Foo::Tuple::(); //~ WARNING type parameter on variant + let _ = Foo::Struct:: {}; //~ WARNING type parameter on variant + if let Foo::Unit:: = Foo::Unit:: {} + //~^ WARNING type parameter on variant + //~| WARNING type parameter on variant + if let Foo::Tuple::() = Foo::Tuple::() {} + //~^ WARNING type parameter on variant + //~| WARNING type parameter on variant + if let Foo::Struct:: {} = (Foo::Struct:: {}) {} + //~^ WARNING type parameter on variant + //~| WARNING type parameter on variant +} diff --git a/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.stderr b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.stderr new file mode 100644 index 0000000000000..efc46893415ca --- /dev/null +++ b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.stderr @@ -0,0 +1,104 @@ +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:19:24 + | +LL | let _ = Foo::Unit::; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:2:9 + | +LL | #![warn(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | let _ = Foo::::Unit; + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:20:25 + | +LL | let _ = Foo::Tuple::(); + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | let _ = Foo::::Tuple(); + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:26 + | +LL | let _ = Foo::Struct:: {}; + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | let _ = Foo::::Struct {}; + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:22:45 + | +LL | if let Foo::Unit:: = Foo::Unit:: {} + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | if let Foo::Unit:: = Foo::::Unit {} + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:22:23 + | +LL | if let Foo::Unit:: = Foo::Unit:: {} + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | if let Foo::::Unit = Foo::Unit:: {} + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:25:49 + | +LL | if let Foo::Tuple::() = Foo::Tuple::() {} + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | if let Foo::Tuple::() = Foo::::Tuple() {} + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:25:24 + | +LL | if let Foo::Tuple::() = Foo::Tuple::() {} + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | if let Foo::::Tuple() = Foo::Tuple::() {} + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:28:53 + | +LL | if let Foo::Struct:: {} = (Foo::Struct:: {}) {} + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | if let Foo::Struct:: {} = (Foo::::Struct {}) {} + | ^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:28:25 + | +LL | if let Foo::Struct:: {} = (Foo::Struct:: {}) {} + | ^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | if let Foo::::Struct {} = (Foo::Struct:: {}) {} + | ^^^^^^^^^^ -- + diff --git a/src/test/ui/generics/generic-recursive-tag.rs b/src/test/ui/generics/generic-recursive-tag.rs index e1875f0abbe61..44a40c99208f9 100644 --- a/src/test/ui/generics/generic-recursive-tag.rs +++ b/src/test/ui/generics/generic-recursive-tag.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(non_camel_case_types)] +#![allow(non_camel_case_types, type_param_on_variant_ctor)] #![feature(box_syntax)] enum list { cons(Box, Box>), nil, } diff --git a/src/test/ui/generics/generic-tag-match.rs b/src/test/ui/generics/generic-tag-match.rs index 09ed6a808e6ca..dac0554a00b39 100644 --- a/src/test/ui/generics/generic-tag-match.rs +++ b/src/test/ui/generics/generic-tag-match.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(unused_assignments)] -#![allow(non_camel_case_types)] +#![allow(unused_assignments, non_camel_case_types, type_param_on_variant_ctor)] enum foo { arm(T), } diff --git a/src/test/ui/generics/generic-tag-values.rs b/src/test/ui/generics/generic-tag-values.rs index 230f477b6e9a3..9fe885f42d52b 100644 --- a/src/test/ui/generics/generic-tag-values.rs +++ b/src/test/ui/generics/generic-tag-values.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(non_camel_case_types)] +#![allow(non_camel_case_types, type_param_on_variant_ctor)] enum noption { some(T), } diff --git a/src/test/ui/generics/generic-tag.rs b/src/test/ui/generics/generic-tag.rs index 74ef4eeba8ab7..92c1c6646837d 100644 --- a/src/test/ui/generics/generic-tag.rs +++ b/src/test/ui/generics/generic-tag.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(unused_assignments)] -#![allow(non_camel_case_types)] +#![allow(unused_assignments, non_camel_case_types, type_param_on_variant_ctor)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-22546.rs b/src/test/ui/issues/issue-22546.rs index c26e457f9e452..57fa59e4c8125 100644 --- a/src/test/ui/issues/issue-22546.rs +++ b/src/test/ui/issues/issue-22546.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(unused_variables)] +#![allow(unused_variables, type_param_on_variant_ctor)] // Parsing patterns with paths with type parameters (issue #22544) use std::default::Default; @@ -49,4 +49,7 @@ fn main() { if let Option::None:: { .. } = Some(8) { panic!(); } + if let Option::::None { .. } = Some(8) { + panic!(); + } } diff --git a/src/test/ui/issues/issue-40003.rs b/src/test/ui/issues/issue-40003.rs index 642de6b8fe352..99477fbc2730e 100644 --- a/src/test/ui/issues/issue-40003.rs +++ b/src/test/ui/issues/issue-40003.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(unused_must_use)] +#![allow(unused_must_use, type_param_on_variant_ctor)] fn main() { if false { test(); } } diff --git a/src/test/ui/issues/issue-61696.rs b/src/test/ui/issues/issue-61696.rs index dca52927fd7c0..cdc9b1a8f04e6 100644 --- a/src/test/ui/issues/issue-61696.rs +++ b/src/test/ui/issues/issue-61696.rs @@ -1,4 +1,5 @@ // run-pass +#![allow(type_param_on_variant_ctor)] pub enum Infallible {} diff --git a/src/test/ui/nll/user-annotations/adt-brace-enums.rs b/src/test/ui/nll/user-annotations/adt-brace-enums.rs index 0d9828342d8cb..3bbd175846d0d 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.rs +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.rs @@ -1,3 +1,4 @@ +#![warn(type_param_on_variant_ctor)] // Unit test for the "user substitutions" that are annotated on each // node. @@ -12,38 +13,78 @@ fn no_annot() { fn annot_underscore() { let c = 66; - SomeEnum::SomeVariant::<_> { t: &c }; + SomeEnum::<_>::SomeVariant { t: &c }; +} + +fn annot_underscore2() { + let c = 66; + SomeEnum::SomeVariant::<_> { t: &c }; //~ WARNING } fn annot_reference_any_lifetime() { let c = 66; - SomeEnum::SomeVariant::<&u32> { t: &c }; + SomeEnum::<&u32>::SomeVariant { t: &c }; +} + +fn annot_reference_any_lifetime2() { + let c = 66; + SomeEnum::SomeVariant::<&u32> { t: &c }; //~ WARNING } fn annot_reference_static_lifetime() { + let c = 66; + SomeEnum::<&'static u32>::SomeVariant { t: &c }; //~ ERROR +} + +fn annot_reference_static_lifetime2() { let c = 66; SomeEnum::SomeVariant::<&'static u32> { t: &c }; //~ ERROR + //~^ WARNING } fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeEnum::<&'a u32>::SomeVariant { t: &c }; //~ ERROR +} + +fn annot_reference_named_lifetime2<'a>(_d: &'a u32) { let c = 66; SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR + //~^ WARNING } fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { - SomeEnum::SomeVariant::<&'a u32> { t: c }; + SomeEnum::<&'a u32>::SomeVariant { t: c }; +} + +fn annot_reference_named_lifetime_ok2<'a>(c: &'a u32) { + SomeEnum::SomeVariant::<&'a u32> { t: c }; //~ WARNING } fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeEnum::<&'a u32>::SomeVariant { t: &c }; //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure2<'a>(_: &'a u32) { let _closure = || { let c = 66; SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR + //~^ WARNING }; } fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { let _closure = || { - SomeEnum::SomeVariant::<&'a u32> { t: c }; + SomeEnum::<&'a u32>::SomeVariant { t: c }; + }; +} + +fn annot_reference_named_lifetime_in_closure_ok2<'a>(c: &'a u32) { + let _closure = || { + SomeEnum::SomeVariant::<&'a u32> { t: c }; //~ WARNING }; } diff --git a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr index e38b77fdcea01..ee16e05258b91 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr @@ -1,42 +1,166 @@ +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:21:28 + | +LL | SomeEnum::SomeVariant::<_> { t: &c }; + | ^^^ + | +note: the lint level is defined here + --> $DIR/adt-brace-enums.rs:1:9 + | +LL | #![warn(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | SomeEnum::<_>::SomeVariant { t: &c }; + | ^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:31:28 + | +LL | SomeEnum::SomeVariant::<&u32> { t: &c }; + | ^^^^^^ + | +help: set the type parameter on the enum + | +LL | SomeEnum::<&u32>::SomeVariant { t: &c }; + | ^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:41:28 + | +LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; + | ^^^^^^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | SomeEnum::<&'static u32>::SomeVariant { t: &c }; + | ^^^^^^^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:52:28 + | +LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; + | ^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; + | ^^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:61:28 + | +LL | SomeEnum::SomeVariant::<&'a u32> { t: c }; + | ^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | SomeEnum::<&'a u32>::SomeVariant { t: c }; + | ^^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:74:32 + | +LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; + | ^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; + | ^^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:87:32 + | +LL | SomeEnum::SomeVariant::<&'a u32> { t: c }; + | ^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | SomeEnum::<&'a u32>::SomeVariant { t: c }; + | ^^^^^^^^^^^ -- + error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:25:48 + --> $DIR/adt-brace-enums.rs:36:48 + | +LL | SomeEnum::<&'static u32>::SomeVariant { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-enums.rs:41:48 | LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; | ^^ | | | borrowed value does not live long enough | requires that `c` is borrowed for `'static` +LL | LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:30:43 + --> $DIR/adt-brace-enums.rs:47:43 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here LL | let c = 66; +LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-enums.rs:52:43 + | +LL | fn annot_reference_named_lifetime2<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +LL | let c = 66; LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough | requires that `c` is borrowed for `'a` +LL | LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:40:47 + --> $DIR/adt-brace-enums.rs:67:47 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here ... +LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-enums.rs:74:47 + | +LL | fn annot_reference_named_lifetime_in_closure2<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough | requires that `c` is borrowed for `'a` +LL | LL | }; | - `c` dropped here while still borrowed -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs index 59cd69c0ca55d..943c9a1299ab0 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs @@ -1,21 +1,51 @@ +#![warn(type_param_on_variant_ctor)] enum Foo<'a> { Bar { field: &'a u32 } } fn in_let() { + let y = 22; + let foo = Foo::Bar { field: &y }; + //~^ ERROR `y` does not live long enough + let Foo::Bar::<'static> { field: _z } = foo; //~ WARNING +} + +fn in_match() { + let y = 22; + let foo = Foo::Bar { field: &y }; + //~^ ERROR `y` does not live long enough + match foo { + Foo::Bar::<'static> { field: _z } => {} //~ WARNING + } +} + +fn in_let_2() { + let y = 22; + let foo = Foo::Bar { field: &y }; + //~^ ERROR `y` does not live long enough + let Foo::<'static>::Bar { field: _z } = foo; +} + +fn in_match_2() { + let y = 22; + let foo = Foo::Bar { field: &y }; + //~^ ERROR `y` does not live long enough + match foo { + Foo::<'static>::Bar { field: _z } => {} + } +} + +fn in_let_3() { let y = 22; let foo = Foo::Bar { field: &y }; - //~^ ERROR `y` does not live long enough - let Foo::Bar::<'static> { field: _z } = foo; + let Foo::Bar { field: _z } = foo; } -fn in_match() { +fn in_match_3() { let y = 22; let foo = Foo::Bar { field: &y }; - //~^ ERROR `y` does not live long enough match foo { - Foo::Bar::<'static> { field: _z } => { - } + Foo::Bar { field: _z } => {} } } diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr index a97e7a9fd46fc..8afec696182ab 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr @@ -1,26 +1,76 @@ +warning: type parameter on variant + --> $DIR/pattern_substs_on_brace_enum_variant.rs:10:18 + | +LL | let Foo::Bar::<'static> { field: _z } = foo; + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/pattern_substs_on_brace_enum_variant.rs:1:9 + | +LL | #![warn(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | let Foo::<'static>::Bar { field: _z } = foo; + | ^^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/pattern_substs_on_brace_enum_variant.rs:18:18 + | +LL | Foo::Bar::<'static> { field: _z } => {} + | ^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | Foo::<'static>::Bar { field: _z } => {} + | ^^^^^^^^^^^ -- + error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:7:33 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:8:32 | -LL | let foo = Foo::Bar { field: &y }; - | ^^ borrowed value does not live long enough +LL | let foo = Foo::Bar { field: &y }; + | ^^ borrowed value does not live long enough LL | -LL | let Foo::Bar::<'static> { field: _z } = foo; - | --------------------------------- type annotation requires that `y` is borrowed for `'static` +LL | let Foo::Bar::<'static> { field: _z } = foo; + | --------------------------------- type annotation requires that `y` is borrowed for `'static` LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:14:33 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:15:32 | -LL | let foo = Foo::Bar { field: &y }; - | ^^ borrowed value does not live long enough +LL | let foo = Foo::Bar { field: &y }; + | ^^ borrowed value does not live long enough ... -LL | Foo::Bar::<'static> { field: _z } => { - | --------------------------------- type annotation requires that `y` is borrowed for `'static` +LL | Foo::Bar::<'static> { field: _z } => {} + | --------------------------------- type annotation requires that `y` is borrowed for `'static` +LL | } +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_brace_enum_variant.rs:24:32 + | +LL | let foo = Foo::Bar { field: &y }; + | ^^ borrowed value does not live long enough +LL | +LL | let Foo::<'static>::Bar { field: _z } = foo; + | --------------------------------- type annotation requires that `y` is borrowed for `'static` +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_brace_enum_variant.rs:31:32 + | +LL | let foo = Foo::Bar { field: &y }; + | ^^ borrowed value does not live long enough ... +LL | Foo::<'static>::Bar { field: _z } => {} + | --------------------------------- type annotation requires that `y` is borrowed for `'static` +LL | } LL | } | - `y` dropped here while still borrowed -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs index 6fa59fdd8d899..3294552cb6208 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs @@ -1,3 +1,4 @@ +#![warn(type_param_on_variant_ctor)] enum Foo<'a> { Bar(&'a u32) } @@ -6,7 +7,7 @@ fn in_let() { let y = 22; let foo = Foo::Bar(&y); //~^ ERROR `y` does not live long enough - let Foo::Bar::<'static>(_z) = foo; + let Foo::Bar::<'static>(_z) = foo; //~ WARNING } fn in_match() { @@ -14,8 +15,7 @@ fn in_match() { let foo = Foo::Bar(&y); //~^ ERROR `y` does not live long enough match foo { - Foo::Bar::<'static>(_z) => { - } + Foo::Bar::<'static>(_z) => {} //~ WARNING } } diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr index 920c906f63a58..32c70672df15f 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr @@ -1,5 +1,32 @@ +warning: type parameter on variant + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:10:19 + | +LL | let Foo::Bar::<'static>(_z) = foo; + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:1:9 + | +LL | #![warn(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | let Foo::<'static>::Bar(_z) = foo; + | ^^^^^^^^^^^ -- + +warning: type parameter on variant + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:18:19 + | +LL | Foo::Bar::<'static>(_z) => {} + | ^^^^^^^^^ + | +help: set the type parameter on the enum + | +LL | Foo::<'static>::Bar(_z) => {} + | ^^^^^^^^^^^ -- + error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:7:24 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:8:24 | LL | let foo = Foo::Bar(&y); | ^^ borrowed value does not live long enough @@ -10,14 +37,14 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:14:24 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:15:24 | LL | let foo = Foo::Bar(&y); | ^^ borrowed value does not live long enough ... -LL | Foo::Bar::<'static>(_z) => { +LL | Foo::Bar::<'static>(_z) => {} | ----------------------- type annotation requires that `y` is borrowed for `'static` -... +LL | } LL | } | - `y` dropped here while still borrowed diff --git a/src/test/ui/nullable-pointer-iotareduction.rs b/src/test/ui/nullable-pointer-iotareduction.rs index 4c6964f294b5e..78e76e618716c 100644 --- a/src/test/ui/nullable-pointer-iotareduction.rs +++ b/src/test/ui/nullable-pointer-iotareduction.rs @@ -1,6 +1,7 @@ // run-pass #![feature(box_syntax)] +#![allow(type_param_on_variant_ctor)] // Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions, // which "says that a destructor applied to an object built from a constructor diff --git a/src/test/ui/occurs-check-3.rs b/src/test/ui/occurs-check-3.rs index 9c04204010b77..2ab35699ae7ea 100644 --- a/src/test/ui/occurs-check-3.rs +++ b/src/test/ui/occurs-check-3.rs @@ -1,4 +1,5 @@ // From Issue #778 +#![allow(type_param_on_variant_ctor)] enum Clam { A(T) } fn main() { let c; c = Clam::A(c); match c { Clam::A::(_) => { } } } diff --git a/src/test/ui/occurs-check-3.stderr b/src/test/ui/occurs-check-3.stderr index 04c404d543a95..4d7eeeb91f69f 100644 --- a/src/test/ui/occurs-check-3.stderr +++ b/src/test/ui/occurs-check-3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/occurs-check-3.rs:4:24 + --> $DIR/occurs-check-3.rs:5:24 | LL | fn main() { let c; c = Clam::A(c); match c { Clam::A::(_) => { } } } | ^^^^^^^^^^ cyclic type of infinite size diff --git a/src/test/ui/shadow.rs b/src/test/ui/shadow.rs index 2495c8f47e7e0..f7608c10b2f3a 100644 --- a/src/test/ui/shadow.rs +++ b/src/test/ui/shadow.rs @@ -1,7 +1,6 @@ // run-pass -#![allow(non_camel_case_types)] -#![allow(dead_code)] +#![allow(non_camel_case_types, type_param_on_variant_ctor, dead_code)] fn foo(c: Vec ) { let a: isize = 5; let mut b: Vec = Vec::new(); diff --git a/src/test/ui/size-and-align.rs b/src/test/ui/size-and-align.rs index a32b5de72920a..9439f43517fbd 100644 --- a/src/test/ui/size-and-align.rs +++ b/src/test/ui/size-and-align.rs @@ -1,6 +1,6 @@ // run-pass -#![allow(non_camel_case_types)] +#![allow(non_camel_case_types, type_param_on_variant_ctor)] enum clam { a(T, isize), b, } fn uhoh(v: Vec> ) { diff --git a/src/test/ui/structs-enums/simple-match-generic-tag.rs b/src/test/ui/structs-enums/simple-match-generic-tag.rs index 762fd49ad2475..d01734774a5bf 100644 --- a/src/test/ui/structs-enums/simple-match-generic-tag.rs +++ b/src/test/ui/structs-enums/simple-match-generic-tag.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] +#![allow(dead_code, non_camel_case_types, type_param_on_variant_ctor)] enum opt { none, some(T) } diff --git a/src/test/ui/try-poll.rs b/src/test/ui/try-poll.rs index d42e51c7405ba..38170fd1170c5 100644 --- a/src/test/ui/try-poll.rs +++ b/src/test/ui/try-poll.rs @@ -1,6 +1,6 @@ // build-pass (FIXME(62277): could be check-pass?) -#![allow(dead_code, unused)] +#![allow(dead_code, unused, type_param_on_variant_ctor)] use std::task::Poll; diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs index 19fcc78721ab1..67fc8c968c769 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs @@ -1,4 +1,5 @@ // run-pass +#![allow(type_param_on_variant_ctor)] // Check that resolving, in the value namespace, to an `enum` variant // through a type alias is well behaved in the presence of generics. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs index f182c3ba8c798..c4d058f41eb51 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs @@ -52,7 +52,7 @@ fn main() { // Tuple struct variant Enum::<()>::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR multiple segments with type parameters are not allowed Alias::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed for this type [E0109] @@ -70,7 +70,7 @@ fn main() { // Struct variant Enum::<()>::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR multiple segments with type parameters are not allowed Alias::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed for this type [E0109] @@ -88,7 +88,7 @@ fn main() { // Unit variant Enum::<()>::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR multiple segments with type parameters are not allowed Alias::UVariant::<()>; //~^ ERROR type arguments are not allowed for this type [E0109] diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index 412b4dbda4fde..114d209f13bba 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -154,11 +154,13 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::UVariant::<()>; | ^^ type argument not allowed -error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:54:29 +error: multiple segments with type parameters are not allowed + --> $DIR/enum-variant-generic-args.rs:54:11 | LL | Enum::<()>::TSVariant::<()>(()); - | ^^ type argument not allowed + | ^^^^ ^^^^ + | + = note: only a single path segment can specify type parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:57:24 @@ -196,11 +198,13 @@ error[E0109]: type arguments are not allowed for this type LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ type argument not allowed -error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:72:28 +error: multiple segments with type parameters are not allowed + --> $DIR/enum-variant-generic-args.rs:72:11 | LL | Enum::<()>::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | ^^^^ ^^^^ + | + = note: only a single path segment can specify type parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:75:23 @@ -238,11 +242,13 @@ error[E0109]: type arguments are not allowed for this type LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed -error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:90:28 +error: multiple segments with type parameters are not allowed + --> $DIR/enum-variant-generic-args.rs:90:11 | LL | Enum::<()>::UVariant::<()>; - | ^^ type argument not allowed + | ^^^^ ^^^^ + | + = note: only a single path segment can specify type parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:93:23 diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs index c1153fa4dc7b4..53ef40e291e0a 100644 --- a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs +++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs @@ -1,3 +1,4 @@ +#![deny(type_param_on_variant_ctor)] // Check that a generic type for an `enum` admits type application // on both the type constructor and the generic type's variant. // @@ -8,7 +9,7 @@ type Alias = Option; fn main() { let _ = Option::::None; // OK - let _ = Option::None::; // OK (Lint in future!) + let _ = Option::None::; //~ ERROR type parameter on variant let _ = Alias::::None; // OK let _ = Alias::None::; //~ ERROR type arguments are not allowed for this type } diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr index a1064d6925111..261eed15498d6 100644 --- a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr +++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr @@ -1,9 +1,25 @@ +error: type parameter on variant + --> $DIR/no-type-application-on-aliased-enum-variant.rs:12:27 + | +LL | let _ = Option::None::; + | ^^^^ + | +note: the lint level is defined here + --> $DIR/no-type-application-on-aliased-enum-variant.rs:1:9 + | +LL | #![deny(type_param_on_variant_ctor)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: set the type parameter on the enum + | +LL | let _ = Option::::None; + | ^^^^^^ -- + error[E0109]: type arguments are not allowed for this type - --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27 + --> $DIR/no-type-application-on-aliased-enum-variant.rs:14:27 | LL | let _ = Alias::None::; | ^^ type argument not allowed -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0109`.