From f023b920b195477b65945550a2c5949ca7e7cf3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 27 May 2022 15:20:21 -0700 Subject: [PATCH 01/17] Rework `prohibit_generics` --- compiler/rustc_typeck/src/astconv/mod.rs | 140 ++++++++++++----------- 1 file changed, 75 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 96d083bb94f3c..492e9609f96ff 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -16,7 +16,7 @@ use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ - struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, + struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -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)); + 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); + 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); + 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( @@ -1796,7 +1796,7 @@ 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)); + self.prohibit_generics(slice::from_ref(assoc_segment).iter()); return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); } else { variant_resolution = Some(variant_def.def_id); @@ -2017,69 +2017,79 @@ 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: IntoIterator>>( + pub fn prohibit_generics<'a, T: Iterator> + Clone>( &self, segments: T, ) -> bool { - let mut has_err = false; - for segment in segments { - let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false); - for arg in segment.args().args { - let (span, kind) = match arg { - hir::GenericArg::Lifetime(lt) => { - if err_for_lt { - continue; - } - err_for_lt = true; - has_err = true; - (lt.span, "lifetime") - } - hir::GenericArg::Type(ty) => { - if err_for_ty { - continue; - } - err_for_ty = true; - has_err = true; - (ty.span, "type") - } - hir::GenericArg::Const(ct) => { - if err_for_ct { - continue; - } - err_for_ct = true; - has_err = true; - (ct.span, "const") - } - hir::GenericArg::Infer(inf) => { - if err_for_ty { - continue; - } - has_err = true; - err_for_ty = true; - (inf.span, "generic") - } - }; - let mut err = struct_span_err!( - self.tcx().sess, - span, - E0109, - "{} arguments are not allowed for this type", - kind, - ); - err.span_label(span, format!("{} argument not allowed", kind)); - err.emit(); - if err_for_lt && err_for_ty && err_for_ct { - break; - } + let args = segments.clone().flat_map(|segment| segment.args().args); + + let (lt, ty, ct, inf) = + args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg { + hir::GenericArg::Lifetime(_) => (true, ty, ct, inf), + hir::GenericArg::Type(_) => (lt, true, ct, inf), + hir::GenericArg::Const(_) => (lt, ty, true, inf), + hir::GenericArg::Infer(_) => (lt, ty, ct, true), + }); + let mut emitted = false; + if lt || ty || ct || inf { + let arg_spans: Vec = args + .map(|arg| match arg { + hir::GenericArg::Lifetime(lt) => lt.span, + hir::GenericArg::Type(ty) => ty.span, + hir::GenericArg::Const(ct) => ct.span, + hir::GenericArg::Infer(inf) => inf.span, + }) + .collect(); + + let mut types = Vec::with_capacity(4); + if lt { + types.push("lifetime"); + } + if ty { + types.push("type"); + } + if ct { + types.push("const"); } + if inf { + types.push("generic"); + } + let (kind, s) = match types[..] { + [.., _, last] => ( + format!( + "{} and `{last}`", + types[..types.len() - 1] + .iter() + .map(|&x| x) + .intersperse(", ") + .collect::() + ), + "s", + ), + [only] => (format!("{only}"), ""), + [] => unreachable!(), + }; + let last_span = *arg_spans.last().unwrap(); + let span: MultiSpan = arg_spans.into(); + let mut err = struct_span_err!( + self.tcx().sess, + span, + E0109, + "{kind} arguments are not allowed for this type", + ); + err.span_label(last_span, format!("{kind} argument{s} not allowed")); + err.emit(); + emitted = true; + } + for segment in segments { // Only emit the first error to avoid overloading the user with error messages. if let [binding, ..] = segment.args().bindings { - has_err = true; Self::prohibit_assoc_ty_binding(self.tcx(), binding.span); + return true; } } - has_err + emitted } // FIXME(eddyb, varkor) handle type paths here too, not just value ones. @@ -2229,7 +2239,7 @@ 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); + self.prohibit_generics(item_segment.1.iter()); let substs = self.ast_path_substs_for_ty(span, did, item_segment.0); self.normalize_ty(span, tcx.mk_opaque(did, substs)) } @@ -2242,7 +2252,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { did, ) => { assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.split_last().unwrap().1); + 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 => { @@ -2265,7 +2275,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::Def(DefKind::TyParam, def_id) => { assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments); + self.prohibit_generics(path.segments.iter()); let def_id = def_id.expect_local(); let item_def_id = tcx.hir().ty_param_owner(def_id); @@ -2276,13 +2286,13 @@ 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); + self.prohibit_generics(path.segments.iter()); 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); + self.prohibit_generics(path.segments.iter()); // Try to evaluate any array length constants. let ty = tcx.at(span).type_of(def_id); // HACK(min_const_generics): Forbid generic `Self` types @@ -2324,7 +2334,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]); + self.prohibit_generics(path.segments[..path.segments.len() - 2].iter()); self.qpath_to_ty( span, opt_self_ty, @@ -2335,7 +2345,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::PrimTy(prim_ty) => { assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments); + self.prohibit_generics(path.segments.iter()); match prim_ty { hir::PrimTy::Bool => tcx.types.bool, hir::PrimTy::Char => tcx.types.char, From 9b2d80a197453001f9acd40020c1db6c0178c7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 27 May 2022 19:53:31 -0700 Subject: [PATCH 02/17] Provide more context when denying invalid type params --- compiler/rustc_typeck/src/astconv/mod.rs | 169 ++++++++++-- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 1 + .../rustc_typeck/src/check/fn_ctxt/checks.rs | 7 +- src/test/ui/error-codes/E0109.stderr | 6 + src/test/ui/error-codes/E0110.stderr | 6 + src/test/ui/structs/struct-path-self.stderr | 32 +++ .../enum-variant-generic-args.stderr | 122 +++++++++ src/test/ui/type/issue-91268.stderr | 6 + src/test/ui/typeck/prim-with-args.fixed | 28 ++ src/test/ui/typeck/prim-with-args.rs | 45 ++-- src/test/ui/typeck/prim-with-args.stderr | 246 ++++++++++++++---- .../ui/usize-generic-argument-parent.stderr | 6 + 12 files changed, 564 insertions(+), 110 deletions(-) create mode 100644 src/test/ui/typeck/prim-with-args.fixed diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 492e9609f96ff..56a4025f2972a 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::`, 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> + Clone>( + pub fn prohibit_generics<'a>( &self, - segments: T, + segments: impl Iterator> + 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 ac2dc6522adc2..c28c041e78dff 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 34cc02f180b40..83afbfa54b1dd 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 = >::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 577e286fcc6ce..cb12bcd1ba402 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; | ^^^ type argument not allowed + | +help: primitive type `u32` doesn't have type parameters + | +LL - type X = u32; +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 b022131808738..5140f72b3ce21 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 693ed35cbc9c6..f8b85559db844 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:: {}; | ^^ type argument not allowed + | +help: the `Self` type doesn't accept type parameters + | +LL - let z = Self:: {}; +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:: {}; | ^^ 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:: {}; + | ~ error[E0109]: type arguments are not allowed for this type --> $DIR/struct-path-self.rs:30:24 | LL | let z = Self:: {}; | ^^ 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:: {}; + | ~ 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 115ecb013766d..a0df5c416b26b 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` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl Enum { + | --------------- `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` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl Enum { + | --------------- `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` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl Enum { + | --------------- `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` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl Enum { + | --------------- `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` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl Enum { + | --------------- `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` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl Enum { + | --------------- `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 2fe6ba6248c8d..9e86fd3aa7d6d 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 0000000000000..0fd4a0f984e1e --- /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 e5beaca6abb8c..a21fe69dc6a87 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; //~ 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 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<'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 4bde981e7f2d4..d7c32cf8ecf40 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; - | ^^^^^ 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; + | ^^^^^ type argument not allowed | -LL | let x: i8; - | ^^^^^ type argument not allowed +help: primitive type `isize` doesn't have type parameters + | +LL - let _x: 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; +LL | let _x: i8; | ^^^^^ type argument not allowed + | +help: primitive type `i8` doesn't have type parameters + | +LL - let _x: i8; +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; - | ^^^^^ type argument not allowed +LL | let _x: i16; + | ^^^^^ type argument not allowed + | +help: primitive type `i16` doesn't have type parameters + | +LL - let _x: i16; +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; - | ^^^^^ type argument not allowed +LL | let _x: i32; + | ^^^^^ type argument not allowed + | +help: primitive type `i32` doesn't have type parameters + | +LL - let _x: i32; +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; - | ^^^^^ type argument not allowed +LL | let _x: i64; + | ^^^^^ type argument not allowed + | +help: primitive type `i64` doesn't have type parameters + | +LL - let _x: i64; +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; + | ^^^^^ type argument not allowed | -LL | let x: u8; - | ^^^^^ type argument not allowed +help: primitive type `usize` doesn't have type parameters + | +LL - let _x: usize; +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; +LL | let _x: u8; | ^^^^^ type argument not allowed + | +help: primitive type `u8` doesn't have type parameters + | +LL - let _x: u8; +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; - | ^^^^^ type argument not allowed +LL | let _x: u16; + | ^^^^^ type argument not allowed + | +help: primitive type `u16` doesn't have type parameters + | +LL - let _x: u16; +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; - | ^^^^^ type argument not allowed +LL | let _x: u32; + | ^^^^^ type argument not allowed + | +help: primitive type `u32` doesn't have type parameters + | +LL - let _x: u32; +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; +LL | let _x: u64; | ^^^^^ type argument not allowed + | +help: primitive type `u64` doesn't have type parameters + | +LL - let _x: u64; +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; + | ^^^^^ type argument not allowed + | +help: primitive type `char` doesn't have type parameters + | +LL - let _x: char; +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 f1eae3b500840..98505d7bbe8b0 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; | ^^^ const argument not allowed + | +help: primitive type `usize` doesn't have type parameters + | +LL - let x: usize; +LL + let x: usize; + | error: aborting due to previous error From 532671b8eee37199ae9e41d377a82a910c6e25b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 31 May 2022 12:53:52 -0700 Subject: [PATCH 03/17] More accurately handle suggestions * Confirm the path segment being modified is an `enum` * Check whether type has type param before suggesting changing `Self` * Wording changes * Add clarifying comments * Suggest removing args from `Self` if the type doesn't have type params --- compiler/rustc_typeck/src/astconv/mod.rs | 110 +++++++++++++----- src/test/ui/structs/struct-path-self.stderr | 26 +++-- .../enum-variant-generic-args.stderr | 24 ++-- 3 files changed, 106 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 56a4025f2972a..4555e31016f91 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1803,52 +1803,84 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None); 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 type_name = tcx.item_name(adt_def.did()); + let msg = format!( + "you might have meant to specity type parameters on enum \ + `{type_name}`" + ); let Some(args) = assoc_segment.args else { return; }; + // Get the span of the generics args *including* the leading `::`. let args_span = assoc_segment.ident.span.shrink_to_hi().to(args.span_ext); + if tcx.generics_of(adt_def.did()).count() == 0 { + // FIXME(estebank): we could also verify that the arguments being + // work for the `enum`, instead of just looking if it takes *any*. + err.span_suggestion_verbose( + args_span, + &format!("{type_name} doesn't have type parameters"), + String::new(), + Applicability::MachineApplicable, + ); + return; + } 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 { + 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(), + // `segment` is the previous to last element on the path, + // which would normally be the `enum` itself, while the last + // `_` `PathSegment` corresponds to the variant. + [.., hir::PathSegment { + ident, + args, + res: Some(Res::Def(DefKind::Enum, _)), + .. + }, _] => ( + // We need to include the `::` in `Type::Variant::` + // to point the span to `::`, not just ``. + ident.span.shrink_to_hi().to(args.map_or( + ident.span.shrink_to_hi(), |a| a.span_ext)), false, ), [segment] => ( + // We need to include the `::` in `Type::Variant::` + // to point the span to `::`, not just ``. 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!(), + _ => { + err.note(&msg); + return; + } } } 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::`, where - // `Self` is the enum. + // `Self` is the enum, and suggest replacing `Self` with the + // appropriate type: `Type::::Variant`. (qself.span, format!("{type_name}{snippet}")) } else { (qself_sugg_span, snippet) }, (args_span, String::new()), ]; - err.multipart_suggestion_verbose(&msg, suggestion, Applicability::MaybeIncorrect); + err.multipart_suggestion_verbose( + &msg, + suggestion, + Applicability::MaybeIncorrect, + ); }); return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); } else { @@ -2369,8 +2401,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // 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(), @@ -2379,32 +2409,52 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let type_name = tcx.item_name(def_id); let span_of_ty = tcx.def_ident_span(def_id); + let generics = tcx.generics_of(def_id).count(); - let msg = format!("the `Self` type is `{ty}`"); + let msg = format!("`Self` is of type `{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`"), + &format!("`Self` is or type `{type_name}` in this `impl`"), + ); + let mut postfix = ""; + if generics == 0 { + postfix = ", which doesn't have type parameters"; + } + span.push_span_label( + t_sp, + &format!("`Self` corresponds to this type{postfix}"), ); - 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, - ); + if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper { + if generics == 0 { + // FIXME(estebank): we could also verify that the arguments being + // work for the `enum`, instead of just looking if it takes *any*. + err.span_suggestion_verbose( + segment.ident.span.shrink_to_hi().to(args.span_ext), + "the `Self` type doesn't accept type parameters", + String::new(), + Applicability::MachineApplicable, + ); + return; + } else { + 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, + ); + } } } }); diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr index f8b85559db844..bf9fe72d71842 100644 --- a/src/test/ui/structs/struct-path-self.stderr +++ b/src/test/ui/structs/struct-path-self.stderr @@ -34,18 +34,19 @@ error[E0109]: type arguments are not allowed for this type LL | let z = Self:: {}; | ^^ type argument not allowed | -note: the `Self` type is `S` +note: `Self` is of type `S` --> $DIR/struct-path-self.rs:1:8 | LL | struct S; - | ^ `Self` corresponds to this type + | ^ `Self` corresponds to this type, which doesn't have type parameters ... 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 + | ------------- `Self` is or type `S` in this `impl` +help: the `Self` type doesn't accept type parameters | -LL | let z = S:: {}; - | ~ +LL - let z = Self:: {}; +LL + let z = Self {}; + | error[E0109]: type arguments are not allowed for this type --> $DIR/struct-path-self.rs:30:24 @@ -53,18 +54,19 @@ error[E0109]: type arguments are not allowed for this type LL | let z = Self:: {}; | ^^ type argument not allowed | -note: the `Self` type is `S` +note: `Self` is of type `S` --> $DIR/struct-path-self.rs:1:8 | LL | struct S; - | ^ `Self` corresponds to this type + | ^ `Self` corresponds to this type, which doesn't have type parameters ... 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 + | ------ `Self` is or type `S` in this `impl` +help: the `Self` type doesn't accept type parameters | -LL | let z = S:: {}; - | ~ +LL - let z = Self:: {}; +LL + let z = Self {}; + | 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 a0df5c416b26b..98c164ff4180e 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 @@ -29,14 +29,14 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::TSVariant(()); | ^^ type argument not allowed | -note: the `Self` type is `Enum` +note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 | LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is `Enum` in this `impl` + | --------------- `Self` is or type `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(()); @@ -67,14 +67,14 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::TSVariant::<()>(()); | ^^ type argument not allowed | -note: the `Self` type is `Enum` +note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 | LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is `Enum` in this `impl` + | --------------- `Self` is or type `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::<()>(()); @@ -129,14 +129,14 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::SVariant { v: () }; | ^^ type argument not allowed | -note: the `Self` type is `Enum` +note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 | LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is `Enum` in this `impl` + | --------------- `Self` is or type `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: () }; @@ -160,14 +160,14 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed | -note: the `Self` type is `Enum` +note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 | LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is `Enum` in this `impl` + | --------------- `Self` is or type `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: () }; @@ -210,14 +210,14 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::UVariant; | ^^ type argument not allowed | -note: the `Self` type is `Enum` +note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 | LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is `Enum` in this `impl` + | --------------- `Self` is or type `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; @@ -229,14 +229,14 @@ error[E0109]: type arguments are not allowed for this type LL | Self::<()>::UVariant::<()>; | ^^ type argument not allowed | -note: the `Self` type is `Enum` +note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 | LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is `Enum` in this `impl` + | --------------- `Self` is or type `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::<()>; From 3d60691996af1cc19723f06f180e0bc8d9b750ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 31 May 2022 14:20:15 -0700 Subject: [PATCH 04/17] Fix test --- src/test/ui/derives/issue-97343.stderr | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/ui/derives/issue-97343.stderr b/src/test/ui/derives/issue-97343.stderr index eedd54f1e9f0c..4679ef2cc7bf5 100644 --- a/src/test/ui/derives/issue-97343.stderr +++ b/src/test/ui/derives/issue-97343.stderr @@ -6,6 +6,11 @@ LL | #[derive(Debug)] LL | pub struct Irrelevant { | ^^^^^^^^^^ type argument not allowed | +note: type parameter `Irrelevant` defined here + --> $DIR/issue-97343.rs:4:23 + | +LL | pub struct Irrelevant { + | ^^^^^^^^^^ = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error From 196a30ebff0156240b3297f9859fb57fe725c081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 1 Jun 2022 13:04:35 -0700 Subject: [PATCH 05/17] Fix typo --- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- src/test/ui/structs/struct-path-self.stderr | 4 ++-- .../enum-variant-generic-args.stderr | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 4555e31016f91..7efec3f51f7a8 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2417,7 +2417,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut span: MultiSpan = vec![t_sp].into(); span.push_span_label( i_sp, - &format!("`Self` is or type `{type_name}` in this `impl`"), + &format!("`Self` is on type `{type_name}` in this `impl`"), ); let mut postfix = ""; if generics == 0 { diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr index bf9fe72d71842..37384e56bc9ef 100644 --- a/src/test/ui/structs/struct-path-self.stderr +++ b/src/test/ui/structs/struct-path-self.stderr @@ -41,7 +41,7 @@ LL | struct S; | ^ `Self` corresponds to this type, which doesn't have type parameters ... LL | impl Tr for S { - | ------------- `Self` is or type `S` in this `impl` + | ------------- `Self` is on type `S` in this `impl` help: the `Self` type doesn't accept type parameters | LL - let z = Self:: {}; @@ -61,7 +61,7 @@ LL | struct S; | ^ `Self` corresponds to this type, which doesn't have type parameters ... LL | impl S { - | ------ `Self` is or type `S` in this `impl` + | ------ `Self` is on type `S` in this `impl` help: the `Self` type doesn't accept type parameters | LL - let z = Self:: {}; 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 98c164ff4180e..b1b0ec99999c6 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 @@ -36,7 +36,7 @@ LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is or type `Enum` in this `impl` + | --------------- `Self` is on type `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(()); @@ -74,7 +74,7 @@ LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is or type `Enum` in this `impl` + | --------------- `Self` is on type `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::<()>(()); @@ -136,7 +136,7 @@ LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is or type `Enum` in this `impl` + | --------------- `Self` is on type `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: () }; @@ -167,7 +167,7 @@ LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is or type `Enum` in this `impl` + | --------------- `Self` is on type `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: () }; @@ -217,7 +217,7 @@ LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is or type `Enum` in this `impl` + | --------------- `Self` is on type `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; @@ -236,7 +236,7 @@ LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^ `Self` corresponds to this type ... LL | impl Enum { - | --------------- `Self` is or type `Enum` in this `impl` + | --------------- `Self` is on type `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::<()>; From ad63f907e987673fc99dce3e4d1437720705f5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 1 Jun 2022 16:55:30 -0700 Subject: [PATCH 06/17] Make output more specific --- compiler/rustc_typeck/src/astconv/mod.rs | 47 ++++- src/test/ui/derives/issue-97343.rs | 2 +- src/test/ui/derives/issue-97343.stderr | 7 +- src/test/ui/error-codes/E0109.stderr | 6 +- src/test/ui/error-codes/E0110.stderr | 6 +- src/test/ui/issues/issue-22706.rs | 2 +- src/test/ui/issues/issue-22706.stderr | 6 +- src/test/ui/issues/issue-57924.rs | 2 +- src/test/ui/issues/issue-57924.stderr | 6 +- src/test/ui/issues/issue-60989.rs | 4 +- src/test/ui/issues/issue-60989.stderr | 12 +- src/test/ui/mod-subitem-as-enum-variant.rs | 2 +- .../ui/mod-subitem-as-enum-variant.stderr | 6 +- .../ui/structs/struct-path-associated-type.rs | 4 +- .../struct-path-associated-type.stderr | 12 +- src/test/ui/structs/struct-path-self.rs | 6 +- src/test/ui/structs/struct-path-self.stderr | 18 +- .../enum-variant-generic-args.rs | 54 +++--- .../enum-variant-generic-args.stderr | 162 ++++++++++++------ ...ype-application-on-aliased-enum-variant.rs | 2 +- ...application-on-aliased-enum-variant.stderr | 6 +- src/test/ui/type/issue-91268.rs | 2 +- src/test/ui/type/issue-91268.stderr | 6 +- src/test/ui/typeck/prim-with-args.fixed | 44 ++--- src/test/ui/typeck/prim-with-args.rs | 44 ++--- src/test/ui/typeck/prim-with-args.stderr | 132 +++++++++----- src/test/ui/usize-generic-argument-parent.rs | 2 +- .../ui/usize-generic-argument-parent.stderr | 6 +- 28 files changed, 391 insertions(+), 217 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 7efec3f51f7a8..405acfc186cf4 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2108,6 +2108,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>), ) -> bool { let args = segments.clone().flat_map(|segment| segment.args().args); + let types_and_spans: Vec<_> = segments + .clone() + .flat_map(|segment| { + segment.res.and_then(|res| { + if segment.args().args.is_empty() { + None + } else { + let mut desc = res.descr(); + if desc == "unresolved item" { + desc = "this type"; + }; + + let name = match res { + Res::PrimTy(ty) => Some(ty.name()), + Res::Def(_, def_id) => self.tcx().opt_item_name(def_id), + _ => None, + }; + Some(( + match name { + Some(ty) => format!("{desc} `{ty}`"), + None => desc.to_string(), + }, + segment.ident.span, + )) + } + }) + }) + .collect(); + let this_type = match &types_and_spans[..] { + [.., _, (last, _)] => format!( + "{} and {last}", + types_and_spans[..types_and_spans.len() - 1] + .iter() + .map(|(x, _)| x.as_str()) + .intersperse(&", ") + .collect::() + ), + [(only, _)] => only.to_string(), + [] => "this type".to_string(), + }; let (lt, ty, ct, inf) = args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg { @@ -2143,7 +2183,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let (kind, s) = match types[..] { [.., _, last] => ( format!( - "{} and `{last}`", + "{} and {last}", types[..types.len() - 1] .iter() .map(|&x| x) @@ -2161,9 +2201,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.tcx().sess, span, E0109, - "{kind} arguments are not allowed for this type", + "{kind} arguments are not allowed on {this_type}", ); err.span_label(last_span, format!("{kind} argument{s} not allowed")); + for (_, span) in types_and_spans { + err.span_label(span, "not allowed on this"); + } extend(&mut err); err.emit(); emitted = true; diff --git a/src/test/ui/derives/issue-97343.rs b/src/test/ui/derives/issue-97343.rs index adec6c7a5c5a3..6f0e4d55aeb04 100644 --- a/src/test/ui/derives/issue-97343.rs +++ b/src/test/ui/derives/issue-97343.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; #[derive(Debug)] -pub struct Irrelevant { //~ ERROR type arguments are not allowed for this type +pub struct Irrelevant { //~ ERROR type arguments are not allowed on type parameter irrelevant: Irrelevant, } diff --git a/src/test/ui/derives/issue-97343.stderr b/src/test/ui/derives/issue-97343.stderr index 4679ef2cc7bf5..ac797a8f50152 100644 --- a/src/test/ui/derives/issue-97343.stderr +++ b/src/test/ui/derives/issue-97343.stderr @@ -1,8 +1,11 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on type parameter `Irrelevant` --> $DIR/issue-97343.rs:4:23 | LL | #[derive(Debug)] - | ----- in this derive macro expansion + | ----- + | | + | not allowed on this + | in this derive macro expansion LL | pub struct Irrelevant { | ^^^^^^^^^^ type argument not allowed | diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr index cb12bcd1ba402..e91c74151b3b3 100644 --- a/src/test/ui/error-codes/E0109.stderr +++ b/src/test/ui/error-codes/E0109.stderr @@ -1,8 +1,10 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/E0109.rs:1:14 | LL | type X = u32; - | ^^^ type argument not allowed + | --- ^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `u32` doesn't have type parameters | diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index 5140f72b3ce21..4425d87e2b0c8 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -1,8 +1,10 @@ -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/E0110.rs:1:14 | LL | type X = u32<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `u32` doesn't have type parameters | diff --git a/src/test/ui/issues/issue-22706.rs b/src/test/ui/issues/issue-22706.rs index 28e8a72280481..bb8a58d3d2ecc 100644 --- a/src/test/ui/issues/issue-22706.rs +++ b/src/test/ui/issues/issue-22706.rs @@ -1,3 +1,3 @@ fn is_copy::Copy>() {} -//~^ ERROR type arguments are not allowed for this type [E0109] +//~^ ERROR type arguments are not allowed on module `marker` [E0109] fn main() {} diff --git a/src/test/ui/issues/issue-22706.stderr b/src/test/ui/issues/issue-22706.stderr index c5929397f6501..66911f081d76c 100644 --- a/src/test/ui/issues/issue-22706.stderr +++ b/src/test/ui/issues/issue-22706.stderr @@ -1,8 +1,10 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on module `marker` --> $DIR/issue-22706.rs:1:29 | LL | fn is_copy::Copy>() {} - | ^^^ type argument not allowed + | ------ ^^^ type argument not allowed + | | + | not allowed on this error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57924.rs b/src/test/ui/issues/issue-57924.rs index dc2942225e3de..8846912a8ff79 100644 --- a/src/test/ui/issues/issue-57924.rs +++ b/src/test/ui/issues/issue-57924.rs @@ -3,7 +3,7 @@ pub struct Gcm(E); impl Gcm { pub fn crash(e: E) -> Self { Self::(e) - //~^ ERROR type arguments are not allowed for this type + //~^ ERROR type arguments are not allowed on self constructor } } diff --git a/src/test/ui/issues/issue-57924.stderr b/src/test/ui/issues/issue-57924.stderr index 2f184b1aae171..211b0dde48c2e 100644 --- a/src/test/ui/issues/issue-57924.stderr +++ b/src/test/ui/issues/issue-57924.stderr @@ -1,8 +1,10 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self constructor --> $DIR/issue-57924.rs:5:16 | LL | Self::(e) - | ^ type argument not allowed + | ---- ^ type argument not allowed + | | + | not allowed on this error: aborting due to previous error diff --git a/src/test/ui/issues/issue-60989.rs b/src/test/ui/issues/issue-60989.rs index 6dae1e1347b7a..29db3fdb47104 100644 --- a/src/test/ui/issues/issue-60989.rs +++ b/src/test/ui/issues/issue-60989.rs @@ -10,9 +10,9 @@ impl From for B { fn main() { let c1 = (); c1::<()>; - //~^ ERROR type arguments are not allowed for this type + //~^ ERROR type arguments are not allowed on local variable let c1 = A {}; c1::>; - //~^ ERROR type arguments are not allowed for this type + //~^ ERROR type arguments are not allowed on local variable } diff --git a/src/test/ui/issues/issue-60989.stderr b/src/test/ui/issues/issue-60989.stderr index 5d2d9e83c9b9c..9076f4f9385ba 100644 --- a/src/test/ui/issues/issue-60989.stderr +++ b/src/test/ui/issues/issue-60989.stderr @@ -1,14 +1,18 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on local variable --> $DIR/issue-60989.rs:12:10 | LL | c1::<()>; - | ^^ type argument not allowed + | -- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on local variable --> $DIR/issue-60989.rs:16:10 | LL | c1::>; - | ^^^^^^^^^^^ type argument not allowed + | -- ^^^^^^^^^^^ type argument not allowed + | | + | not allowed on this error: aborting due to 2 previous errors diff --git a/src/test/ui/mod-subitem-as-enum-variant.rs b/src/test/ui/mod-subitem-as-enum-variant.rs index 9328d1a9045e5..959024c46f4ff 100644 --- a/src/test/ui/mod-subitem-as-enum-variant.rs +++ b/src/test/ui/mod-subitem-as-enum-variant.rs @@ -5,5 +5,5 @@ mod Mod { fn main() { Mod::FakeVariant::(0); Mod::::FakeVariant(0); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on module `Mod` [E0109] } diff --git a/src/test/ui/mod-subitem-as-enum-variant.stderr b/src/test/ui/mod-subitem-as-enum-variant.stderr index d6815c91e5e9e..15da1d155a337 100644 --- a/src/test/ui/mod-subitem-as-enum-variant.stderr +++ b/src/test/ui/mod-subitem-as-enum-variant.stderr @@ -1,8 +1,10 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on module `Mod` --> $DIR/mod-subitem-as-enum-variant.rs:7:11 | LL | Mod::::FakeVariant(0); - | ^^^ type argument not allowed + | --- ^^^ type argument not allowed + | | + | not allowed on this error: aborting due to previous error diff --git a/src/test/ui/structs/struct-path-associated-type.rs b/src/test/ui/structs/struct-path-associated-type.rs index e44a203b7832a..f88572f8419c0 100644 --- a/src/test/ui/structs/struct-path-associated-type.rs +++ b/src/test/ui/structs/struct-path-associated-type.rs @@ -13,7 +13,7 @@ fn f() { //~^ ERROR expected struct, variant or union type, found associated type let z = T::A:: {}; //~^ ERROR expected struct, variant or union type, found associated type - //~| ERROR type arguments are not allowed for this type + //~| ERROR type arguments are not allowed on this type match S { T::A {} => {} //~^ ERROR expected struct, variant or union type, found associated type @@ -22,7 +22,7 @@ fn f() { fn g>() { let s = T::A {}; // OK - let z = T::A:: {}; //~ ERROR type arguments are not allowed for this type + let z = T::A:: {}; //~ ERROR type arguments are not allowed on this type match S { T::A {} => {} // OK } diff --git a/src/test/ui/structs/struct-path-associated-type.stderr b/src/test/ui/structs/struct-path-associated-type.stderr index 0b1b6a5e3af28..7424ceecbe3b6 100644 --- a/src/test/ui/structs/struct-path-associated-type.stderr +++ b/src/test/ui/structs/struct-path-associated-type.stderr @@ -4,11 +4,13 @@ error[E0071]: expected struct, variant or union type, found associated type LL | let s = T::A {}; | ^^^^ not a struct -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/struct-path-associated-type.rs:14:20 | LL | let z = T::A:: {}; - | ^^ type argument not allowed + | - ^^ type argument not allowed + | | + | not allowed on this error[E0071]: expected struct, variant or union type, found associated type --> $DIR/struct-path-associated-type.rs:14:13 @@ -22,11 +24,13 @@ error[E0071]: expected struct, variant or union type, found associated type LL | T::A {} => {} | ^^^^ not a struct -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/struct-path-associated-type.rs:25:20 | LL | let z = T::A:: {}; - | ^^ type argument not allowed + | - ^^ type argument not allowed + | | + | not allowed on this error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:32:13 diff --git a/src/test/ui/structs/struct-path-self.rs b/src/test/ui/structs/struct-path-self.rs index c938ce8dad98d..6e529c7ed2b70 100644 --- a/src/test/ui/structs/struct-path-self.rs +++ b/src/test/ui/structs/struct-path-self.rs @@ -6,7 +6,7 @@ trait Tr { //~^ ERROR expected struct, variant or union type, found type parameter let z = Self:: {}; //~^ ERROR expected struct, variant or union type, found type parameter - //~| ERROR type arguments are not allowed for this type + //~| ERROR type arguments are not allowed on self type match s { Self { .. } => {} //~^ ERROR expected struct, variant or union type, found type parameter @@ -17,7 +17,7 @@ trait Tr { impl Tr for S { fn f() { let s = Self {}; // OK - let z = Self:: {}; //~ ERROR type arguments are not allowed for this type + let z = Self:: {}; //~ ERROR type arguments are not allowed on self type match s { Self { .. } => {} // OK } @@ -27,7 +27,7 @@ impl Tr for S { impl S { fn g() { let s = Self {}; // OK - let z = Self:: {}; //~ ERROR type arguments are not allowed for this type + let z = Self:: {}; //~ ERROR type arguments are not allowed on self type match s { Self { .. } => {} // OK } diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr index 37384e56bc9ef..3a4baeb9f6cf0 100644 --- a/src/test/ui/structs/struct-path-self.stderr +++ b/src/test/ui/structs/struct-path-self.stderr @@ -4,11 +4,13 @@ error[E0071]: expected struct, variant or union type, found type parameter `Self LL | let s = Self {}; | ^^^^ not a struct -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/struct-path-self.rs:7:24 | LL | let z = Self:: {}; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | help: the `Self` type doesn't accept type parameters | @@ -28,11 +30,13 @@ error[E0071]: expected struct, variant or union type, found type parameter `Self LL | Self { .. } => {} | ^^^^ not a struct -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/struct-path-self.rs:20:24 | LL | let z = Self:: {}; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `S` --> $DIR/struct-path-self.rs:1:8 @@ -48,11 +52,13 @@ LL - let z = Self:: {}; LL + let z = Self {}; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/struct-path-self.rs:30:24 | LL | let z = Self:: {}; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `S` --> $DIR/struct-path-self.rs:1:8 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 6bc4f528faaf9..e6f45036f8514 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 @@ -13,38 +13,38 @@ impl Enum { Self::TSVariant(()); //~^ ERROR mismatched types [E0308] Self::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Self::<()>::TSVariant(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on self type [E0109] //~| ERROR mismatched types [E0308] Self::<()>::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] - //~| ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR type arguments are not allowed on this type [E0109] } fn s_variant() { Self::SVariant { v: () }; //~^ ERROR mismatched types [E0308] Self::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] //~| ERROR mismatched types [E0308] Self::<()>::SVariant { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on self type [E0109] //~| ERROR mismatched types [E0308] Self::<()>::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] - //~| ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR type arguments are not allowed on this type [E0109] //~| ERROR mismatched types [E0308] } fn u_variant() { Self::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Self::<()>::UVariant; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on self type [E0109] Self::<()>::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] - //~| ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR type arguments are not allowed on this type [E0109] } } @@ -52,54 +52,54 @@ fn main() { // Tuple struct variant Enum::<()>::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Alias::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Alias::<()>::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::<()>::TSVariant(()); //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] AliasFixed::<()>::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] // Struct variant Enum::<()>::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Alias::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Alias::<()>::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::<()>::SVariant { v: () }; //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] AliasFixed::<()>::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] // Unit variant Enum::<()>::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Alias::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] Alias::<()>::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::<()>::UVariant; //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] AliasFixed::<()>::UVariant::<()>; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^ ERROR type arguments are not allowed on this type [E0109] //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] } 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 b1b0ec99999c6..3e60ab108a82f 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 @@ -17,17 +17,21 @@ note: tuple variant defined here LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^^^^^^ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:15:27 | LL | Self::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/enum-variant-generic-args.rs:17:16 | LL | Self::<()>::TSVariant(()); - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 @@ -61,11 +65,13 @@ note: tuple variant defined here LL | enum Enum { TSVariant(T), SVariant { v: T }, UVariant } | ^^^^^^^^^ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/enum-variant-generic-args.rs:20:16 | LL | Self::<()>::TSVariant::<()>(()); - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 @@ -80,11 +86,13 @@ help: the `Self` type doesn't accept type parameters, use the concrete type's na LL | Enum::<()>::TSVariant::<()>(()); | ~~~~ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:20:33 | LL | Self::<()>::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this error[E0308]: mismatched types --> $DIR/enum-variant-generic-args.rs:26:29 @@ -98,11 +106,13 @@ LL | Self::SVariant { v: () }; = note: expected type parameter `T` found unit type `()` -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:28:26 | LL | Self::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters help: you might have meant to specity type parameters on enum `Enum` @@ -123,11 +133,13 @@ LL | Self::SVariant::<()> { v: () }; = note: expected type parameter `T` found unit type `()` -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/enum-variant-generic-args.rs:31:16 | LL | Self::<()>::SVariant { v: () }; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 @@ -154,11 +166,13 @@ LL | Self::<()>::SVariant { v: () }; = note: expected type parameter `T` found unit type `()` -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/enum-variant-generic-args.rs:34:16 | LL | Self::<()>::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 @@ -173,11 +187,13 @@ help: the `Self` type doesn't accept type parameters, use the concrete type's na LL | Enum::<()>::SVariant::<()> { v: () }; | ~~~~ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:34:32 | LL | Self::<()>::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters help: you might have meant to specity type parameters on enum `Enum` @@ -198,17 +214,21 @@ LL | Self::<()>::SVariant::<()> { v: () }; = note: expected type parameter `T` found unit type `()` -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:41:26 | LL | Self::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/enum-variant-generic-args.rs:43:16 | LL | Self::<()>::UVariant; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 @@ -223,11 +243,13 @@ help: the `Self` type doesn't accept type parameters, use the concrete type's na LL | Enum::<()>::UVariant; | ~~~~ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on self type --> $DIR/enum-variant-generic-args.rs:45:16 | LL | Self::<()>::UVariant::<()>; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this | note: `Self` is of type `Enum` --> $DIR/enum-variant-generic-args.rs:7:6 @@ -242,35 +264,45 @@ help: the `Self` type doesn't accept type parameters, use the concrete type's na LL | Enum::<()>::UVariant::<()>; | ~~~~ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:45:32 | LL | Self::<()>::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:54:29 | LL | Enum::<()>::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:57:24 | LL | Alias::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:59:30 | LL | Alias::<()>::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:62:29 | LL | AliasFixed::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:64:5 @@ -300,25 +332,31 @@ note: type alias defined here, with 0 generic parameters LL | type AliasFixed = Enum<()>; | ^^^^^^^^^^ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:66:35 | LL | AliasFixed::<()>::TSVariant::<()>(()); - | ^^ type argument not allowed + | --------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:72:28 | LL | Enum::<()>::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:75:23 | LL | Alias::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters help: you might have meant to specity type parameters on enum `Enum` @@ -327,11 +365,13 @@ LL - Alias::SVariant::<()> { v: () }; LL + Alias::<()>::SVariant { v: () }; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:77:29 | LL | Alias::<()>::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters help: you might have meant to specity type parameters on enum `Enum` @@ -340,11 +380,13 @@ LL - Alias::<()>::SVariant::<()> { v: () }; LL + Alias::<()>::SVariant { v: () }; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:80:28 | LL | AliasFixed::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters help: you might have meant to specity type parameters on enum `Enum` @@ -381,11 +423,13 @@ note: type alias defined here, with 0 generic parameters LL | type AliasFixed = Enum<()>; | ^^^^^^^^^^ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:84:34 | LL | AliasFixed::<()>::SVariant::<()> { v: () }; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this | = note: enum variants can't have type parameters help: you might have meant to specity type parameters on enum `Enum` @@ -394,29 +438,37 @@ LL - AliasFixed::<()>::SVariant::<()> { v: () }; LL + AliasFixed::<()>::SVariant { v: () }; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:90:28 | LL | Enum::<()>::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:93:23 | LL | Alias::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:95:29 | LL | Alias::<()>::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:98:28 | LL | AliasFixed::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:100:5 @@ -446,11 +498,13 @@ note: type alias defined here, with 0 generic parameters LL | type AliasFixed = Enum<()>; | ^^^^^^^^^^ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:102:34 | LL | AliasFixed::<()>::UVariant::<()>; - | ^^ type argument not allowed + | -------- ^^ type argument not allowed + | | + | not allowed on this error: aborting due to 39 previous errors 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..872ece0c0f99e 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 @@ -10,5 +10,5 @@ fn main() { let _ = Option::::None; // OK let _ = Option::None::; // OK (Lint in future!) let _ = Alias::::None; // OK - let _ = Alias::None::; //~ ERROR type arguments are not allowed for this type + let _ = Alias::None::; //~ ERROR type arguments are not allowed on 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..474548a14a9a6 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,10 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27 | LL | let _ = Alias::None::; - | ^^ type argument not allowed + | ---- ^^ type argument not allowed + | | + | not allowed on this error: aborting due to previous error diff --git a/src/test/ui/type/issue-91268.rs b/src/test/ui/type/issue-91268.rs index fd2733c1c545e..01ed9ea9e231f 100644 --- a/src/test/ui/type/issue-91268.rs +++ b/src/test/ui/type/issue-91268.rs @@ -1,7 +1,7 @@ // error-pattern: this file contains an unclosed delimiter // error-pattern: cannot find type `ţ` in this scope // error-pattern: parenthesized type parameters may only be used with a `Fn` trait -// error-pattern: type arguments are not allowed for this type +// error-pattern: type arguments are not allowed on this type // error-pattern: mismatched types // ignore-tidy-trailing-newlines // `ţ` must be the last character in this file, it cannot be followed by a newline diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr index 9e86fd3aa7d6d..b8900b0218066 100644 --- a/src/test/ui/type/issue-91268.stderr +++ b/src/test/ui/type/issue-91268.stderr @@ -30,11 +30,13 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait LL | 0: u8(ţ | ^^^^ only `Fn` traits may use parentheses -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/issue-91268.rs:9:11 | LL | 0: u8(ţ - | ^ type argument not allowed + | -- ^ type argument not allowed + | | + | not allowed on this | help: primitive type `u8` doesn't have type parameters | diff --git a/src/test/ui/typeck/prim-with-args.fixed b/src/test/ui/typeck/prim-with-args.fixed index 0fd4a0f984e1e..1c5fd7508676a 100644 --- a/src/test/ui/typeck/prim-with-args.fixed +++ b/src/test/ui/typeck/prim-with-args.fixed @@ -1,28 +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 type arguments are not allowed on this type +let _x: i8; //~ ERROR type arguments are not allowed on this type +let _x: i16; //~ ERROR type arguments are not allowed on this type +let _x: i32; //~ ERROR type arguments are not allowed on this type +let _x: i64; //~ ERROR type arguments are not allowed on this type +let _x: usize; //~ ERROR type arguments are not allowed on this type +let _x: u8; //~ ERROR type arguments are not allowed on this type +let _x: u16; //~ ERROR type arguments are not allowed on this type +let _x: u32; //~ ERROR type arguments are not allowed on this type +let _x: u64; //~ ERROR type arguments are not allowed on this type +let _x: char; //~ ERROR type arguments are not allowed on 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 +let _x: isize; //~ ERROR lifetime arguments are not allowed on this type +let _x: i8; //~ ERROR lifetime arguments are not allowed on this type +let _x: i16; //~ ERROR lifetime arguments are not allowed on this type +let _x: i32; //~ ERROR lifetime arguments are not allowed on this type +let _x: i64; //~ ERROR lifetime arguments are not allowed on this type +let _x: usize; //~ ERROR lifetime arguments are not allowed on this type +let _x: u8; //~ ERROR lifetime arguments are not allowed on this type +let _x: u16; //~ ERROR lifetime arguments are not allowed on this type +let _x: u32; //~ ERROR lifetime arguments are not allowed on this type +let _x: u64; //~ ERROR lifetime arguments are not allowed on this type +let _x: char; //~ ERROR lifetime arguments are not allowed on this type } diff --git a/src/test/ui/typeck/prim-with-args.rs b/src/test/ui/typeck/prim-with-args.rs index a21fe69dc6a87..b05d6c1cb4e4a 100644 --- a/src/test/ui/typeck/prim-with-args.rs +++ b/src/test/ui/typeck/prim-with-args.rs @@ -1,28 +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 type arguments are not allowed on this type +let _x: i8; //~ ERROR type arguments are not allowed on this type +let _x: i16; //~ ERROR type arguments are not allowed on this type +let _x: i32; //~ ERROR type arguments are not allowed on this type +let _x: i64; //~ ERROR type arguments are not allowed on this type +let _x: usize; //~ ERROR type arguments are not allowed on this type +let _x: u8; //~ ERROR type arguments are not allowed on this type +let _x: u16; //~ ERROR type arguments are not allowed on this type +let _x: u32; //~ ERROR type arguments are not allowed on this type +let _x: u64; //~ ERROR type arguments are not allowed on this type +let _x: char; //~ ERROR type arguments are not allowed on 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 on this type +let _x: i8<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: i16<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: i32<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: i64<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: usize<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: u8<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: u16<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: u32<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: u64<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: char<'static>; //~ ERROR lifetime arguments are not allowed on this type } diff --git a/src/test/ui/typeck/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr index d7c32cf8ecf40..1728757c8086b 100644 --- a/src/test/ui/typeck/prim-with-args.stderr +++ b/src/test/ui/typeck/prim-with-args.stderr @@ -1,8 +1,10 @@ -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:4:15 | LL | let _x: isize; - | ^^^^^ type argument not allowed + | ----- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `isize` doesn't have type parameters | @@ -10,11 +12,13 @@ LL - let _x: isize; LL + let _x: isize; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:5:12 | LL | let _x: i8; - | ^^^^^ type argument not allowed + | -- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `i8` doesn't have type parameters | @@ -22,11 +26,13 @@ LL - let _x: i8; LL + let _x: i8; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:6:13 | LL | let _x: i16; - | ^^^^^ type argument not allowed + | --- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `i16` doesn't have type parameters | @@ -34,11 +40,13 @@ LL - let _x: i16; LL + let _x: i16; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:7:13 | LL | let _x: i32; - | ^^^^^ type argument not allowed + | --- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `i32` doesn't have type parameters | @@ -46,11 +54,13 @@ LL - let _x: i32; LL + let _x: i32; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:8:13 | LL | let _x: i64; - | ^^^^^ type argument not allowed + | --- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `i64` doesn't have type parameters | @@ -58,11 +68,13 @@ LL - let _x: i64; LL + let _x: i64; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:9:15 | LL | let _x: usize; - | ^^^^^ type argument not allowed + | ----- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `usize` doesn't have type parameters | @@ -70,11 +82,13 @@ LL - let _x: usize; LL + let _x: usize; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:10:12 | LL | let _x: u8; - | ^^^^^ type argument not allowed + | -- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `u8` doesn't have type parameters | @@ -82,11 +96,13 @@ LL - let _x: u8; LL + let _x: u8; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:11:13 | LL | let _x: u16; - | ^^^^^ type argument not allowed + | --- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `u16` doesn't have type parameters | @@ -94,11 +110,13 @@ LL - let _x: u16; LL + let _x: u16; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:12:13 | LL | let _x: u32; - | ^^^^^ type argument not allowed + | --- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `u32` doesn't have type parameters | @@ -106,11 +124,13 @@ LL - let _x: u32; LL + let _x: u32; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:13:13 | LL | let _x: u64; - | ^^^^^ type argument not allowed + | --- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `u64` doesn't have type parameters | @@ -118,11 +138,13 @@ LL - let _x: u64; LL + let _x: u64; | -error[E0109]: type arguments are not allowed for this type +error[E0109]: type arguments are not allowed on this type --> $DIR/prim-with-args.rs:14:14 | LL | let _x: char; - | ^^^^^ type argument not allowed + | ---- ^^^^^ type argument not allowed + | | + | not allowed on this | help: primitive type `char` doesn't have type parameters | @@ -130,11 +152,13 @@ LL - let _x: char; LL + let _x: char; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:16:15 | LL | let _x: isize<'static>; - | ^^^^^^^ lifetime argument not allowed + | ----- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `isize` doesn't have type parameters | @@ -142,11 +166,13 @@ LL - let _x: isize<'static>; LL + let _x: isize; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:17:12 | LL | let _x: i8<'static>; - | ^^^^^^^ lifetime argument not allowed + | -- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `i8` doesn't have type parameters | @@ -154,11 +180,13 @@ LL - let _x: i8<'static>; LL + let _x: i8; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:18:13 | LL | let _x: i16<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `i16` doesn't have type parameters | @@ -166,11 +194,13 @@ LL - let _x: i16<'static>; LL + let _x: i16; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:19:13 | LL | let _x: i32<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `i32` doesn't have type parameters | @@ -178,11 +208,13 @@ LL - let _x: i32<'static>; LL + let _x: i32; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:20:13 | LL | let _x: i64<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `i64` doesn't have type parameters | @@ -190,11 +222,13 @@ LL - let _x: i64<'static>; LL + let _x: i64; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:21:15 | LL | let _x: usize<'static>; - | ^^^^^^^ lifetime argument not allowed + | ----- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `usize` doesn't have type parameters | @@ -202,11 +236,13 @@ LL - let _x: usize<'static>; LL + let _x: usize; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:22:12 | LL | let _x: u8<'static>; - | ^^^^^^^ lifetime argument not allowed + | -- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `u8` doesn't have type parameters | @@ -214,11 +250,13 @@ LL - let _x: u8<'static>; LL + let _x: u8; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:23:13 | LL | let _x: u16<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `u16` doesn't have type parameters | @@ -226,11 +264,13 @@ LL - let _x: u16<'static>; LL + let _x: u16; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:24:13 | LL | let _x: u32<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `u32` doesn't have type parameters | @@ -238,11 +278,13 @@ LL - let _x: u32<'static>; LL + let _x: u32; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:25:13 | LL | let _x: u64<'static>; - | ^^^^^^^ lifetime argument not allowed + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `u64` doesn't have type parameters | @@ -250,11 +292,13 @@ LL - let _x: u64<'static>; LL + let _x: u64; | -error[E0109]: lifetime arguments are not allowed for this type +error[E0109]: lifetime arguments are not allowed on this type --> $DIR/prim-with-args.rs:26:14 | LL | let _x: char<'static>; - | ^^^^^^^ lifetime argument not allowed + | ---- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on this | help: primitive type `char` doesn't have type parameters | diff --git a/src/test/ui/usize-generic-argument-parent.rs b/src/test/ui/usize-generic-argument-parent.rs index 46b06e2b3662a..6d17ba9b5b261 100644 --- a/src/test/ui/usize-generic-argument-parent.rs +++ b/src/test/ui/usize-generic-argument-parent.rs @@ -1,5 +1,5 @@ fn foo() { - let x: usize; //~ ERROR const arguments are not allowed for this type + let x: usize; //~ ERROR const arguments are not allowed on this type } fn main() {} diff --git a/src/test/ui/usize-generic-argument-parent.stderr b/src/test/ui/usize-generic-argument-parent.stderr index 98505d7bbe8b0..e47de289d1ed2 100644 --- a/src/test/ui/usize-generic-argument-parent.stderr +++ b/src/test/ui/usize-generic-argument-parent.stderr @@ -1,8 +1,10 @@ -error[E0109]: const arguments are not allowed for this type +error[E0109]: const arguments are not allowed on this type --> $DIR/usize-generic-argument-parent.rs:2:18 | LL | let x: usize; - | ^^^ const argument not allowed + | ----- ^^^ const argument not allowed + | | + | not allowed on this | help: primitive type `usize` doesn't have type parameters | From cd8cfbfb098f8e1da086ee7d164af03e3fdde189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 2 Jun 2022 14:06:54 -0700 Subject: [PATCH 07/17] review comments --- compiler/rustc_typeck/src/astconv/mod.rs | 50 +++++++------------ src/test/ui/error-codes/E0109.stderr | 2 +- src/test/ui/error-codes/E0110.stderr | 2 +- src/test/ui/structs/struct-path-self.stderr | 4 +- src/test/ui/type/issue-91268.stderr | 2 +- src/test/ui/typeck/prim-with-args.stderr | 44 ++++++++-------- .../ui/usize-generic-argument-parent.stderr | 2 +- 7 files changed, 47 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 405acfc186cf4..bcff2ae512909 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1816,7 +1816,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // work for the `enum`, instead of just looking if it takes *any*. err.span_suggestion_verbose( args_span, - &format!("{type_name} doesn't have type parameters"), + &format!("{type_name} doesn't have generic parameters"), String::new(), Applicability::MachineApplicable, ); @@ -2115,20 +2115,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if segment.args().args.is_empty() { None } else { - let mut desc = res.descr(); - if desc == "unresolved item" { - desc = "this type"; - }; - - let name = match res { - Res::PrimTy(ty) => Some(ty.name()), - Res::Def(_, def_id) => self.tcx().opt_item_name(def_id), - _ => None, - }; Some(( - match name { - Some(ty) => format!("{desc} `{ty}`"), - None => desc.to_string(), + match res { + Res::PrimTy(ty) => format!("{} `{}`", res.descr(), ty.name()), + Res::Def(_, def_id) + if let Some(name) = self.tcx().opt_item_name(def_id) => { + format!("{} `{name}`", res.descr()) + } + Res::Err => "this type".to_string(), + _ => res.descr().to_string(), }, segment.ident.span, )) @@ -2158,33 +2153,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }); let mut emitted = false; if lt || ty || ct || inf { - let arg_spans: Vec = args - .map(|arg| match arg { - hir::GenericArg::Lifetime(lt) => lt.span, - hir::GenericArg::Type(ty) => ty.span, - hir::GenericArg::Const(ct) => ct.span, - hir::GenericArg::Infer(inf) => inf.span, - }) - .collect(); + let arg_spans: Vec = args.map(|arg| arg.span()).collect(); - let mut types = Vec::with_capacity(4); + let mut kinds = Vec::with_capacity(4); if lt { - types.push("lifetime"); + kinds.push("lifetime"); } if ty { - types.push("type"); + kinds.push("type"); } if ct { - types.push("const"); + kinds.push("const"); } if inf { - types.push("generic"); + kinds.push("generic"); } - let (kind, s) = match types[..] { + let (kind, s) = match kinds[..] { [.., _, last] => ( format!( "{} and {last}", - types[..types.len() - 1] + kinds[..kinds.len() - 1] .iter() .map(|&x| x) .intersperse(", ") @@ -2464,7 +2452,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); let mut postfix = ""; if generics == 0 { - postfix = ", which doesn't have type parameters"; + postfix = ", which doesn't have generic parameters"; } span.push_span_label( t_sp, @@ -2557,7 +2545,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { 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"), + &format!("primitive type `{name}` doesn't have generic parameters"), String::new(), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr index e91c74151b3b3..e0e437e18ae8c 100644 --- a/src/test/ui/error-codes/E0109.stderr +++ b/src/test/ui/error-codes/E0109.stderr @@ -6,7 +6,7 @@ LL | type X = u32; | | | not allowed on this | -help: primitive type `u32` doesn't have type parameters +help: primitive type `u32` doesn't have generic parameters | LL - type X = u32; LL + type X = u32; diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index 4425d87e2b0c8..15e1b959193fa 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -6,7 +6,7 @@ LL | type X = u32<'static>; | | | not allowed on this | -help: primitive type `u32` doesn't have type parameters +help: primitive type `u32` doesn't have generic parameters | LL - type X = u32<'static>; LL + type X = u32; diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr index 3a4baeb9f6cf0..cccdd7b0f023f 100644 --- a/src/test/ui/structs/struct-path-self.stderr +++ b/src/test/ui/structs/struct-path-self.stderr @@ -42,7 +42,7 @@ note: `Self` is of type `S` --> $DIR/struct-path-self.rs:1:8 | LL | struct S; - | ^ `Self` corresponds to this type, which doesn't have type parameters + | ^ `Self` corresponds to this type, which doesn't have generic parameters ... LL | impl Tr for S { | ------------- `Self` is on type `S` in this `impl` @@ -64,7 +64,7 @@ note: `Self` is of type `S` --> $DIR/struct-path-self.rs:1:8 | LL | struct S; - | ^ `Self` corresponds to this type, which doesn't have type parameters + | ^ `Self` corresponds to this type, which doesn't have generic parameters ... LL | impl S { | ------ `Self` is on type `S` in this `impl` diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr index b8900b0218066..199fd6a23f755 100644 --- a/src/test/ui/type/issue-91268.stderr +++ b/src/test/ui/type/issue-91268.stderr @@ -38,7 +38,7 @@ LL | 0: u8(ţ | | | not allowed on this | -help: primitive type `u8` doesn't have type parameters +help: primitive type `u8` doesn't have generic parameters | LL - 0: u8(ţ LL + 0: u8 diff --git a/src/test/ui/typeck/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr index 1728757c8086b..7e7bc580b3b95 100644 --- a/src/test/ui/typeck/prim-with-args.stderr +++ b/src/test/ui/typeck/prim-with-args.stderr @@ -6,7 +6,7 @@ LL | let _x: isize; | | | not allowed on this | -help: primitive type `isize` doesn't have type parameters +help: primitive type `isize` doesn't have generic parameters | LL - let _x: isize; LL + let _x: isize; @@ -20,7 +20,7 @@ LL | let _x: i8; | | | not allowed on this | -help: primitive type `i8` doesn't have type parameters +help: primitive type `i8` doesn't have generic parameters | LL - let _x: i8; LL + let _x: i8; @@ -34,7 +34,7 @@ LL | let _x: i16; | | | not allowed on this | -help: primitive type `i16` doesn't have type parameters +help: primitive type `i16` doesn't have generic parameters | LL - let _x: i16; LL + let _x: i16; @@ -48,7 +48,7 @@ LL | let _x: i32; | | | not allowed on this | -help: primitive type `i32` doesn't have type parameters +help: primitive type `i32` doesn't have generic parameters | LL - let _x: i32; LL + let _x: i32; @@ -62,7 +62,7 @@ LL | let _x: i64; | | | not allowed on this | -help: primitive type `i64` doesn't have type parameters +help: primitive type `i64` doesn't have generic parameters | LL - let _x: i64; LL + let _x: i64; @@ -76,7 +76,7 @@ LL | let _x: usize; | | | not allowed on this | -help: primitive type `usize` doesn't have type parameters +help: primitive type `usize` doesn't have generic parameters | LL - let _x: usize; LL + let _x: usize; @@ -90,7 +90,7 @@ LL | let _x: u8; | | | not allowed on this | -help: primitive type `u8` doesn't have type parameters +help: primitive type `u8` doesn't have generic parameters | LL - let _x: u8; LL + let _x: u8; @@ -104,7 +104,7 @@ LL | let _x: u16; | | | not allowed on this | -help: primitive type `u16` doesn't have type parameters +help: primitive type `u16` doesn't have generic parameters | LL - let _x: u16; LL + let _x: u16; @@ -118,7 +118,7 @@ LL | let _x: u32; | | | not allowed on this | -help: primitive type `u32` doesn't have type parameters +help: primitive type `u32` doesn't have generic parameters | LL - let _x: u32; LL + let _x: u32; @@ -132,7 +132,7 @@ LL | let _x: u64; | | | not allowed on this | -help: primitive type `u64` doesn't have type parameters +help: primitive type `u64` doesn't have generic parameters | LL - let _x: u64; LL + let _x: u64; @@ -146,7 +146,7 @@ LL | let _x: char; | | | not allowed on this | -help: primitive type `char` doesn't have type parameters +help: primitive type `char` doesn't have generic parameters | LL - let _x: char; LL + let _x: char; @@ -160,7 +160,7 @@ LL | let _x: isize<'static>; | | | not allowed on this | -help: primitive type `isize` doesn't have type parameters +help: primitive type `isize` doesn't have generic parameters | LL - let _x: isize<'static>; LL + let _x: isize; @@ -174,7 +174,7 @@ LL | let _x: i8<'static>; | | | not allowed on this | -help: primitive type `i8` doesn't have type parameters +help: primitive type `i8` doesn't have generic parameters | LL - let _x: i8<'static>; LL + let _x: i8; @@ -188,7 +188,7 @@ LL | let _x: i16<'static>; | | | not allowed on this | -help: primitive type `i16` doesn't have type parameters +help: primitive type `i16` doesn't have generic parameters | LL - let _x: i16<'static>; LL + let _x: i16; @@ -202,7 +202,7 @@ LL | let _x: i32<'static>; | | | not allowed on this | -help: primitive type `i32` doesn't have type parameters +help: primitive type `i32` doesn't have generic parameters | LL - let _x: i32<'static>; LL + let _x: i32; @@ -216,7 +216,7 @@ LL | let _x: i64<'static>; | | | not allowed on this | -help: primitive type `i64` doesn't have type parameters +help: primitive type `i64` doesn't have generic parameters | LL - let _x: i64<'static>; LL + let _x: i64; @@ -230,7 +230,7 @@ LL | let _x: usize<'static>; | | | not allowed on this | -help: primitive type `usize` doesn't have type parameters +help: primitive type `usize` doesn't have generic parameters | LL - let _x: usize<'static>; LL + let _x: usize; @@ -244,7 +244,7 @@ LL | let _x: u8<'static>; | | | not allowed on this | -help: primitive type `u8` doesn't have type parameters +help: primitive type `u8` doesn't have generic parameters | LL - let _x: u8<'static>; LL + let _x: u8; @@ -258,7 +258,7 @@ LL | let _x: u16<'static>; | | | not allowed on this | -help: primitive type `u16` doesn't have type parameters +help: primitive type `u16` doesn't have generic parameters | LL - let _x: u16<'static>; LL + let _x: u16; @@ -272,7 +272,7 @@ LL | let _x: u32<'static>; | | | not allowed on this | -help: primitive type `u32` doesn't have type parameters +help: primitive type `u32` doesn't have generic parameters | LL - let _x: u32<'static>; LL + let _x: u32; @@ -286,7 +286,7 @@ LL | let _x: u64<'static>; | | | not allowed on this | -help: primitive type `u64` doesn't have type parameters +help: primitive type `u64` doesn't have generic parameters | LL - let _x: u64<'static>; LL + let _x: u64; @@ -300,7 +300,7 @@ LL | let _x: char<'static>; | | | not allowed on this | -help: primitive type `char` doesn't have type parameters +help: primitive type `char` doesn't have generic parameters | LL - let _x: char<'static>; LL + let _x: char; diff --git a/src/test/ui/usize-generic-argument-parent.stderr b/src/test/ui/usize-generic-argument-parent.stderr index e47de289d1ed2..c657f0faa0b98 100644 --- a/src/test/ui/usize-generic-argument-parent.stderr +++ b/src/test/ui/usize-generic-argument-parent.stderr @@ -6,7 +6,7 @@ LL | let x: usize; | | | not allowed on this | -help: primitive type `usize` doesn't have type parameters +help: primitive type `usize` doesn't have generic parameters | LL - let x: usize; LL + let x: usize; From e0cbac6a398b4d0aa73eb590f7fcd1460ef97050 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:09:23 +0200 Subject: [PATCH 08/17] Add "no-fallthrough" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index f66ecbf78af7b..cf99ed56de137 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -70,5 +70,6 @@ module.exports = { "no-dupe-keys": "error", "no-duplicate-case": "error", "no-ex-assign": "error", + "no-fallthrough": "error", } }; From fe503adf4c023f8f8284262ea2b39bf2ce3fabcf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:11:33 +0200 Subject: [PATCH 09/17] Add "no-invalid-regexp" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index cf99ed56de137..e6ed3809cddcf 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -71,5 +71,6 @@ module.exports = { "no-duplicate-case": "error", "no-ex-assign": "error", "no-fallthrough": "error", + "no-invalid-regexp": "error", } }; From e7d1b5a9526bcd15066a99cd96f6d3cbb140a873 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:13:42 +0200 Subject: [PATCH 10/17] Add "no-import-assign" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index e6ed3809cddcf..efc6f28d0435c 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -72,5 +72,6 @@ module.exports = { "no-ex-assign": "error", "no-fallthrough": "error", "no-invalid-regexp": "error", + "no-import-assign": "error", } }; From 584eec6c26eb2c1058cf70f25b0a3a64b598d456 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:14:07 +0200 Subject: [PATCH 11/17] Add "no-self-compare" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index efc6f28d0435c..ff97e74759f45 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -73,5 +73,6 @@ module.exports = { "no-fallthrough": "error", "no-invalid-regexp": "error", "no-import-assign": "error", + "no-self-compare": "error", } }; From 72bd8e49964146fe803ecdcc25de9ef1cf37beda Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:16:23 +0200 Subject: [PATCH 12/17] Add "no-template-curly-in-string" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index ff97e74759f45..fa1ff41b9a58f 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -74,5 +74,6 @@ module.exports = { "no-invalid-regexp": "error", "no-import-assign": "error", "no-self-compare": "error", + "no-template-curly-in-string": "error", } }; From 1e4a149823b4ac139c2cffff6138b905c3c6e129 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:20:46 +0200 Subject: [PATCH 13/17] Add "block-scoped-var" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index fa1ff41b9a58f..627c3e0780b8b 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -75,5 +75,6 @@ module.exports = { "no-import-assign": "error", "no-self-compare": "error", "no-template-curly-in-string": "error", + "block-scoped-var": "error", } }; From 7db2b00be3e4bc30495041461764bfc7917dbfd1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:28:34 +0200 Subject: [PATCH 14/17] Add "guard-for-in" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index 627c3e0780b8b..ab0bff952285f 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -76,5 +76,6 @@ module.exports = { "no-self-compare": "error", "no-template-curly-in-string": "error", "block-scoped-var": "error", + "guard-for-in": "error", } }; From 6ce2e052e16f8c7c317686fb6d3d4b4670169745 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jun 2022 11:29:49 +0200 Subject: [PATCH 15/17] Add "no-alert" eslint rule --- src/librustdoc/html/static/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index ab0bff952285f..bd83b254caacb 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -77,5 +77,6 @@ module.exports = { "no-template-curly-in-string": "error", "block-scoped-var": "error", "guard-for-in": "error", + "no-alert": "error", } }; From b1294e86bbbccda04da32584484bac4dc47bf0cc Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Apr 2022 22:15:58 +0200 Subject: [PATCH 16/17] Manipulate lifetimes by LocalDefId for region resolution. --- compiler/rustc_ast_lowering/src/lib.rs | 41 ++--- .../src/diagnostics/region_name.rs | 4 +- compiler/rustc_hir/src/hir.rs | 52 ++++--- compiler/rustc_hir/src/intravisit.rs | 8 +- .../src/middle/resolve_lifetime.rs | 11 +- .../rustc_resolve/src/late/diagnostics.rs | 29 +++- compiler/rustc_resolve/src/late/lifetimes.rs | 147 ++++++++---------- .../wrong_number_of_generic_args.rs | 4 +- src/librustdoc/clean/mod.rs | 23 +-- .../clippy/clippy_lints/src/lifetimes.rs | 2 +- src/tools/clippy/clippy_lints/src/ptr.rs | 2 +- .../clippy/clippy_utils/src/hir_utils.rs | 8 +- 12 files changed, 161 insertions(+), 170 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 96db40cb95b97..d1ea76b392223 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -672,9 +672,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Param { .. } => { (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit) } - LifetimeRes::Fresh { param, .. } => { - (hir::ParamName::Fresh(param), hir::LifetimeParamKind::Elided) - } + LifetimeRes::Fresh { .. } => (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided), LifetimeRes::Static | LifetimeRes::Error => return None, res => panic!( "Unexpected lifetime resolution {:?} for {:?} at {:?}", @@ -1576,10 +1574,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id }) } // Input lifetime like `'1`: - LifetimeRes::Fresh { param, .. } => ( - hir::ParamName::Fresh(outer_def_id), - LifetimeRes::Fresh { param, binder: fn_node_id }, - ), + LifetimeRes::Fresh { param, .. } => { + (hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id }) + } LifetimeRes::Static | LifetimeRes::Error => continue, res => { panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span) @@ -1749,7 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::Lifetime { debug!(?self.captured_lifetimes); let name = match res { - LifetimeRes::Param { param, binder } => { + LifetimeRes::Param { mut param, binder } => { debug_assert_ne!(ident.name, kw::UnderscoreLifetime); let p_name = ParamName::Plain(ident); if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) = @@ -1757,10 +1754,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { && !binders_to_ignore.contains(&binder) { match captures.entry(param) { - Entry::Occupied(_) => {} + Entry::Occupied(o) => param = self.resolver.local_def_id(o.get().1), Entry::Vacant(v) => { let p_id = self.resolver.next_node_id(); - self.resolver.create_def( + let p_def_id = self.resolver.create_def( *parent_def_id, p_id, DefPathData::LifetimeNs(p_name.ident().name), @@ -1769,10 +1766,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); v.insert((span, p_id, p_name, res)); + param = p_def_id; } } } - hir::LifetimeName::Param(p_name) + hir::LifetimeName::Param(param, p_name) } LifetimeRes::Fresh { mut param, binder } => { debug_assert_eq!(ident.name, kw::UnderscoreLifetime); @@ -1792,21 +1790,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span.with_parent(None), ); - let p_name = ParamName::Fresh(param); - v.insert((span, p_id, p_name, res)); + v.insert((span, p_id, ParamName::Fresh, res)); param = p_def_id; } } } - let p_name = ParamName::Fresh(param); - hir::LifetimeName::Param(p_name) + hir::LifetimeName::Param(param, ParamName::Fresh) } LifetimeRes::Anonymous { binder, elided } => { - let l_name = if elided { - hir::LifetimeName::Implicit - } else { - hir::LifetimeName::Underscore - }; if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) = &mut self.captured_lifetimes && !binders_to_ignore.contains(&binder) @@ -1819,11 +1810,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExpnId::root(), span.with_parent(None), ); - let p_name = ParamName::Fresh(p_def_id); - captures.insert(p_def_id, (span, p_id, p_name, res)); - hir::LifetimeName::Param(p_name) + captures.insert(p_def_id, (span, p_id, ParamName::Fresh, res)); + hir::LifetimeName::Param(p_def_id, ParamName::Fresh) + } else if elided { + hir::LifetimeName::Implicit } else { - l_name + hir::LifetimeName::Underscore } } LifetimeRes::Static => hir::LifetimeName::Static, @@ -1831,6 +1823,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span), }; debug!(?self.captured_lifetimes); + debug!(?name); hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name } } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index cb4b154d271a5..fcb6ae438fed9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -567,14 +567,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?; match lifetime.name { - hir::LifetimeName::Param(hir::ParamName::Plain(_) | hir::ParamName::Error) + hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error) | hir::LifetimeName::Error | hir::LifetimeName::Static => { let lifetime_span = lifetime.span; Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span)) } - hir::LifetimeName::Param(hir::ParamName::Fresh(_)) + hir::LifetimeName::Param(_, hir::ParamName::Fresh) | hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index dbe6fe6ea8402..b98d434111862 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi; use smallvec::SmallVec; use std::fmt; -#[derive(Copy, Clone, Encodable, HashStable_Generic)] +#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)] pub struct Lifetime { pub hir_id: HirId, pub span: Span, @@ -60,7 +60,7 @@ pub enum ParamName { /// ``` /// where `'f` is something like `Fresh(0)`. The indices are /// unique per impl, but not necessarily continuous. - Fresh(LocalDefId), + Fresh, /// Indicates an illegal name was given and an error has been /// reported (so we should squelch other derived errors). Occurs @@ -72,9 +72,7 @@ impl ParamName { pub fn ident(&self) -> Ident { match *self { ParamName::Plain(ident) => ident, - ParamName::Fresh(_) | ParamName::Error => { - Ident::with_dummy_span(kw::UnderscoreLifetime) - } + ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime), } } @@ -90,7 +88,7 @@ impl ParamName { #[derive(HashStable_Generic)] pub enum LifetimeName { /// User-given names or fresh (synthetic) names. - Param(ParamName), + Param(LocalDefId, ParamName), /// User wrote nothing (e.g., the lifetime in `&u32`). Implicit, @@ -127,7 +125,7 @@ impl LifetimeName { | LifetimeName::Error => Ident::empty(), LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), - LifetimeName::Param(param_name) => param_name.ident(), + LifetimeName::Param(_, param_name) => param_name.ident(), } } @@ -136,9 +134,9 @@ impl LifetimeName { LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Implicit | LifetimeName::Underscore - | LifetimeName::Param(ParamName::Fresh(_)) + | LifetimeName::Param(_, ParamName::Fresh) | LifetimeName::Error => true, - LifetimeName::Static | LifetimeName::Param(_) => false, + LifetimeName::Static | LifetimeName::Param(..) => false, } } @@ -148,12 +146,12 @@ impl LifetimeName { | LifetimeName::Implicit | LifetimeName::Underscore => true, - // It might seem surprising that `Fresh(_)` counts as + // It might seem surprising that `Fresh` counts as // *not* elided -- but this is because, as far as the code - // in the compiler is concerned -- `Fresh(_)` variants act + // in the compiler is concerned -- `Fresh` variants act // equivalently to "some fresh name". They correspond to // early-bound regions on an impl, in other words. - LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false, + LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false, } } @@ -163,8 +161,8 @@ impl LifetimeName { pub fn normalize_to_macros_2_0(&self) -> LifetimeName { match *self { - LifetimeName::Param(param_name) => { - LifetimeName::Param(param_name.normalize_to_macros_2_0()) + LifetimeName::Param(def_id, param_name) => { + LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0()) } lifetime_name => lifetime_name, } @@ -177,12 +175,6 @@ impl fmt::Display for Lifetime { } } -impl fmt::Debug for Lifetime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "lifetime({}: {})", self.hir_id, self.name.ident()) - } -} - impl Lifetime { pub fn is_elided(&self) -> bool { self.name.is_elided() @@ -628,6 +620,16 @@ impl<'hir> Generics<'hir> { }) } + pub fn outlives_for_param( + &self, + param_def_id: LocalDefId, + ) -> impl Iterator> { + self.predicates.iter().filter_map(move |pred| match pred { + WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp), + _ => None, + }) + } + pub fn bounds_span_for_suggestions(&self, param_def_id: LocalDefId) -> Option { self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map( |bound| { @@ -769,6 +771,16 @@ pub struct WhereRegionPredicate<'hir> { pub bounds: GenericBounds<'hir>, } +impl<'hir> WhereRegionPredicate<'hir> { + /// Returns `true` if `param_def_id` matches the `lifetime` of this predicate. + pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool { + match self.lifetime.name { + LifetimeName::Param(id, _) => id == param_def_id, + _ => false, + } + } +} + /// An equality predicate (e.g., `T = int`); currently unsupported. #[derive(Debug, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 5b83a29bb33c3..bd8587f1106e9 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -510,11 +510,11 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) { pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { visitor.visit_id(lifetime.hir_id); match lifetime.name { - LifetimeName::Param(ParamName::Plain(ident)) => { + LifetimeName::Param(_, ParamName::Plain(ident)) => { visitor.visit_ident(ident); } - LifetimeName::Param(ParamName::Fresh(_)) - | LifetimeName::Param(ParamName::Error) + LifetimeName::Param(_, ParamName::Fresh) + | LifetimeName::Param(_, ParamName::Error) | LifetimeName::Static | LifetimeName::Error | LifetimeName::Implicit @@ -879,7 +879,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi visitor.visit_id(param.hir_id); match param.name { ParamName::Plain(ident) => visitor.visit_ident(ident), - ParamName::Error | ParamName::Fresh(_) => {} + ParamName::Error | ParamName::Fresh => {} } match param.kind { GenericParamKind::Lifetime { .. } => {} diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 70586cefaeee1..cdc0d07680193 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -6,7 +6,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::ItemLocalId; use rustc_macros::HashStable; -use rustc_span::symbol::Symbol; #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)] pub enum Region { @@ -22,12 +21,12 @@ pub enum Region { /// so that we can e.g. suggest elided-lifetimes-in-paths of the form <'_, '_> e.g. #[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)] pub enum LifetimeScopeForPath { - // Contains all lifetime names that are in scope and could possibly be used in generics - // arguments of path. - NonElided(Vec), + /// Contains all lifetime names that are in scope and could possibly be used in generics + /// arguments of path. + NonElided(Vec), - // Information that allows us to suggest args of the form `<'_>` in case - // no generic arguments were provided for a path. + /// Information that allows us to suggest args of the form `<'_>` in case + /// no generic arguments were provided for a path. Elided, } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9213652e35f8e..cb39eb5416ba2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -13,7 +13,7 @@ use rustc_ast::{ }; use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_pretty::pprust::path_segment_to_string; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, @@ -21,7 +21,7 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; -use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; use rustc_session::lint; use rustc_session::parse::feature_err; @@ -2082,7 +2082,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { /// Returns whether to add `'static` lifetime to the suggested lifetime list. pub(crate) fn report_elision_failure( - &mut self, + &self, diag: &mut Diagnostic, params: &[ElisionFailureInfo], ) -> bool { @@ -2187,10 +2187,27 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { &self, err: &mut Diagnostic, mut spans_with_counts: Vec<(Span, usize)>, - lifetime_names: &FxHashSet, - lifetime_spans: Vec, - params: &[ElisionFailureInfo], + in_scope_lifetimes: FxIndexSet, + params: Option<&[ElisionFailureInfo]>, ) { + let (mut lifetime_names, lifetime_spans): (FxHashSet<_>, Vec<_>) = in_scope_lifetimes + .iter() + .filter_map(|def_id| { + let name = self.tcx.item_name(def_id.to_def_id()); + let span = self.tcx.def_ident_span(def_id.to_def_id())?; + Some((name, span)) + }) + .filter(|&(n, _)| n != kw::UnderscoreLifetime) + .unzip(); + + if let Some(params) = params { + // If there's no lifetime available, suggest `'static`. + if self.report_elision_failure(err, params) && lifetime_names.is_empty() { + lifetime_names.insert(kw::StaticLifetime); + } + } + let params = params.unwrap_or(&[]); + let snippets: Vec> = spans_with_counts .iter() .map(|(span, _)| self.tcx.sess.source_map().span_to_snippet(*span).ok()) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 59c2db25b8e05..6cd81aa7dac13 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -8,14 +8,14 @@ use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot}; use rustc_ast::walk_list; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefIdMap, LocalDefId}; use rustc_hir::hir_id::ItemLocalId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName}; +use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node}; use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; @@ -33,9 +33,9 @@ use std::mem::take; use tracing::{debug, span, Level}; trait RegionExt { - fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region); + fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region); - fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region); + fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region); fn late_anon(named_late_bound_vars: u32, index: &Cell) -> Region; @@ -51,22 +51,22 @@ trait RegionExt { } impl RegionExt for Region { - fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region) { + fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region) { let i = *index; *index += 1; let def_id = hir_map.local_def_id(param.hir_id); debug!("Region::early: index={} def_id={:?}", i, def_id); - (param.name.normalize_to_macros_2_0(), Region::EarlyBound(i, def_id.to_def_id())) + (def_id, Region::EarlyBound(i, def_id.to_def_id())) } - fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region) { + fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) { let depth = ty::INNERMOST; let def_id = hir_map.local_def_id(param.hir_id); debug!( "Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}", idx, param, depth, def_id, ); - (param.name.normalize_to_macros_2_0(), Region::LateBound(depth, idx, def_id.to_def_id())) + (def_id, Region::LateBound(depth, idx, def_id.to_def_id())) } fn late_anon(named_late_bound_vars: u32, index: &Cell) -> Region { @@ -178,7 +178,7 @@ enum Scope<'a> { Binder { /// We use an IndexMap here because we want these lifetimes in order /// for diagnostics. - lifetimes: FxIndexMap, + lifetimes: FxIndexMap, /// if we extend this scope with another scope, what is the next index /// we should use for an early-bound region? @@ -554,10 +554,7 @@ fn get_lifetime_scopes_for_path(mut scope: &Scope<'_>) -> LifetimeScopeForPath { loop { match scope { Scope::Binder { lifetimes, s, .. } => { - available_lifetimes.extend(lifetimes.keys().filter_map(|p| match p { - hir::ParamName::Plain(ident) => Some(ident.name), - _ => None, - })); + available_lifetimes.extend(lifetimes.keys()); scope = s; } Scope::Body { s, .. } => { @@ -841,7 +838,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.missing_named_lifetime_spots .push(MissingLifetimeSpot::HigherRanked { span, span_type }); - let (lifetimes, binders): (FxIndexMap, Vec<_>) = c + let (lifetimes, binders): (FxIndexMap, Vec<_>) = c .generic_params .iter() .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) @@ -898,7 +895,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // cc #48468 self.resolve_elided_lifetimes(&[lifetime]) } - LifetimeName::Param(_) | LifetimeName::Static => { + LifetimeName::Param(..) | LifetimeName::Static => { // If the user wrote an explicit name, use that. self.visit_lifetime(lifetime); } @@ -1016,17 +1013,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { for param in generics.params { match param.kind { GenericParamKind::Lifetime { .. } => { - let (name, reg) = Region::early(self.tcx.hir(), &mut index, ¶m); + let (def_id, reg) = Region::early(self.tcx.hir(), &mut index, ¶m); if let hir::ParamName::Plain(Ident { name: kw::UnderscoreLifetime, .. - }) = name + }) = param.name { // Pick the elided lifetime "definition" if one exists // and use it to make an elision scope. elision = Some(reg); } else { - lifetimes.insert(name, reg); + lifetimes.insert(def_id, reg); } } GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { @@ -1174,7 +1171,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let mut index = self.next_early_index(); let mut non_lifetime_count = 0; debug!("visit_ty: index = {}", index); - let lifetimes: FxIndexMap = generics + let lifetimes: FxIndexMap = generics .params .iter() .filter_map(|param| match param.kind { @@ -1218,15 +1215,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { #[tracing::instrument(level = "debug", skip(self))] fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { - if lifetime_ref.is_elided() { - self.resolve_elided_lifetimes(&[lifetime_ref]); - return; - } - if lifetime_ref.is_static() { - self.insert_lifetime(lifetime_ref, Region::Static); - return; + match lifetime_ref.name { + hir::LifetimeName::ImplicitObjectLifetimeDefault + | hir::LifetimeName::Implicit + | hir::LifetimeName::Underscore => self.resolve_elided_lifetimes(&[lifetime_ref]), + hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), + hir::LifetimeName::Param(param_def_id, _) => { + self.resolve_lifetime_ref(param_def_id, lifetime_ref) + } + // If we've already reported an error, just ignore `lifetime_ref`. + hir::LifetimeName::Error => {} } - self.resolve_lifetime_ref(lifetime_ref); } fn visit_assoc_type_binding(&mut self, type_binding: &'tcx hir::TypeBinding<'_>) { @@ -1311,7 +1310,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { ref bound_generic_params, .. }) => { - let (lifetimes, binders): (FxIndexMap, Vec<_>) = + let (lifetimes, binders): (FxIndexMap, Vec<_>) = bound_generic_params .iter() .filter(|param| { @@ -1433,7 +1432,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let (mut binders, scope_type) = self.poly_trait_ref_binder_info(); let initial_bound_vars = binders.len() as u32; - let mut lifetimes: FxIndexMap = FxIndexMap::default(); + let mut lifetimes: FxIndexMap = FxIndexMap::default(); let binders_iter = trait_ref .bound_generic_params .iter() @@ -1580,14 +1579,17 @@ fn object_lifetime_defaults_for_item<'tcx>( .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some((param.hir_id, hir::LifetimeName::Param(param.name))) + let param_def_id = tcx.hir().local_def_id(param.hir_id); + Some(( + param_def_id, + hir::LifetimeName::Param(param_def_id, param.name), + )) } _ => None, }) .enumerate() .find(|&(_, (_, lt_name))| lt_name == name) - .map_or(Set1::Many, |(i, (id, _))| { - let def_id = tcx.hir().local_def_id(id); + .map_or(Set1::Many, |(i, (def_id, _))| { Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id())) }) } @@ -1660,7 +1662,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ) where F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>), { - insert_late_bound_lifetimes(self.map, decl, generics); + insert_late_bound_lifetimes(self.tcx, self.map, decl, generics); // Find the start of nested early scopes, e.g., in methods. let mut next_early_index = 0; @@ -1680,7 +1682,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut non_lifetime_count = 0; let mut named_late_bound_vars = 0; - let lifetimes: FxIndexMap = generics + let lifetimes: FxIndexMap = generics .params .iter() .filter_map(|param| match param.kind { @@ -1763,14 +1765,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.next_early_index_helper(false) } - fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) { - debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref); - - // If we've already reported an error, just ignore `lifetime_ref`. - if let LifetimeName::Error = lifetime_ref.name { - return; - } - + #[tracing::instrument(level = "debug", skip(self))] + fn resolve_lifetime_ref( + &mut self, + region_def_id: LocalDefId, + lifetime_ref: &'tcx hir::Lifetime, + ) { // Walk up the scope chain, tracking the number of fn scopes // that we pass through, until we find a lifetime with the // given name or we run out of scopes. @@ -1790,14 +1790,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } Scope::Binder { ref lifetimes, scope_type, s, .. } => { - match lifetime_ref.name { - LifetimeName::Param(param_name) => { - if let Some(&def) = lifetimes.get(¶m_name.normalize_to_macros_2_0()) - { - break Some(def.shifted(late_depth)); - } - } - _ => bug!("expected LifetimeName::Param"), + if let Some(&def) = lifetimes.get(®ion_def_id) { + break Some(def.shifted(late_depth)); } match scope_type { BinderScopeType::Normal => late_depth += 1, @@ -2473,8 +2467,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut late_depth = 0; let mut scope = self.scope; - let mut lifetime_names = FxHashSet::default(); - let mut lifetime_spans = vec![]; + let mut in_scope_lifetimes = FxIndexSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2484,12 +2477,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { s, ref lifetimes, scope_type, .. } => { // collect named lifetimes for suggestions - for name in lifetimes.keys() { - if let hir::ParamName::Plain(name) = name { - lifetime_names.insert(name.name); - lifetime_spans.push(name.span); - } - } + in_scope_lifetimes.extend(lifetimes.keys().copied()); match scope_type { BinderScopeType::Normal => late_depth += 1, BinderScopeType::Concatenating => {} @@ -2524,12 +2512,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { match scope { Scope::Binder { ref lifetimes, s, .. } => { // Collect named lifetimes for suggestions. - for name in lifetimes.keys() { - if let hir::ParamName::Plain(name) = name { - lifetime_names.insert(name.name); - lifetime_spans.push(name.span); - } - } + in_scope_lifetimes.extend(lifetimes.keys().copied()); scope = s; } Scope::ObjectLifetimeDefault { ref s, .. } @@ -2574,19 +2557,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut err = self.report_missing_lifetime_specifiers(spans.clone(), lifetime_refs.len()); - if let Some(params) = error { - // If there's no lifetime available, suggest `'static`. - if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() { - lifetime_names.insert(kw::StaticLifetime); - } - } - self.add_missing_lifetime_specifiers_label( &mut err, spans_with_counts, - &lifetime_names, - lifetime_spans, - error.unwrap_or(&[]), + in_scope_lifetimes, + error, ); err.emit(); } @@ -2647,8 +2622,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// "Constrained" basically means that it appears in any type but /// not amongst the inputs to a projection. In other words, `<&'a /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`. -#[tracing::instrument(level = "debug", skip(map))] +#[tracing::instrument(level = "debug", skip(tcx, map))] fn insert_late_bound_lifetimes( + tcx: TyCtxt<'_>, map: &mut NamedRegionMap, decl: &hir::FnDecl<'_>, generics: &hir::Generics<'_>, @@ -2683,15 +2659,16 @@ fn insert_late_bound_lifetimes( hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => continue, } - let lt_name = hir::LifetimeName::Param(param.name.normalize_to_macros_2_0()); + let param_def_id = tcx.hir().local_def_id(param.hir_id); + // appears in the where clauses? early-bound. - if appears_in_where_clause.regions.contains(<_name) { + if appears_in_where_clause.regions.contains(¶m_def_id) { continue; } // does not appear in the inputs, but appears in the return type? early-bound. - if !constrained_by_input.regions.contains(<_name) - && appears_in_output.regions.contains(<_name) + if !constrained_by_input.regions.contains(¶m_def_id) + && appears_in_output.regions.contains(¶m_def_id) { continue; } @@ -2706,7 +2683,7 @@ fn insert_late_bound_lifetimes( #[derive(Default)] struct ConstrainedCollector { - regions: FxHashSet, + regions: FxHashSet, } impl<'v> Visitor<'v> for ConstrainedCollector { @@ -2738,18 +2715,22 @@ fn insert_late_bound_lifetimes( } fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { - self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0()); + if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name { + self.regions.insert(def_id); + } } } #[derive(Default)] struct AllCollector { - regions: FxHashSet, + regions: FxHashSet, } impl<'v> Visitor<'v> for AllCollector { fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { - self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0()); + if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name { + self.regions.insert(def_id); + } } } } diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index f1dc3cbbac459..bc3a3db9fdadb 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -514,7 +514,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { param_names .iter() .take(num_params_to_take) - .map(|p| p.as_str()) + .map(|def_id| { + self.tcx.item_name(def_id.to_def_id()).to_ident_string() + }) .collect::>() .join(", ") } else { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c725cf93be2f4..f3070fb35f1d0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -475,24 +475,14 @@ fn clean_generic_param<'tcx>( generics: Option<&hir::Generics<'tcx>>, param: &hir::GenericParam<'tcx>, ) -> GenericParamDef { + let did = cx.tcx.hir().local_def_id(param.hir_id); let (name, kind) = match param.kind { hir::GenericParamKind::Lifetime { .. } => { let outlives = if let Some(generics) = generics { generics - .predicates - .iter() - .flat_map(|pred| { - match pred { - hir::WherePredicate::RegionPredicate(rp) - if rp.lifetime.name == hir::LifetimeName::Param(param.name) - && !rp.in_where_clause => - { - rp.bounds - } - _ => &[], - } - .iter() - }) + .outlives_for_param(did) + .filter(|bp| !bp.in_where_clause) + .flat_map(|bp| bp.bounds) .map(|bound| match bound { hir::GenericBound::Outlives(lt) => lt.clean(cx), _ => panic!(), @@ -504,7 +494,6 @@ fn clean_generic_param<'tcx>( (param.name.ident().name, GenericParamDefKind::Lifetime { outlives }) } hir::GenericParamKind::Type { ref default, synthetic } => { - let did = cx.tcx.hir().local_def_id(param.hir_id); let bounds = if let Some(generics) = generics { generics .bounds_for_param(did) @@ -528,7 +517,7 @@ fn clean_generic_param<'tcx>( hir::GenericParamKind::Const { ty, default } => ( param.name.ident().name, GenericParamDefKind::Const { - did: cx.tcx.hir().local_def_id(param.hir_id).to_def_id(), + did: did.to_def_id(), ty: Box::new(ty.clean(cx)), default: default.map(|ct| { let def_id = cx.tcx.hir().local_def_id(ct.hir_id); @@ -1459,7 +1448,7 @@ impl<'tcx> Clean<'tcx, Type> for hir::Ty<'tcx> { // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though; // there's no case where it could cause the function to fail to compile. let elided = - l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_))); + l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh)); let lifetime = if elided { None } else { Some(l.clean(cx)) }; BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) } } diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 51d5b510ab930..070c7e591420d 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -371,7 +371,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> { if let Some(ref lt) = *lifetime { if lt.name == LifetimeName::Static { self.lts.push(RefLt::Static); - } else if let LifetimeName::Param(ParamName::Fresh(_)) = lt.name { + } else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name { // Fresh lifetimes generated should be ignored. } else if lt.is_elided() { self.lts.push(RefLt::Unnamed); diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 548f7b2528b11..0b96f6ff68358 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -343,7 +343,7 @@ impl fmt::Display for RefPrefix { use fmt::Write; f.write_char('&')?; match self.lt { - LifetimeName::Param(ParamName::Plain(name)) => { + LifetimeName::Param(_, ParamName::Plain(name)) => { name.fmt(f)?; f.write_char(' ')?; }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c440793b90e0e..fc1a4e1f60255 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -902,16 +902,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_lifetime(&mut self, lifetime: Lifetime) { std::mem::discriminant(&lifetime.name).hash(&mut self.s); - if let LifetimeName::Param(ref name) = lifetime.name { + if let LifetimeName::Param(param_id, ref name) = lifetime.name { std::mem::discriminant(name).hash(&mut self.s); + param_id.hash(&mut self.s); match name { ParamName::Plain(ref ident) => { ident.name.hash(&mut self.s); }, - ParamName::Fresh(ref size) => { - size.hash(&mut self.s); - }, - ParamName::Error => {}, + ParamName::Fresh | ParamName::Error => {}, } } } From ba40fe99c3624719e8bf7f324f02ecb0d8cb7849 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 May 2022 08:59:15 +0200 Subject: [PATCH 17/17] Compute `is_late_bound` in a separate query. The computation is actually much simpler, and can be done by directly fetching the HIR for the `FnDecl` and its generics. --- .../rustc_borrowck/src/universal_regions.rs | 4 +- compiler/rustc_middle/src/hir/map/mod.rs | 6 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 7 ++ compiler/rustc_resolve/src/late/lifetimes.rs | 92 +++++-------------- compiler/rustc_typeck/src/collect.rs | 35 ++----- 6 files changed, 47 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 7b63ec516b8c4..c2c093f9f2fc7 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -830,11 +830,11 @@ fn for_each_late_bound_region_defined_on<'tcx>( fn_def_id: DefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) { + if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) { for ®ion_def_id in late_bounds.iter() { let name = tcx.item_name(region_def_id.to_def_id()); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: owner.to_def_id(), + scope: fn_def_id, bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name), })); f(liberated_region); diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 97f429cfd3fa6..2c40eab8764af 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -364,7 +364,11 @@ impl<'hir> Map<'hir> { match node.node { OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics), OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics), - OwnerNode::Item(Item { + OwnerNode::ForeignItem(ForeignItem { + kind: ForeignItemKind::Fn(_, _, generics), + .. + }) + | OwnerNode::Item(Item { kind: ItemKind::Fn(_, generics, _) | ItemKind::TyAlias(_, generics) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 38d8e0b581953..899d6c7e490a6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1584,7 +1584,7 @@ rustc_queries! { Option<&'tcx FxHashMap> { desc { "looking up a named region" } } - query is_late_bound_map(_: LocalDefId) -> Option<(LocalDefId, &'tcx FxHashSet)> { + query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxHashSet> { desc { "testing if a region is late bound" } } /// For a given item (like a struct), gets the default lifetimes to be used diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a0d92e2a5dd94..72e2beb372d3c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2803,6 +2803,13 @@ impl<'tcx> TyCtxt<'tcx> { self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned()) } + pub fn is_late_bound(self, id: HirId) -> bool { + self.is_late_bound_map(id.owner).map_or(false, |set| { + let def_id = self.hir().local_def_id(id); + set.contains(&def_id) + }) + } + pub fn late_bound_vars(self, id: HirId) -> &'tcx List { self.mk_bound_variable_kinds( self.late_bound_vars_map(id.owner) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 6cd81aa7dac13..11f80b314d770 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -16,11 +16,11 @@ use rustc_hir::def_id::{DefIdMap, LocalDefId}; use rustc_hir::hir_id::ItemLocalId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node}; -use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet}; +use rustc_hir::{GenericParamKind, HirIdMap}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::*; -use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; +use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::{kw, sym, Ident}; @@ -134,11 +134,6 @@ struct NamedRegionMap { // `Region` describing how that region is bound defs: HirIdMap, - // the set of lifetime def ids that are late-bound; a region can - // be late-bound if (a) it does NOT appear in a where-clause and - // (b) it DOES appear in the arguments. - late_bound: HirIdSet, - // Maps relevant hir items to the bound vars on them. These include: // - function defs // - function pointers @@ -402,7 +397,7 @@ fn resolve_lifetimes_trait_definition( tcx: TyCtxt<'_>, local_def_id: LocalDefId, ) -> ResolveLifetimes { - convert_named_region_map(tcx, do_resolve(tcx, local_def_id, true, false)) + convert_named_region_map(do_resolve(tcx, local_def_id, true, false)) } /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`. @@ -410,7 +405,7 @@ fn resolve_lifetimes_trait_definition( /// `named_region_map`, `is_late_bound_map`, etc. #[tracing::instrument(level = "debug", skip(tcx))] fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes { - convert_named_region_map(tcx, do_resolve(tcx, local_def_id, false, false)) + convert_named_region_map(do_resolve(tcx, local_def_id, false, false)) } fn do_resolve( @@ -422,7 +417,6 @@ fn do_resolve( let item = tcx.hir().expect_item(local_def_id); let mut named_region_map = NamedRegionMap { defs: Default::default(), - late_bound: Default::default(), late_bound_vars: Default::default(), scope_for_path: with_scope_for_path.then(|| Default::default()), }; @@ -439,18 +433,13 @@ fn do_resolve( named_region_map } -fn convert_named_region_map(tcx: TyCtxt<'_>, named_region_map: NamedRegionMap) -> ResolveLifetimes { +fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes { let mut rl = ResolveLifetimes::default(); for (hir_id, v) in named_region_map.defs { let map = rl.defs.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); } - for hir_id in named_region_map.late_bound { - let map = rl.late_bound.entry(hir_id.owner).or_default(); - let def_id = tcx.hir().local_def_id(hir_id); - map.insert(def_id); - } for (hir_id, v) in named_region_map.late_bound_vars { let map = rl.late_bound_vars.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); @@ -506,28 +495,6 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId { item } -fn is_late_bound_map<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, -) -> Option<(LocalDefId, &'tcx FxHashSet)> { - match tcx.def_kind(def_id) { - DefKind::AnonConst | DefKind::InlineConst => { - let mut def_id = tcx.local_parent(def_id); - // We search for the next outer anon const or fn here - // while skipping closures. - // - // Note that for `AnonConst` we still just recurse until we - // find a function body, but who cares :shrug: - while tcx.is_closure(def_id.to_def_id()) { - def_id = tcx.local_parent(def_id); - } - - tcx.is_late_bound_map(def_id) - } - _ => resolve_lifetimes_for(tcx, def_id).late_bound.get(&def_id).map(|lt| (def_id, lt)), - } -} - /// In traits, there is an implicit `Self` type parameter which comes before the generics. /// We have to account for this when computing the index of the other generic parameters. /// This function returns whether there is such an implicit parameter defined on the given item. @@ -687,9 +654,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { _ => {} } match item.kind { - hir::ItemKind::Fn(ref sig, ref generics, _) => { + hir::ItemKind::Fn(_, ref generics, _) => { self.missing_named_lifetime_spots.push(generics.into()); - self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| { + self.visit_early_late(None, item.hir_id(), generics, |this| { intravisit::walk_item(this, item); }); self.missing_named_lifetime_spots.pop(); @@ -731,13 +698,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.map.defs.insert(hir::HirId { owner, local_id }, *region); }); } - for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() { - late_bound.iter().for_each(|&id| { - let hir_id = self.tcx.local_def_id_to_hir_id(id); - debug_assert_eq!(owner, hir_id.owner); - self.map.late_bound.insert(hir_id); - }); - } for (&owner, late_bound_vars) in resolved_lifetimes.late_bound_vars.iter() { @@ -807,8 +767,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { - hir::ForeignItemKind::Fn(ref decl, _, ref generics) => { - self.visit_early_late(None, item.hir_id(), decl, generics, |this| { + hir::ForeignItemKind::Fn(_, _, ref generics) => { + self.visit_early_late(None, item.hir_id(), generics, |this| { intravisit::walk_foreign_item(this, item); }) } @@ -1085,13 +1045,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { use self::hir::TraitItemKind::*; match trait_item.kind { - Fn(ref sig, _) => { + Fn(_, _) => { self.missing_named_lifetime_spots.push((&trait_item.generics).into()); let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(trait_item.hir_id())), trait_item.hir_id(), - &sig.decl, &trait_item.generics, |this| intravisit::walk_trait_item(this, trait_item), ); @@ -1153,13 +1112,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { use self::hir::ImplItemKind::*; match impl_item.kind { - Fn(ref sig, _) => { + Fn(..) => { self.missing_named_lifetime_spots.push((&impl_item.generics).into()); let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(impl_item.hir_id())), impl_item.hir_id(), - &sig.decl, &impl_item.generics, |this| intravisit::walk_impl_item(this, impl_item), ); @@ -1656,14 +1614,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { &mut self, parent_id: Option, hir_id: hir::HirId, - decl: &'tcx hir::FnDecl<'tcx>, generics: &'tcx hir::Generics<'tcx>, walk: F, ) where F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>), { - insert_late_bound_lifetimes(self.tcx, self.map, decl, generics); - // Find the start of nested early scopes, e.g., in methods. let mut next_early_index = 0; if let Some(parent_id) = parent_id { @@ -1687,7 +1642,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - if self.map.late_bound.contains(¶m.hir_id) { + if self.tcx.is_late_bound(param.hir_id) { let late_bound_idx = named_late_bound_vars; named_late_bound_vars += 1; Some(Region::late(late_bound_idx, self.tcx.hir(), param)) @@ -1708,7 +1663,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .iter() .filter(|param| { matches!(param.kind, GenericParamKind::Lifetime { .. }) - && self.map.late_bound.contains(¶m.hir_id) + && self.tcx.is_late_bound(param.hir_id) }) .enumerate() .map(|(late_bound_idx, param)| { @@ -2613,7 +2568,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } /// Detects late-bound lifetimes and inserts them into -/// `map.late_bound`. +/// `late_bound`. /// /// A region declared on a fn is **late-bound** if: /// - it is constrained by an argument type; @@ -2622,13 +2577,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// "Constrained" basically means that it appears in any type but /// not amongst the inputs to a projection. In other words, `<&'a /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`. -#[tracing::instrument(level = "debug", skip(tcx, map))] -fn insert_late_bound_lifetimes( - tcx: TyCtxt<'_>, - map: &mut NamedRegionMap, - decl: &hir::FnDecl<'_>, - generics: &hir::Generics<'_>, -) { +fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxHashSet> { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?; + let generics = tcx.hir().get_generics(def_id)?; + + let mut late_bound = FxHashSet::default(); + let mut constrained_by_input = ConstrainedCollector::default(); for arg_ty in decl.inputs { constrained_by_input.visit_ty(arg_ty); @@ -2675,11 +2630,12 @@ fn insert_late_bound_lifetimes( debug!("lifetime {:?} with id {:?} is late-bound", param.name.ident(), param.hir_id); - let inserted = map.late_bound.insert(param.hir_id); + let inserted = late_bound.insert(param_def_id); assert!(inserted, "visited lifetime {:?} twice", param.hir_id); } - return; + debug!(?late_bound); + return Some(tcx.arena.alloc(late_bound)); #[derive(Default)] struct ConstrainedCollector { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 4322440d6856b..34d107349e7c7 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1364,7 +1364,6 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, generics: &'tcx hir::Generics<'tcx>, decl: &'tcx hir::FnDecl<'tcx>, ) -> Option { @@ -1373,14 +1372,9 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option match item.kind { hir::TraitItemKind::Fn(ref sig, _) => { - has_late_bound_regions(tcx, item.def_id, &item.generics, sig.decl) + has_late_bound_regions(tcx, &item.generics, sig.decl) } _ => None, }, Node::ImplItem(item) => match item.kind { hir::ImplItemKind::Fn(ref sig, _) => { - has_late_bound_regions(tcx, item.def_id, &item.generics, sig.decl) + has_late_bound_regions(tcx, &item.generics, sig.decl) } _ => None, }, Node::ForeignItem(item) => match item.kind { hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => { - has_late_bound_regions(tcx, item.def_id, generics, fn_decl) + has_late_bound_regions(tcx, generics, fn_decl) } _ => None, }, Node::Item(item) => match item.kind { hir::ItemKind::Fn(ref sig, .., ref generics, _) => { - has_late_bound_regions(tcx, item.def_id, generics, sig.decl) + has_late_bound_regions(tcx, generics, sig.decl) } _ => None, }, @@ -1671,7 +1665,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { params.push(opt_self); } - let early_lifetimes = early_bound_lifetimes_from_generics(tcx, hir_id.owner, ast_generics); + let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef { name: param.name.ident().name, index: own_start + i as u32, @@ -2054,23 +2048,10 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity { /// `resolve_lifetime::early_bound_lifetimes`. fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, generics: &'a hir::Generics<'a>, ) -> impl Iterator> + Captures<'tcx> { - let late_bound_map = if generics.params.is_empty() { - // This function may be called on `def_id == CRATE_DEF_ID`, - // which makes `is_late_bound_map` ICE. Don't even try if there - // is no generic parameter. - None - } else { - tcx.is_late_bound_map(def_id) - }; - let is_late_bound = move |hir_id| { - let id = tcx.hir().local_def_id(hir_id); - late_bound_map.map_or(false, |(_, set)| set.contains(&id)) - }; generics.params.iter().filter(move |param| match param.kind { - GenericParamKind::Lifetime { .. } => !is_late_bound(param.hir_id), + GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id), _ => false, }) } @@ -2255,7 +2236,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // have to be careful to only iterate over early-bound regions. let mut index = parent_count + has_own_self as u32 - + early_bound_lifetimes_from_generics(tcx, hir_id.owner, ast_generics).count() as u32; + + early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32; // Collect the predicates that were written inline by the user on each // type parameter (e.g., ``).