From aafdbb693eb4a4f7a6f885b75a24a528382ab9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 21 Feb 2020 15:52:44 -0800 Subject: [PATCH 1/4] Treat `ExprKind::Path` and `ExprKind::Struct` the same for the purposes of path checking --- src/librustc_ast_lowering/path.rs | 17 ++++- src/librustc_error_codes/error_codes/E0109.md | 6 +- src/librustc_typeck/astconv.rs | 72 ++++++++++++++----- src/librustc_typeck/check/mod.rs | 5 +- src/librustc_typeck/collect.rs | 3 +- ...lifetime-in-def-not-in-path-issue-69356.rs | 24 +++++++ .../pattern_substs_on_brace_enum_variant.rs | 41 +++++++++-- ...attern_substs_on_brace_enum_variant.stderr | 45 +++++++++--- 8 files changed, 172 insertions(+), 41 deletions(-) create mode 100644 src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.rs diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index b45a06e1c1d2a..ee03686971152 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) 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_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 78c05a51e4fbd..cc722a3cc96c2 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(|_| segment.ident.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, @@ -2509,13 +2540,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &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 +2556,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 +2567,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 +2580,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 +2625,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 +2680,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..8ed43980b8646 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) => { 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/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..ccb8b41b6076c --- /dev/null +++ b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.rs @@ -0,0 +1,24 @@ +// check-pass + +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 {}) {} + // // FIXME: these should be linted against. + 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:: {}) {} +} 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..2b712cc641891 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 @@ -3,19 +3,48 @@ enum Foo<'a> { } 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; +} + +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 } => {} + } +} + +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..202462d540e96 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,49 @@ 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:7: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:14: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:23: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:30: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`. From 0339831b12fdb7a6502fd9db164dc6017bf6c3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 24 Feb 2020 15:19:27 -0800 Subject: [PATCH 2/4] Lint against `E::V::

`, suggest `E::

::V` --- src/librustc_ast_lowering/lib.rs | 4 +- src/librustc_ast_lowering/path.rs | 3 +- src/librustc_hir/hir.rs | 4 +- src/librustc_session/lint/builtin.rs | 8 ++ src/librustc_typeck/astconv.rs | 34 ++++- src/test/ui/binding/simple-generic-match.rs | 2 +- src/test/ui/binding/use-uninit-match.rs | 10 +- src/test/ui/binding/use-uninit-match2.rs | 11 +- src/test/ui/constructor-lifetime-args.rs | 6 + src/test/ui/constructor-lifetime-args.stderr | 39 +++++- .../ui/deriving/deriving-associated-types.rs | 1 + .../deriving/deriving-clone-generic-enum.rs | 2 +- .../dropck_no_diverge_on_nonregular_3.rs | 5 + .../dropck_no_diverge_on_nonregular_3.stderr | 38 +++++- src/test/ui/enum-discriminant/niche.rs | 1 + ...lifetime-in-def-not-in-path-issue-69356.rs | 14 +- ...time-in-def-not-in-path-issue-69356.stderr | 100 ++++++++++++++ src/test/ui/generics/generic-recursive-tag.rs | 2 +- src/test/ui/generics/generic-tag-match.rs | 3 +- src/test/ui/generics/generic-tag-values.rs | 2 +- src/test/ui/generics/generic-tag.rs | 3 +- src/test/ui/issues/issue-22546.rs | 5 +- src/test/ui/issues/issue-40003.rs | 2 +- src/test/ui/issues/issue-61696.rs | 1 + .../nll/user-annotations/adt-brace-enums.rs | 48 ++++++- .../user-annotations/adt-brace-enums.stderr | 128 +++++++++++++++++- .../pattern_substs_on_brace_enum_variant.rs | 4 +- ...attern_substs_on_brace_enum_variant.stderr | 23 ++++ .../pattern_substs_on_tuple_enum_variant.rs | 5 +- ...attern_substs_on_tuple_enum_variant.stderr | 27 +++- src/test/ui/nullable-pointer-iotareduction.rs | 1 + src/test/ui/occurs-check-3.rs | 1 + src/test/ui/occurs-check-3.stderr | 2 +- src/test/ui/shadow.rs | 3 +- src/test/ui/size-and-align.rs | 2 +- .../structs-enums/simple-match-generic-tag.rs | 3 +- src/test/ui/try-poll.rs | 2 +- .../enum-variant-generic-args-pass.rs | 1 + .../enum-variant-generic-args.rs | 2 +- .../enum-variant-generic-args.stderr | 8 +- ...ype-application-on-aliased-enum-variant.rs | 2 +- ...application-on-aliased-enum-variant.stderr | 12 ++ 42 files changed, 517 insertions(+), 57 deletions(-) create mode 100644 src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.stderr 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 ee03686971152..5e1643493654a 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -360,6 +360,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment.ident, segment.id, id, ); + let param_span = path_span.with_lo(segment.ident.span.shrink_to_hi().lo()); hir::PathSegment { ident: segment.ident, hir_id: Some(id), @@ -368,7 +369,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_span))) }, } } 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..c358cf90a6829 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, + Warn, + "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 cc722a3cc96c2..0b3d11dfc260c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2500,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. @@ -2535,6 +2534,37 @@ 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 { hir_id: Some(hir_id), args: Some(args), .. }] = segments { + let span = args.span; + if span.hi() == span.lo() { + // The params were not written by the user, but rather derived. These are expected. + return; + } + self.tcx().struct_span_lint_hir( + lint::builtin::TYPE_PARAM_ON_VARIANT_CTOR, + *hir_id, + span, + |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, 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..927b530793838 100644 --- a/src/test/ui/constructor-lifetime-args.rs +++ b/src/test/ui/constructor-lifetime-args.rs @@ -21,6 +21,12 @@ fn main() { E::V(&0); // OK E::V::<'static>(&0); //~^ ERROR wrong number of lifetime arguments: expected 2, found 1 + //~| WARNING type parameter on variant E::V::<'static, 'static, 'static>(&0); //~^ ERROR wrong number of lifetime arguments: expected 2, found 3 + //~| WARNING 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..0ad8587356b91 100644 --- a/src/test/ui/constructor-lifetime-args.stderr +++ b/src/test/ui/constructor-lifetime-args.stderr @@ -10,18 +10,53 @@ error[E0107]: wrong number of lifetime arguments: expected 2, found 3 LL | S::<'static, 'static, 'static>(&0, &0); | ^^^^^^^ unexpected lifetime argument +warning: type parameter on variant + --> $DIR/constructor-lifetime-args.rs:22:9 + | +LL | E::V::<'static>(&0); + | ^^^^^^^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +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 | LL | E::V::<'static>(&0); | ^^^^^^^^^^^^^^^ expected 2 lifetime arguments +warning: type parameter on variant + --> $DIR/constructor-lifetime-args.rs:25:9 + | +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:25: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:28: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:30:27 + | +LL | E::<'static, 'static, 'static>::V(&0); + | ^^^^^^^ unexpected lifetime argument + +error: aborting due to 6 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..110260c45a018 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 @@ -33,4 +33,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..557c6b6010e91 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,3 +1,15 @@ +warning: type parameter on variant + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:29 + | +LL | Some(Wrapper::Simple::); + | ^^^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +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 | @@ -22,5 +34,29 @@ 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:37: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:38: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:38: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/lifetime-in-def-not-in-path-issue-69356.rs b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.rs index ccb8b41b6076c..6063e49209aa0 100644 --- 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 @@ -14,11 +14,17 @@ pub fn main() { if let Foo::::Unit = Foo::::Unit {} if let Foo::::Tuple() = Foo::::Tuple() {} if let Foo::::Struct {} = (Foo::::Struct {}) {} - // // FIXME: these should be linted against. - let _ = Foo::Unit::; - let _ = Foo::Tuple::(); - let _ = 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..7e17d4807d84d --- /dev/null +++ b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.stderr @@ -0,0 +1,100 @@ +warning: type parameter on variant + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:18:22 + | +LL | let _ = Foo::Unit::; + | ^^^^^^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:19:23 + | +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:20:24 + | +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:21:43 + | +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:21:21 + | +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:24:47 + | +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:24:22 + | +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:27:51 + | +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:27:23 + | +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..13d180b0d94d3 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.rs +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.rs @@ -12,38 +12,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..ee26fa1fe7ca9 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,162 @@ +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:20:26 + | +LL | SomeEnum::SomeVariant::<_> { t: &c }; + | ^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +help: set the type parameter on the enum + | +LL | SomeEnum::<_>::SomeVariant { t: &c }; + | ^^^^^ -- + +warning: type parameter on variant + --> $DIR/adt-brace-enums.rs:30:26 + | +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:40:26 + | +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:51:26 + | +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:60:26 + | +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:73:30 + | +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:86:30 + | +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:35: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:40: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:46: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:51: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:66: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:73: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 2b712cc641891..8eaa5c4bdc01c 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 @@ -6,7 +6,7 @@ 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; + let Foo::Bar::<'static> { field: _z } = foo; //~ WARNING } fn in_match() { @@ -14,7 +14,7 @@ fn in_match() { let foo = Foo::Bar { field: &y }; //~^ ERROR `y` does not live long enough match foo { - Foo::Bar::<'static> { field: _z } => {} + Foo::Bar::<'static> { field: _z } => {} //~ WARNING } } 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 202462d540e96..3c61bdcc04aff 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,3 +1,26 @@ +warning: type parameter on variant + --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:16 + | +LL | let Foo::Bar::<'static> { field: _z } = foo; + | ^^^^^^^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:17:16 + | +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:32 | 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..893a96b34cf9f 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 @@ -6,7 +6,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 +14,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..d3cc4a55d988b 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,3 +1,26 @@ +warning: type parameter on variant + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:17 + | +LL | let Foo::Bar::<'static>(_z) = foo; + | ^^^^^^^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:17:17 + | +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 | @@ -15,9 +38,9 @@ error[E0597]: `y` does not live long enough 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..4d8186db76a30 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 @@ -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] 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..fee2ce1c52f9a 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 @@ -196,11 +196,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:5 | 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 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..4c972598a4b34 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 @@ -8,7 +8,7 @@ type Alias = Option; fn main() { let _ = Option::::None; // OK - let _ = Option::None::; // OK (Lint in future!) + let _ = Option::None::; //~ WARNING 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..d79da1731895c 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,3 +1,15 @@ +warning: type parameter on variant + --> $DIR/no-type-application-on-aliased-enum-variant.rs:11:25 + | +LL | let _ = Option::None::; + | ^^^^^^ + | + = note: `#[warn(type_param_on_variant_ctor)]` on by default +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 | From 9d58e12af574dff2085abcd3fa3e32d22b7d66ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 24 Feb 2020 16:22:49 -0800 Subject: [PATCH 3/4] Specific error for +1 path segments with params --- src/librustc_ast_lowering/path.rs | 5 +- src/librustc_typeck/astconv.rs | 12 +-- src/librustc_typeck/check/mod.rs | 23 +++--- src/test/ui/constructor-lifetime-args.stderr | 8 +- .../dropck_no_diverge_on_nonregular_3.stderr | 4 +- src/test/ui/enum/forbid-many-type-params.rs | 21 ++++++ .../ui/enum/forbid-many-type-params.stderr | 74 +++++++++++++++++++ ...time-in-def-not-in-path-issue-69356.stderr | 36 ++++----- .../user-annotations/adt-brace-enums.stderr | 28 +++---- ...attern_substs_on_brace_enum_variant.stderr | 8 +- ...attern_substs_on_tuple_enum_variant.stderr | 8 +- .../enum-variant-generic-args.rs | 4 +- .../enum-variant-generic-args.stderr | 20 +++-- ...application-on-aliased-enum-variant.stderr | 4 +- 14 files changed, 180 insertions(+), 75 deletions(-) create mode 100644 src/test/ui/enum/forbid-many-type-params.rs create mode 100644 src/test/ui/enum/forbid-many-type-params.stderr diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 5e1643493654a..fb5c809b9f052 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -360,7 +360,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment.ident, segment.id, id, ); - let param_span = path_span.with_lo(segment.ident.span.shrink_to_hi().lo()); + 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), @@ -369,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, param_span))) + Some(self.arena.alloc(generic_args.into_generic_args(self.arena, param_sp))) }, } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0b3d11dfc260c..8030bd7bc245a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2327,7 +2327,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) -> bool { let segments_with_params = segments .into_iter() - .filter_map(|segment| segment.args.map(|_| segment.ident.span)) + .filter_map(|segment| segment.args.map(|arg| arg.span)) .collect::>(); if segments_with_params.len() <= 1 { return false; @@ -2537,16 +2537,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { 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 { hir_id: Some(hir_id), args: Some(args), .. }] = segments { - let span = args.span; - if span.hi() == span.lo() { + 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, - span, + sp, |lint| { let mut err = lint.build("type parameter on variant"); let sugg_span = prev.ident.span.shrink_to_hi(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8ed43980b8646..1f86ddb9c97b4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5378,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 }); @@ -5415,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/test/ui/constructor-lifetime-args.stderr b/src/test/ui/constructor-lifetime-args.stderr index 0ad8587356b91..8719bdf2e70da 100644 --- a/src/test/ui/constructor-lifetime-args.stderr +++ b/src/test/ui/constructor-lifetime-args.stderr @@ -11,10 +11,10 @@ LL | S::<'static, 'static, 'static>(&0, &0); | ^^^^^^^ unexpected lifetime argument warning: type parameter on variant - --> $DIR/constructor-lifetime-args.rs:22:9 + --> $DIR/constructor-lifetime-args.rs:22:11 | LL | E::V::<'static>(&0); - | ^^^^^^^^^^^ + | ^^^^^^^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum @@ -29,10 +29,10 @@ LL | E::V::<'static>(&0); | ^^^^^^^^^^^^^^^ expected 2 lifetime arguments warning: type parameter on variant - --> $DIR/constructor-lifetime-args.rs:25:9 + --> $DIR/constructor-lifetime-args.rs:25:11 | LL | E::V::<'static, 'static, 'static>(&0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: set the type parameter on the enum | 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 557c6b6010e91..eb5a6f440b0d4 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,8 +1,8 @@ warning: type parameter on variant - --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:29 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:31 | LL | Some(Wrapper::Simple::); - | ^^^^^^^ + | ^^^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum 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.stderr b/src/test/ui/enum/lifetime-in-def-not-in-path-issue-69356.stderr index 7e17d4807d84d..70cbdbc61d9a8 100644 --- 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 @@ -1,8 +1,8 @@ warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:18:22 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:18:24 | LL | let _ = Foo::Unit::; - | ^^^^^^^^^^ + | ^^^^^^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum @@ -11,10 +11,10 @@ LL | let _ = Foo::::Unit; | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:19:23 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:19:25 | LL | let _ = Foo::Tuple::(); - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -22,10 +22,10 @@ LL | let _ = Foo::::Tuple(); | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:20:24 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:20:26 | LL | let _ = Foo::Struct:: {}; - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -33,10 +33,10 @@ LL | let _ = Foo::::Struct {}; | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:43 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:45 | LL | if let Foo::Unit:: = Foo::Unit:: {} - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -44,10 +44,10 @@ LL | if let Foo::Unit:: = Foo::::Unit {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:21 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:23 | LL | if let Foo::Unit:: = Foo::Unit:: {} - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -55,10 +55,10 @@ LL | if let Foo::::Unit = Foo::Unit:: {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:24:47 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:24:49 | LL | if let Foo::Tuple::() = Foo::Tuple::() {} - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -66,10 +66,10 @@ LL | if let Foo::Tuple::() = Foo::::Tuple() {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:24:22 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:24:24 | LL | if let Foo::Tuple::() = Foo::Tuple::() {} - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -77,10 +77,10 @@ LL | if let Foo::::Tuple() = Foo::Tuple::() {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:27:51 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:27:53 | LL | if let Foo::Struct:: {} = (Foo::Struct:: {}) {} - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | @@ -88,10 +88,10 @@ LL | if let Foo::Struct:: {} = (Foo::::Struct {}) {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:27:23 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:27:25 | LL | if let Foo::Struct:: {} = (Foo::Struct:: {}) {} - | ^^^^^^^^^^ + | ^^^^^^^^ | help: set the type parameter on the enum | 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 ee26fa1fe7ca9..9272990c29fe2 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr @@ -1,8 +1,8 @@ warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:20:26 + --> $DIR/adt-brace-enums.rs:20:28 | LL | SomeEnum::SomeVariant::<_> { t: &c }; - | ^^^^^ + | ^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum @@ -11,10 +11,10 @@ LL | SomeEnum::<_>::SomeVariant { t: &c }; | ^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:30:26 + --> $DIR/adt-brace-enums.rs:30:28 | LL | SomeEnum::SomeVariant::<&u32> { t: &c }; - | ^^^^^^^^ + | ^^^^^^ | help: set the type parameter on the enum | @@ -22,10 +22,10 @@ LL | SomeEnum::<&u32>::SomeVariant { t: &c }; | ^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:40:26 + --> $DIR/adt-brace-enums.rs:40:28 | LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ | help: set the type parameter on the enum | @@ -33,10 +33,10 @@ LL | SomeEnum::<&'static u32>::SomeVariant { t: &c }; | ^^^^^^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:51:26 + --> $DIR/adt-brace-enums.rs:51:28 | LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; - | ^^^^^^^^^^^ + | ^^^^^^^^^ | help: set the type parameter on the enum | @@ -44,10 +44,10 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:60:26 + --> $DIR/adt-brace-enums.rs:60:28 | LL | SomeEnum::SomeVariant::<&'a u32> { t: c }; - | ^^^^^^^^^^^ + | ^^^^^^^^^ | help: set the type parameter on the enum | @@ -55,10 +55,10 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: c }; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:73:30 + --> $DIR/adt-brace-enums.rs:73:32 | LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; - | ^^^^^^^^^^^ + | ^^^^^^^^^ | help: set the type parameter on the enum | @@ -66,10 +66,10 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:86:30 + --> $DIR/adt-brace-enums.rs:86:32 | LL | SomeEnum::SomeVariant::<&'a u32> { t: c }; - | ^^^^^^^^^^^ + | ^^^^^^^^^ | help: set the type parameter on the enum | 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 3c61bdcc04aff..9440f50b11256 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,8 +1,8 @@ warning: type parameter on variant - --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:16 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:18 | LL | let Foo::Bar::<'static> { field: _z } = foo; - | ^^^^^^^^^^^ + | ^^^^^^^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum @@ -11,10 +11,10 @@ LL | let Foo::<'static>::Bar { field: _z } = foo; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/pattern_substs_on_brace_enum_variant.rs:17:16 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:17:18 | LL | Foo::Bar::<'static> { field: _z } => {} - | ^^^^^^^^^^^ + | ^^^^^^^^^ | help: set the type parameter on the enum | 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 d3cc4a55d988b..f56d11fcff834 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,8 +1,8 @@ warning: type parameter on variant - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:17 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:19 | LL | let Foo::Bar::<'static>(_z) = foo; - | ^^^^^^^^^^^ + | ^^^^^^^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum @@ -11,10 +11,10 @@ LL | let Foo::<'static>::Bar(_z) = foo; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:17:17 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:17:19 | LL | Foo::Bar::<'static>(_z) => {} - | ^^^^^^^^^^^ + | ^^^^^^^^^ | help: set the type parameter on the enum | 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 4d8186db76a30..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] @@ -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 fee2ce1c52f9a..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 @@ -197,10 +199,10 @@ LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error: multiple segments with type parameters are not allowed - --> $DIR/enum-variant-generic-args.rs:72:5 + --> $DIR/enum-variant-generic-args.rs:72:11 | LL | Enum::<()>::SVariant::<()> { v: () }; - | ^^^^ ^^^^^^^^ + | ^^^^ ^^^^ | = note: only a single path segment can specify type parameters @@ -240,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.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr index d79da1731895c..951947b9402ed 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,8 +1,8 @@ warning: type parameter on variant - --> $DIR/no-type-application-on-aliased-enum-variant.rs:11:25 + --> $DIR/no-type-application-on-aliased-enum-variant.rs:11:27 | LL | let _ = Option::None::; - | ^^^^^^ + | ^^^^ | = note: `#[warn(type_param_on_variant_ctor)]` on by default help: set the type parameter on the enum From 63379aa65ca88eff9060ae8ee16a0717104f657b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 24 Feb 2020 16:43:09 -0800 Subject: [PATCH 4/4] Allow lint `type_param_on_variant_ctor` by default --- src/librustc_session/lint/builtin.rs | 2 +- src/test/ui/constructor-lifetime-args.rs | 5 +-- src/test/ui/constructor-lifetime-args.stderr | 28 +++++++++------- .../dropck_no_diverge_on_nonregular_3.rs | 1 + .../dropck_no_diverge_on_nonregular_3.stderr | 20 +++++++----- ...lifetime-in-def-not-in-path-issue-69356.rs | 1 + ...time-in-def-not-in-path-issue-69356.stderr | 24 ++++++++------ .../nll/user-annotations/adt-brace-enums.rs | 1 + .../user-annotations/adt-brace-enums.stderr | 32 +++++++++++-------- .../pattern_substs_on_brace_enum_variant.rs | 1 + ...attern_substs_on_brace_enum_variant.stderr | 18 +++++++---- .../pattern_substs_on_tuple_enum_variant.rs | 1 + ...attern_substs_on_tuple_enum_variant.stderr | 14 +++++--- ...ype-application-on-aliased-enum-variant.rs | 3 +- ...application-on-aliased-enum-variant.stderr | 14 +++++--- 15 files changed, 100 insertions(+), 65 deletions(-) diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index c358cf90a6829..d856b89b136d5 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -258,7 +258,7 @@ declare_lint! { declare_lint! { pub TYPE_PARAM_ON_VARIANT_CTOR, - Warn, + Allow, "detects generic arguments in path segments corresponding to an enum variant instead of the \ enum itself", } diff --git a/src/test/ui/constructor-lifetime-args.rs b/src/test/ui/constructor-lifetime-args.rs index 927b530793838..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,10 +22,10 @@ fn main() { E::V(&0); // OK E::V::<'static>(&0); //~^ ERROR wrong number of lifetime arguments: expected 2, found 1 - //~| WARNING type parameter on variant + //~| ERROR type parameter on variant E::V::<'static, 'static, 'static>(&0); //~^ ERROR wrong number of lifetime arguments: expected 2, found 3 - //~| WARNING type parameter on variant + //~| 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); diff --git a/src/test/ui/constructor-lifetime-args.stderr b/src/test/ui/constructor-lifetime-args.stderr index 8719bdf2e70da..b19bfda9af4b0 100644 --- a/src/test/ui/constructor-lifetime-args.stderr +++ b/src/test/ui/constructor-lifetime-args.stderr @@ -1,35 +1,39 @@ 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 -warning: type parameter on variant - --> $DIR/constructor-lifetime-args.rs:22:11 +error: type parameter on variant + --> $DIR/constructor-lifetime-args.rs:23:11 | LL | E::V::<'static>(&0); | ^^^^^^^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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 -warning: type parameter on variant - --> $DIR/constructor-lifetime-args.rs:25:11 +error: type parameter on variant + --> $DIR/constructor-lifetime-args.rs:26:11 | LL | E::V::<'static, 'static, 'static>(&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,23 +44,23 @@ LL | E::<'static, 'static, 'static>::V(&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- error[E0107]: wrong number of lifetime arguments: expected 2, found 3 - --> $DIR/constructor-lifetime-args.rs:25:30 + --> $DIR/constructor-lifetime-args.rs:26:30 | LL | E::V::<'static, 'static, 'static>(&0); | ^^^^^^^ unexpected lifetime argument error[E0107]: wrong number of lifetime arguments: expected 2, found 1 - --> $DIR/constructor-lifetime-args.rs:28:5 + --> $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:30:27 + --> $DIR/constructor-lifetime-args.rs:31:27 | LL | E::<'static, 'static, 'static>::V(&0); | ^^^^^^^ unexpected lifetime argument -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0107`. 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 110260c45a018..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. // 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 eb5a6f440b0d4..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,17 +1,21 @@ warning: type parameter on variant - --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:31 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:34:31 | LL | Some(Wrapper::Simple::); | ^^^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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 = | ^ @@ -19,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::); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +31,7 @@ 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::); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +39,7 @@ LL | Some(Wrapper::Simple::); = note: overflowed on FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> error[E0320]: overflow while adding drop-check rules for std::option::Option> - --> $DIR/dropck_no_diverge_on_nonregular_3.rs:37:9 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:38:9 | LL | let v = | ^ @@ -43,7 +47,7 @@ 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:38:9 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:39:9 | LL | Some(Wrapper::::Simple); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +55,7 @@ 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:38:14 + --> $DIR/dropck_no_diverge_on_nonregular_3.rs:39:14 | LL | Some(Wrapper::::Simple); | ^^^^^^^^^^^^^^^^^^^^^^ 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 index 6063e49209aa0..8bab651b46557 100644 --- 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 @@ -1,4 +1,5 @@ // check-pass +#![warn(type_param_on_variant_ctor)] pub enum Foo<'a, T: 'a> { Struct {}, 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 index 70cbdbc61d9a8..efc46893415ca 100644 --- 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 @@ -1,17 +1,21 @@ warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:18:24 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:19:24 | LL | let _ = Foo::Unit::; | ^^^^^^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:19:25 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:20:25 | LL | let _ = Foo::Tuple::(); | ^^^^^^^^ @@ -22,7 +26,7 @@ LL | let _ = Foo::::Tuple(); | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:20:26 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:26 | LL | let _ = Foo::Struct:: {}; | ^^^^^^^^ @@ -33,7 +37,7 @@ LL | let _ = Foo::::Struct {}; | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:45 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:22:45 | LL | if let Foo::Unit:: = Foo::Unit:: {} | ^^^^^^^^ @@ -44,7 +48,7 @@ LL | if let Foo::Unit:: = Foo::::Unit {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:21:23 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:22:23 | LL | if let Foo::Unit:: = Foo::Unit:: {} | ^^^^^^^^ @@ -55,7 +59,7 @@ LL | if let Foo::::Unit = Foo::Unit:: {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:24:49 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:25:49 | LL | if let Foo::Tuple::() = Foo::Tuple::() {} | ^^^^^^^^ @@ -66,7 +70,7 @@ LL | if let Foo::Tuple::() = Foo::::Tuple() {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:24:24 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:25:24 | LL | if let Foo::Tuple::() = Foo::Tuple::() {} | ^^^^^^^^ @@ -77,7 +81,7 @@ LL | if let Foo::::Tuple() = Foo::Tuple::() {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:27:53 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:28:53 | LL | if let Foo::Struct:: {} = (Foo::Struct:: {}) {} | ^^^^^^^^ @@ -88,7 +92,7 @@ LL | if let Foo::Struct:: {} = (Foo::::Struct {}) {} | ^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:27:25 + --> $DIR/lifetime-in-def-not-in-path-issue-69356.rs:28:25 | LL | if let Foo::Struct:: {} = (Foo::Struct:: {}) {} | ^^^^^^^^ 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 13d180b0d94d3..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. 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 9272990c29fe2..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,17 +1,21 @@ warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:20:28 + --> $DIR/adt-brace-enums.rs:21:28 | LL | SomeEnum::SomeVariant::<_> { t: &c }; | ^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:30:28 + --> $DIR/adt-brace-enums.rs:31:28 | LL | SomeEnum::SomeVariant::<&u32> { t: &c }; | ^^^^^^ @@ -22,7 +26,7 @@ LL | SomeEnum::<&u32>::SomeVariant { t: &c }; | ^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:40:28 + --> $DIR/adt-brace-enums.rs:41:28 | LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; | ^^^^^^^^^^^^^^ @@ -33,7 +37,7 @@ LL | SomeEnum::<&'static u32>::SomeVariant { t: &c }; | ^^^^^^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:51:28 + --> $DIR/adt-brace-enums.rs:52:28 | LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^^^^^^^^ @@ -44,7 +48,7 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:60:28 + --> $DIR/adt-brace-enums.rs:61:28 | LL | SomeEnum::SomeVariant::<&'a u32> { t: c }; | ^^^^^^^^^ @@ -55,7 +59,7 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: c }; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:73:32 + --> $DIR/adt-brace-enums.rs:74:32 | LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^^^^^^^^ @@ -66,7 +70,7 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: &c }; | ^^^^^^^^^^^ -- warning: type parameter on variant - --> $DIR/adt-brace-enums.rs:86:32 + --> $DIR/adt-brace-enums.rs:87:32 | LL | SomeEnum::SomeVariant::<&'a u32> { t: c }; | ^^^^^^^^^ @@ -77,7 +81,7 @@ LL | SomeEnum::<&'a u32>::SomeVariant { t: c }; | ^^^^^^^^^^^ -- error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:35:48 + --> $DIR/adt-brace-enums.rs:36:48 | LL | SomeEnum::<&'static u32>::SomeVariant { t: &c }; | ^^ @@ -88,7 +92,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:40:48 + --> $DIR/adt-brace-enums.rs:41:48 | LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; | ^^ @@ -100,7 +104,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:46:43 + --> $DIR/adt-brace-enums.rs:47:43 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -114,7 +118,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:51:43 + --> $DIR/adt-brace-enums.rs:52:43 | LL | fn annot_reference_named_lifetime2<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -129,7 +133,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:66:47 + --> $DIR/adt-brace-enums.rs:67:47 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here @@ -143,7 +147,7 @@ LL | }; | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:73:47 + --> $DIR/adt-brace-enums.rs:74:47 | LL | fn annot_reference_named_lifetime_in_closure2<'a>(_: &'a u32) { | -- lifetime `'a` defined here 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 8eaa5c4bdc01c..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,3 +1,4 @@ +#![warn(type_param_on_variant_ctor)] enum Foo<'a> { Bar { field: &'a u32 } } 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 9440f50b11256..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,17 +1,21 @@ warning: type parameter on variant - --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:18 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:10:18 | LL | let Foo::Bar::<'static> { field: _z } = foo; | ^^^^^^^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:17:18 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:18:18 | LL | Foo::Bar::<'static> { field: _z } => {} | ^^^^^^^^^ @@ -22,7 +26,7 @@ LL | Foo::<'static>::Bar { field: _z } => {} | ^^^^^^^^^^^ -- error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:7:32 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:8:32 | LL | let foo = Foo::Bar { field: &y }; | ^^ borrowed value does not live long enough @@ -33,7 +37,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:14:32 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:15:32 | LL | let foo = Foo::Bar { field: &y }; | ^^ borrowed value does not live long enough @@ -45,7 +49,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:23:32 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:24:32 | LL | let foo = Foo::Bar { field: &y }; | ^^ borrowed value does not live long enough @@ -56,7 +60,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:30:32 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:31:32 | LL | let foo = Foo::Bar { field: &y }; | ^^ borrowed value does not live long enough 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 893a96b34cf9f..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) } 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 f56d11fcff834..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,17 +1,21 @@ warning: type parameter on variant - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:19 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:10:19 | LL | let Foo::Bar::<'static>(_z) = foo; | ^^^^^^^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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:17:19 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:18:19 | LL | Foo::Bar::<'static>(_z) => {} | ^^^^^^^^^ @@ -22,7 +26,7 @@ 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 @@ -33,7 +37,7 @@ 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 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 4c972598a4b34..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::; //~ WARNING type parameter on variant + 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 951947b9402ed..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,21 +1,25 @@ -warning: type parameter on variant - --> $DIR/no-type-application-on-aliased-enum-variant.rs:11:27 +error: type parameter on variant + --> $DIR/no-type-application-on-aliased-enum-variant.rs:12:27 | LL | let _ = Option::None::; | ^^^^ | - = note: `#[warn(type_param_on_variant_ctor)]` on by default +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`.