diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2022-05-27 19:53:31 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2022-06-01 10:41:50 -0700 |
| commit | 9b2d80a197453001f9acd40020c1db6c0178c7fe (patch) | |
| tree | 876dc00b0a3a0aacea42246bf805ff2a4dd9b178 | |
| parent | f023b920b195477b65945550a2c5949ca7e7cf3e (diff) | |
| download | rust-9b2d80a197453001f9acd40020c1db6c0178c7fe.tar.gz rust-9b2d80a197453001f9acd40020c1db6c0178c7fe.zip | |
Provide more context when denying invalid type params
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/mod.rs | 169 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/fn_ctxt/checks.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0109.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0110.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/structs/struct-path-self.stderr | 32 | ||||
| -rw-r--r-- | src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr | 122 | ||||
| -rw-r--r-- | src/test/ui/type/issue-91268.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/typeck/prim-with-args.fixed | 28 | ||||
| -rw-r--r-- | src/test/ui/typeck/prim-with-args.rs | 45 | ||||
| -rw-r--r-- | src/test/ui/typeck/prim-with-args.stderr | 246 | ||||
| -rw-r--r-- | src/test/ui/usize-generic-argument-parent.stderr | 6 |
12 files changed, 564 insertions, 110 deletions
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 492e9609f96..56a4025f297 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Const, DefIdTree, EarlyBinder, Ty, TyCtxt, TypeFold use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi; use rustc_trait_selection::traits; @@ -653,7 +653,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, item_def_id, item_segment ); if tcx.generics_of(item_def_id).params.is_empty() { - self.prohibit_generics(slice::from_ref(item_segment).iter()); + self.prohibit_generics(slice::from_ref(item_segment).iter(), |_| {}); parent_substs } else { @@ -681,7 +681,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref: &hir::TraitRef<'_>, self_ty: Ty<'tcx>, ) -> ty::TraitRef<'tcx> { - self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter()); + self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); self.ast_path_to_mono_trait_ref( trait_ref.path.span, @@ -784,7 +784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let args = trait_segment.args(); let infer_args = trait_segment.infer_args; - self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter()); + self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); self.instantiate_poly_trait_ref_inner( @@ -1776,12 +1776,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir_ref_id: hir::HirId, span: Span, qself_ty: Ty<'tcx>, - qself_res: Res, + qself: &hir::Ty<'_>, assoc_segment: &hir::PathSegment<'_>, permit_variants: bool, ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> { let tcx = self.tcx(); let assoc_ident = assoc_segment.ident; + let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind { + path.res + } else { + Res::Err + }; debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident); @@ -1796,7 +1801,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(variant_def) = variant_def { if permit_variants { tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None); - self.prohibit_generics(slice::from_ref(assoc_segment).iter()); + self.prohibit_generics(slice::from_ref(assoc_segment).iter(), |err| { + err.note("enum variants can't have type parameters"); + let type_name = tcx.opt_item_name(adt_def.did()); + let the_enum = type_name.map(|n| format!("enum `{n}`")).unwrap_or_else(|| "the enum".to_string()); + let msg = format!("you might have meant to specity type parameters on {the_enum}"); + let Some(args) = assoc_segment.args else { return; }; + let args_span = assoc_segment.ident.span.shrink_to_hi().to(args.span_ext); + let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else { + err.note(&msg); + return; + }; + let (qself_sugg_span, is_self) = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind { + // If the path segment already has type params, we want to overwrite + // them. + match &path.segments[..] { + [.., segment, _] => ( + segment.ident.span.shrink_to_hi().to(segment.args.map_or( + segment.ident.span.shrink_to_hi(), + |a| a.span_ext)), + false, + ), + [segment] => ( + segment.ident.span.shrink_to_hi().to(segment.args.map_or( + segment.ident.span.shrink_to_hi(), + |a| a.span_ext)), + kw::SelfUpper == segment.ident.name, + ), + _ => unreachable!(), + } + } else { + err.note(&msg); + return; + }; + let Some(type_name) = type_name else { + err.note(&msg); + return; + }; + let suggestion = vec![ + if is_self { + // Account for people writing `Self::Variant::<Args>`, where + // `Self` is the enum. + (qself.span, format!("{type_name}{snippet}")) + } else { + (qself_sugg_span, snippet) + }, + (args_span, String::new()), + ]; + err.multipart_suggestion_verbose(&msg, suggestion, Applicability::MaybeIncorrect); + }); return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); } else { variant_resolution = Some(variant_def.def_id); @@ -2017,9 +2070,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.normalize_ty(span, tcx.mk_projection(item_def_id, item_substs)) } - pub fn prohibit_generics<'a, T: Iterator<Item = &'a hir::PathSegment<'a>> + Clone>( + pub fn prohibit_generics<'a>( &self, - segments: T, + segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone, + extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>), ) -> bool { let args = segments.clone().flat_map(|segment| segment.args().args); @@ -2078,6 +2132,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "{kind} arguments are not allowed for this type", ); err.span_label(last_span, format!("{kind} argument{s} not allowed")); + extend(&mut err); err.emit(); emitted = true; } @@ -2239,7 +2294,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Check for desugared `impl Trait`. assert!(ty::is_impl_trait_defn(tcx, did).is_none()); let item_segment = path.segments.split_last().unwrap(); - self.prohibit_generics(item_segment.1.iter()); + self.prohibit_generics(item_segment.1.iter(), |err| { + err.note("`impl Trait` types can't have type parameters"); + }); let substs = self.ast_path_substs_for_ty(span, did, item_segment.0); self.normalize_ty(span, tcx.mk_opaque(did, substs)) } @@ -2252,7 +2309,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { did, ) => { assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.split_last().unwrap().1.iter()); + self.prohibit_generics(path.segments.split_last().unwrap().1.iter(), |_| {}); self.ast_path_to_ty(span, did, path.segments.last().unwrap()) } Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => { @@ -2264,18 +2321,26 @@ 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)| { + self.prohibit_generics( + path.segments.iter().enumerate().filter_map(|(index, seg)| { if !generic_segs.contains(&index) { Some(seg) } else { None } + }), + |err| { + err.note("enum variants can't have type parameters"); }, - )); + ); let PathSeg(def_id, index) = path_segs.last().unwrap(); self.ast_path_to_ty(span, *def_id, &path.segments[*index]) } Res::Def(DefKind::TyParam, def_id) => { assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.iter()); + self.prohibit_generics(path.segments.iter(), |err| { + if let Some(span) = tcx.def_ident_span(def_id) { + let name = tcx.item_name(def_id); + err.span_note(span, &format!("type parameter `{name}` defined here")); + } + }); let def_id = def_id.expect_local(); let item_def_id = tcx.hir().ty_param_owner(def_id); @@ -2286,15 +2351,63 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Res::SelfTy { trait_: Some(_), alias_to: None } => { // `Self` in trait or type alias. assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.iter()); + self.prohibit_generics(path.segments.iter(), |err| { + if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments[..] { + err.span_suggestion_verbose( + ident.span.shrink_to_hi().to(args.span_ext), + "the `Self` type doesn't accept type parameters", + String::new(), + Applicability::MaybeIncorrect, + ); + } + }); tcx.types.self_param } Res::SelfTy { trait_: _, alias_to: Some((def_id, forbid_generic)) } => { // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.iter()); // Try to evaluate any array length constants. let ty = tcx.at(span).type_of(def_id); + let span_of_impl = tcx.span_of_impl(def_id); + // TODO: confirm that `def_id`'s type accepts type params at all before suggesting + // using that instead. + self.prohibit_generics(path.segments.iter(), |err| { + let def_id = match *ty.kind() { + ty::Adt(self_def, _) => self_def.did(), + _ => return, + }; + + let type_name = tcx.item_name(def_id); + let span_of_ty = tcx.def_ident_span(def_id); + + let msg = format!("the `Self` type is `{ty}`"); + if let (Ok(i_sp), Some(t_sp)) = (span_of_impl, span_of_ty) { + let i_sp = tcx.sess.source_map().guess_head_span(i_sp); + let mut span: MultiSpan = vec![t_sp].into(); + span.push_span_label( + i_sp, + &format!("`Self` is `{type_name}` in this `impl`"), + ); + span.push_span_label(t_sp, "`Self` corresponds to this type"); + err.span_note(span, &msg); + } else { + err.note(&msg); + } + for segment in path.segments { + if let Some(_args) = segment.args && segment.ident.name == kw::SelfUpper { + err.span_suggestion_verbose( + segment.ident.span, + format!( + "the `Self` type doesn't accept type parameters, use the \ + concrete type's name `{type_name}` instead if you want to \ + specify its type parameters" + ), + type_name.to_string(), + Applicability::MaybeIncorrect, + ); + } + } + }); // HACK(min_const_generics): Forbid generic `Self` types // here as we can't easily do that during nameres. // @@ -2334,7 +2447,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::Def(DefKind::AssocTy, def_id) => { debug_assert!(path.segments.len() >= 2); - self.prohibit_generics(path.segments[..path.segments.len() - 2].iter()); + self.prohibit_generics(path.segments[..path.segments.len() - 2].iter(), |_| {}); self.qpath_to_ty( span, opt_self_ty, @@ -2345,7 +2458,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::PrimTy(prim_ty) => { assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.iter()); + self.prohibit_generics(path.segments.iter(), |err| { + let name = prim_ty.name_str(); + for segment in path.segments { + if let Some(args) = segment.args { + err.span_suggestion_verbose( + segment.ident.span.shrink_to_hi().to(args.span_ext), + &format!("primitive type `{name}` doesn't have type parameters"), + String::new(), + Applicability::MaybeIncorrect, + ); + } + } + }); match prim_ty { hir::PrimTy::Bool => tcx.types.bool, hir::PrimTy::Char => tcx.types.char, @@ -2436,13 +2561,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!(?qself, ?segment); let ty = self.ast_ty_to_ty_inner(qself, false, true); - - let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = qself.kind { - path.res - } else { - Res::Err - }; - self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, res, segment, false) + self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false) .map(|(ty, _, _)| ty) .unwrap_or_else(|_| tcx.ty_error()) } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index ac2dc6522ad..c28c041e78d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1228,6 +1228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } }), + |_| {}, ); if let Res::Local(hid) = res { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 34cc02f180b..83afbfa54b1 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1564,13 +1564,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { QPath::TypeRelative(ref qself, ref segment) => { let ty = self.to_ty(qself); - let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind { - path.res - } else { - Res::Err - }; let result = <dyn AstConv<'_>>::associated_path_to_ty( - self, hir_id, path_span, ty, res, segment, true, + self, hir_id, path_span, ty, qself, segment, true, ); let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error()); let result = result.map(|(_, kind, def_id)| (kind, def_id)); diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr index 577e286fcc6..cb12bcd1ba4 100644 --- a/src/test/ui/error-codes/E0109.stderr +++ b/src/test/ui/error-codes/E0109.stderr @@ -3,6 +3,12 @@ error[E0109]: type arguments are not allowed for this type | LL | type X = u32<i32>; | ^^^ type argument not allowed + | +help: primitive type `u32` doesn't have type parameters + | +LL - type X = u32<i32>; +LL + type X = u32; + | error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index b0221318087..5140f72b3ce 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -3,6 +3,12 @@ error[E0109]: lifetime arguments are not allowed for this type | LL | type X = u32<'static>; | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `u32` doesn't have type parameters + | +LL - type X = u32<'static>; +LL + type X = u32; + | error: aborting due to previous error diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr index 693ed35cbc9..f8b85559db8 100644 --- a/src/test/ui/structs/struct-path-self.stderr +++ b/src/test/ui/structs/struct-path-self.stderr @@ -9,6 +9,12 @@ error[E0109]: type arguments are not allowed for this type | LL | let z = Self::<u8> {}; | ^^ type argument not allowed + | +help: the `Self` type doesn't accept type parameters + | +LL - let z = Self::<u8> {}; +LL + let z = Self {}; + | error[E0071]: expected struct, variant or union type, found type parameter `Self` --> $DIR/struct-path-self.rs:7:17 @@ -27,12 +33,38 @@ error[E0109]: type arguments are not allowed for this type | LL | let z = Self::<u8> {}; | ^^ type argument not allowed + | +note: the `Self` type is `S` + --> $DIR/struct-path-self.rs:1:8 + | +LL | struct S; + | ^ `Self` corresponds to this type +... +LL | impl Tr for S { + | ------------- `Self` is `S` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `S` instead if you want to specify its type parameters + | +LL | let z = S::<u8> {}; + | ~ error[E0109]: type arguments are not allowed for this type --> $DIR/struct-path-self.rs:30:24 | LL | let z = Self::<u8> {}; | ^^ type argument not allowed + | +note: the `Self` type is `S` + --> $DIR/struct-path-self.rs:1:8 + | +LL | struct S; + | ^ `Self` corresponds to this type +... +LL | impl S { + | ------ `Self` is `S` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `S` instead if you want to specify its type parameters + | +LL | let z = S::<u8> {}; + | ~ error: aborting due to 6 previous errors 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 115ecb01376..a0df5c416b2 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 @@ -28,6 +28,19 @@ error[E0109]: type arguments are not allowed for this type | LL | Self::<()>::TSVariant(()); | ^^ type argument not allowed + | +note: the `Self` type is `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::TSVariant(()); + | ~~~~ error[E0308]: mismatched types --> $DIR/enum-variant-generic-args.rs:17:31 @@ -53,6 +66,19 @@ error[E0109]: type arguments are not allowed for this type | LL | Self::<()>::TSVariant::<()>(()); | ^^ type argument not allowed + | +note: the `Self` type is `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::TSVariant::<()>(()); + | ~~~~ error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:20:33 @@ -77,6 +103,13 @@ error[E0109]: type arguments are not allowed for this type | LL | Self::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Self::SVariant::<()> { v: () }; +LL + Enum::<()>::SVariant { v: () }; + | error[E0308]: mismatched types --> $DIR/enum-variant-generic-args.rs:28:35 @@ -95,6 +128,19 @@ error[E0109]: type arguments are not allowed for this type | LL | Self::<()>::SVariant { v: () }; | ^^ type argument not allowed + | +note: the `Self` type is `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::SVariant { v: () }; + | ~~~~ error[E0308]: mismatched types --> $DIR/enum-variant-generic-args.rs:31:35 @@ -113,12 +159,32 @@ error[E0109]: type arguments are not allowed for this type | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed + | +note: the `Self` type is `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::SVariant::<()> { v: () }; + | ~~~~ error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:34:32 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Self::<()>::SVariant::<()> { v: () }; +LL + Enum::<()>::SVariant { v: () }; + | error[E0308]: mismatched types --> $DIR/enum-variant-generic-args.rs:34:41 @@ -143,12 +209,38 @@ error[E0109]: type arguments are not allowed for this type | LL | Self::<()>::UVariant; | ^^ type argument not allowed + | +note: the `Self` type is `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::UVariant; + | ~~~~ error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:45:16 | LL | Self::<()>::UVariant::<()>; | ^^ type argument not allowed + | +note: the `Self` type is `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::UVariant::<()>; + | ~~~~ error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:45:32 @@ -219,24 +311,47 @@ error[E0109]: type arguments are not allowed for this type | LL | Enum::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:75:23 | LL | Alias::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Alias::SVariant::<()> { v: () }; +LL + Alias::<()>::SVariant { v: () }; + | error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:77:29 | LL | Alias::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Alias::<()>::SVariant::<()> { v: () }; +LL + Alias::<()>::SVariant { v: () }; + | error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:80:28 | LL | AliasFixed::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - AliasFixed::SVariant::<()> { v: () }; +LL + AliasFixed::<()>::SVariant { v: () }; + | error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:82:5 @@ -271,6 +386,13 @@ error[E0109]: type arguments are not allowed for this type | LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - AliasFixed::<()>::SVariant::<()> { v: () }; +LL + AliasFixed::<()>::SVariant { v: () }; + | error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:90:28 diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr index 2fe6ba6248c..9e86fd3aa7d 100644 --- a/src/test/ui/type/issue-91268.stderr +++ b/src/test/ui/type/issue-91268.stderr @@ -35,6 +35,12 @@ error[E0109]: type arguments are not allowed for this type | LL | 0: u8(ţ | ^ type argument not allowed + | +help: primitive type `u8` doesn't have type parameters + | +LL - 0: u8(ţ +LL + 0: u8 + | error[E0308]: mismatched types --> $DIR/issue-91268.rs:9:5 diff --git a/src/test/ui/typeck/prim-with-args.fixed b/src/test/ui/typeck/prim-with-args.fixed new file mode 100644 index 00000000000..0fd4a0f984e --- /dev/null +++ b/src/test/ui/typeck/prim-with-args.fixed @@ -0,0 +1,28 @@ +// run-rustfix +fn main() { + +let _x: isize; //~ ERROR type arguments are not allowed for this type +let _x: i8; //~ ERROR type arguments are not allowed for this type +let _x: i16; //~ ERROR type arguments are not allowed for this type +let _x: i32; //~ ERROR type arguments are not allowed for this type +let _x: i64; //~ ERROR type arguments are not allowed for this type +let _x: usize; //~ ERROR type arguments are not allowed for this type +let _x: u8; //~ ERROR type arguments are not allowed for this type +let _x: u16; //~ ERROR type arguments are not allowed for this type +let _x: u32; //~ ERROR type arguments are not allowed for this type +let _x: u64; //~ ERROR type arguments are not allowed for this type +let _x: char; //~ ERROR type arguments are not allowed for this type + +let _x: isize; //~ ERROR lifetime arguments are not allowed for this type +let _x: i8; //~ ERROR lifetime arguments are not allowed for this type +let _x: i16; //~ ERROR lifetime arguments are not allowed for this type +let _x: i32; //~ ERROR lifetime arguments are not allowed for this type +let _x: i64; //~ ERROR lifetime arguments are not allowed for this type +let _x: usize; //~ ERROR lifetime arguments are not allowed for this type +let _x: u8; //~ ERROR lifetime arguments are not allowed for this type +let _x: u16; //~ ERROR lifetime arguments are not allowed for this type +let _x: u32; //~ ERROR lifetime arguments are not allowed for this type +let _x: u64; //~ ERROR lifetime arguments are not allowed for this type +let _x: char; //~ ERROR lifetime arguments are not allowed for this type + +} diff --git a/src/test/ui/typeck/prim-with-args.rs b/src/test/ui/typeck/prim-with-args.rs index e5beaca6abb..a21fe69dc6a 100644 --- a/src/test/ui/typeck/prim-with-args.rs +++ b/src/test/ui/typeck/prim-with-args.rs @@ -1,27 +1,28 @@ +// run-rustfix fn main() { -let x: isize<isize>; //~ ERROR type arguments are not allowed for this type -let x: i8<isize>; //~ ERROR type arguments are not allowed for this type -let x: i16<isize>; //~ ERROR type arguments are not allowed for this type -let x: i32<isize>; //~ ERROR type arguments are not allowed for this type -let x: i64<isize>; //~ ERROR type arguments are not allowed for this type -let x: usize<isize>; //~ ERROR type arguments are not allowed for this type -let x: u8<isize>; //~ ERROR type arguments are not allowed for this type -let x: u16<isize>; //~ ERROR type arguments are not allowed for this type -let x: u32<isize>; //~ ERROR type arguments are not allowed for this type -let x: u64<isize>; //~ ERROR type arguments are not allowed for this type -let x: char<isize>; //~ ERROR type arguments are not allowed for this type +let _x: isize<isize>; //~ ERROR type arguments are not allowed for this type +let _x: i8<isize>; //~ ERROR type arguments are not allowed for this type +let _x: i16<isize>; //~ ERROR type arguments are not allowed for this type +let _x: i32<isize>; //~ ERROR type arguments are not allowed for this type +let _x: i64<isize>; //~ ERROR type arguments are not allowed for this type +let _x: usize<isize>; //~ ERROR type arguments are not allowed for this type +let _x: u8<isize>; //~ ERROR type arguments are not allowed for this type +let _x: u16<isize>; //~ ERROR type arguments are not allowed for this type +let _x: u32<isize>; //~ ERROR type arguments are not allowed for this type +let _x: u64<isize>; //~ ERROR type arguments are not allowed for this type +let _x: char<isize>; //~ ERROR type arguments are not allowed for this type -let x: isize<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: i8<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: i16<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: i32<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: i64<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: usize<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: u8<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: u16<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: u32<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: u64<'static>; //~ ERROR lifetime arguments are not allowed for this type -let x: char<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: isize<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: i8<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: i16<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: i32<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: i64<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: usize<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: u8<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: u16<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: u32<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: u64<'static>; //~ ERROR lifetime arguments are not allowed for this type +let _x: char<'static>; //~ ERROR lifetime arguments are not allowed for this type } diff --git a/src/test/ui/typeck/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr index 4bde981e7f2..d7c32cf8ecf 100644 --- a/src/test/ui/typeck/prim-with-args.stderr +++ b/src/test/ui/typeck/prim-with-args.stderr @@ -1,134 +1,266 @@ error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:3:14 + --> $DIR/prim-with-args.rs:4:15 | -LL | let x: isize<isize>; - | ^^^^^ type argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:4:11 +LL | let _x: isize<isize>; + | ^^^^^ type argument not allowed | -LL | let x: i8<isize>; - | ^^^^^ type argument not allowed +help: primitive type `isize` doesn't have type parameters + | +LL - let _x: isize<isize>; +LL + let _x: isize; + | error[E0109]: type arguments are not allowed for this type --> $DIR/prim-with-args.rs:5:12 | -LL | let x: i16<isize>; +LL | let _x: i8<isize>; | ^^^^^ type argument not allowed + | +help: primitive type `i8` doesn't have type parameters + | +LL - let _x: i8<isize>; +LL + let _x: i8; + | error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:6:12 + --> $DIR/prim-with-args.rs:6:13 | -LL | let x: i32<isize>; - | ^^^^^ type argument not allowed +LL | let _x: i16<isize>; + | ^^^^^ type argument not allowed + | +help: primitive type `i16` doesn't have type parameters + | +LL - let _x: i16<isize>; +LL + let _x: i16; + | error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:7:12 + --> $DIR/prim-with-args.rs:7:13 | -LL | let x: i64<isize>; - | ^^^^^ type argument not allowed +LL | let _x: i32<isize>; + | ^^^^^ type argument not allowed + | +help: primitive type `i32` doesn't have type parameters + | +LL - let _x: i32<isize>; +LL + let _x: i32; + | error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:8:14 + --> $DIR/prim-with-args.rs:8:13 | -LL | let x: usize<isize>; - | ^^^^^ type argument not allowed +LL | let _x: i64<isize>; + | ^^^^^ type argument not allowed + | +help: primitive type `i64` doesn't have type parameters + | +LL - let _x: i64<isize>; +LL + let _x: i64; + | error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:9:11 + --> $DIR/prim-with-args.rs:9:15 + | +LL | let _x: usize<isize>; + | ^^^^^ type argument not allowed | -LL | let x: u8<isize>; - | ^^^^^ type argument not allowed +help: primitive type `usize` doesn't have type parameters + | +LL - let _x: usize<isize>; +LL + let _x: usize; + | error[E0109]: type arguments are not allowed for this type --> $DIR/prim-with-args.rs:10:12 | -LL | let x: u16<isize>; +LL | let _x: u8<isize>; | ^^^^^ type argument not allowed + | +help: primitive type `u8` doesn't have type parameters + | +LL - let _x: u8<isize>; +LL + let _x: u8; + | error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:11:12 + --> $DIR/prim-with-args.rs:11:13 | -LL | let x: u32<isize>; - | ^^^^^ type argument not allowed +LL | let _x: u16<isize>; + | ^^^^^ type argument not allowed + | +help: primitive type `u16` doesn't have type parameters + | +LL - let _x: u16<isize>; +LL + let _x: u16; + | error[E0109]: type arguments are not allowed for this type - --> $DIR/prim-with-args.rs:12:12 + --> $DIR/prim-with-args.rs:12:13 | -LL | let x: u64<isize>; - | ^^^^^ type argument not allowed +LL | let _x: u32<isize>; + | ^^^^^ type argument not allowed + | +help: primitive type `u32` doesn't have type parameters + | +LL - let _x: u32<isize>; +LL + let _x: u32; + | error[E0109]: type arguments are not allowed for this type --> $DIR/prim-with-args.rs:13:13 | -LL | let x: char<isize>; +LL | let _x: u64<isize>; | ^^^^^ type argument not allowed + | +help: primitive type `u64` doesn't have type parameters + | +LL - let _x: u64<isize>; +LL + let _x: u64; + | -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:15:14 +error[E0109]: type arguments are not allowed for this type + --> $DIR/prim-with-args.rs:14:14 | -LL | let x: isize<'static>; - | ^^^^^^^ lifetime argument not allowed +LL | let _x: char<isize>; + | ^^^^^ type argument not allowed + | +help: primitive type `char` doesn't have type parameters + | +LL - let _x: char<isize>; +LL + let _x: char; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:16:11 + --> $DIR/prim-with-args.rs:16:15 + | +LL | let _x: isize<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `isize` doesn't have type parameters | -LL | let x: i8<'static>; - | ^^^^^^^ lifetime argument not allowed +LL - let _x: isize<'static>; +LL + let _x: isize; + | error[E0109]: lifetime arguments are not allowed for this type --> $DIR/prim-with-args.rs:17:12 | -LL | let x: i16<'static>; +LL | let _x: i8<'static>; | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `i8` doesn't have type parameters + | +LL - let _x: i8<'static>; +LL + let _x: i8; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:18:12 + --> $DIR/prim-with-args.rs:18:13 | -LL | let x: i32<'static>; - | ^^^^^^^ lifetime argument not allowed +LL | let _x: i16<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `i16` doesn't have type parameters + | +LL - let _x: i16<'static>; +LL + let _x: i16; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:19:12 + --> $DIR/prim-with-args.rs:19:13 | -LL | let x: i64<'static>; - | ^^^^^^^ lifetime argument not allowed +LL | let _x: i32<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `i32` doesn't have type parameters + | +LL - let _x: i32<'static>; +LL + let _x: i32; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:20:14 + --> $DIR/prim-with-args.rs:20:13 | -LL | let x: usize<'static>; - | ^^^^^^^ lifetime argument not allowed +LL | let _x: i64<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `i64` doesn't have type parameters + | +LL - let _x: i64<'static>; +LL + let _x: i64; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:21:11 + --> $DIR/prim-with-args.rs:21:15 + | +LL | let _x: usize<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `usize` doesn't have type parameters | -LL | let x: u8<'static>; - | ^^^^^^^ lifetime argument not allowed +LL - let _x: usize<'static>; +LL + let _x: usize; + | error[E0109]: lifetime arguments are not allowed for this type --> $DIR/prim-with-args.rs:22:12 | -LL | let x: u16<'static>; +LL | let _x: u8<'static>; | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `u8` doesn't have type parameters + | +LL - let _x: u8<'static>; +LL + let _x: u8; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:23:12 + --> $DIR/prim-with-args.rs:23:13 | -LL | let x: u32<'static>; - | ^^^^^^^ lifetime argument not allowed +LL | let _x: u16<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `u16` doesn't have type parameters + | +LL - let _x: u16<'static>; +LL + let _x: u16; + | error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/prim-with-args.rs:24:12 + --> $DIR/prim-with-args.rs:24:13 | -LL | let x: u64<'static>; - | ^^^^^^^ lifetime argument not allowed +LL | let _x: u32<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `u32` doesn't have type parameters + | +LL - let _x: u32<'static>; +LL + let _x: u32; + | error[E0109]: lifetime arguments are not allowed for this type --> $DIR/prim-with-args.rs:25:13 | -LL | let x: char<'static>; +LL | let _x: u64<'static>; | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `u64` doesn't have type parameters + | +LL - let _x: u64<'static>; +LL + let _x: u64; + | + +error[E0109]: lifetime arguments are not allowed for this type + --> $DIR/prim-with-args.rs:26:14 + | +LL | let _x: char<'static>; + | ^^^^^^^ lifetime argument not allowed + | +help: primitive type `char` doesn't have type parameters + | +LL - let _x: char<'static>; +LL + let _x: char; + | error: aborting due to 22 previous errors diff --git a/src/test/ui/usize-generic-argument-parent.stderr b/src/test/ui/usize-generic-argument-parent.stderr index f1eae3b5008..98505d7bbe8 100644 --- a/src/test/ui/usize-generic-argument-parent.stderr +++ b/src/test/ui/usize-generic-argument-parent.stderr @@ -3,6 +3,12 @@ error[E0109]: const arguments are not allowed for this type | LL | let x: usize<foo>; | ^^^ const argument not allowed + | +help: primitive type `usize` doesn't have type parameters + | +LL - let x: usize<foo>; +LL + let x: usize; + | error: aborting due to previous error |
