diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2022-07-14 15:09:30 +0200 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2022-08-23 00:08:42 +0200 |
| commit | 613dc2204dc628e6804b9d2be8bdeb6f6f43611e (patch) | |
| tree | 0f519991909524a2d658f38bb30cc104b51ba9cf | |
| parent | d7d701a9dc6c424e01d49d937925dc3bf7718138 (diff) | |
| download | rust-613dc2204dc628e6804b9d2be8bdeb6f6f43611e.tar.gz rust-613dc2204dc628e6804b9d2be8bdeb6f6f43611e.zip | |
Improve local generic parameter suggestions.
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 33 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/ident.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/const-generics/early/const-param-from-outer-fn.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0401.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/generics/issue-98432.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-3214.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-5997-enum.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-5997-struct.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/nested-ty-params.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/resolve/bad-type-env-capture.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/resolve/issue-3021-c.stderr | 16 | ||||
| -rw-r--r-- | src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/type/type-arg-out-of-scope.stderr | 12 |
16 files changed, 90 insertions, 81 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 193610ff57d..fc198350198 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -511,7 +511,7 @@ impl<'a> Resolver<'a> { err.span_label(span, "use of generic parameter from outer function"); let sm = self.session.source_map(); - match outer_res { + let def_id = match outer_res { Res::SelfTy { trait_: maybe_trait_defid, alias_to: maybe_impl_defid } => { if let Some(impl_span) = maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id)) @@ -536,11 +536,13 @@ impl<'a> Resolver<'a> { if let Some(span) = self.opt_span(def_id) { err.span_label(span, "type parameter from outer function"); } + def_id } Res::Def(DefKind::ConstParam, def_id) => { if let Some(span) = self.opt_span(def_id) { err.span_label(span, "const parameter from outer function"); } + def_id } _ => { bug!( @@ -548,28 +550,23 @@ impl<'a> Resolver<'a> { DefKind::TyParam or DefKind::ConstParam" ); } - } + }; - if let HasGenericParams::Yes = has_generic_params { + if let HasGenericParams::Yes(span) = has_generic_params { // Try to retrieve the span of the function signature and generate a new // message with a local type or const parameter. let sugg_msg = "try using a local generic parameter instead"; - if let Some((sugg_span, snippet)) = sm.generate_local_type_param_snippet(span) { - // Suggest the modification to the user - err.span_suggestion( - sugg_span, - sugg_msg, - snippet, - Applicability::MachineApplicable, - ); - } else if let Some(sp) = sm.generate_fn_name_span(span) { - err.span_label( - sp, - "try adding a local generic parameter in this method instead", - ); + let name = self.opt_name(def_id).unwrap_or(sym::T); + let (span, snippet) = if span.is_empty() { + let snippet = format!("<{}>", name); + (span, snippet) } else { - err.help("try using a local generic parameter instead"); - } + let span = sm.span_through_char(span, '<').shrink_to_hi(); + let snippet = format!("{}, ", name); + (span, snippet) + }; + // Suggest the modification to the user + err.span_suggestion(span, sugg_msg, snippet, Applicability::MachineApplicable); } err diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index be50eecf4b1..0d8f1cf3656 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1170,10 +1170,11 @@ impl<'a> Resolver<'a> { let has_generic_params: HasGenericParams = match rib.kind { NormalRibKind | ClosureOrAsyncRibKind - | AssocItemRibKind | ModuleRibKind(..) | MacroDefinition(..) | InlineAsmSymRibKind + | FnItemRibKind + | AssocItemRibKind | ForwardGenericParamBanRibKind => { // Nothing to do. Continue. continue; @@ -1211,7 +1212,6 @@ impl<'a> Resolver<'a> { // This was an attempt to use a type parameter outside its scope. ItemRibKind(has_generic_params) => has_generic_params, - FnItemRibKind => HasGenericParams::Yes, ConstParamTyRibKind => { if let Some(span) = finalize { self.report_error( @@ -1248,10 +1248,11 @@ impl<'a> Resolver<'a> { let has_generic_params = match rib.kind { NormalRibKind | ClosureOrAsyncRibKind - | AssocItemRibKind | ModuleRibKind(..) | MacroDefinition(..) | InlineAsmSymRibKind + | FnItemRibKind + | AssocItemRibKind | ForwardGenericParamBanRibKind => continue, ConstantItemRibKind(trivial, _) => { @@ -1278,7 +1279,6 @@ impl<'a> Resolver<'a> { } ItemRibKind(has_generic_params) => has_generic_params, - FnItemRibKind => HasGenericParams::Yes, ConstParamTyRibKind => { if let Some(span) = finalize { self.report_error( diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b6fedd838bb..748a0781c4f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -93,7 +93,7 @@ enum PatBoundCtx { /// Does this the item (from the item rib scope) allow generic parameters? #[derive(Copy, Clone, Debug)] pub(crate) enum HasGenericParams { - Yes, + Yes(Span), No, } @@ -758,7 +758,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { self.with_lifetime_rib(LifetimeRibKind::Item, |this| { this.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: foreign_item.id, kind: LifetimeBinderKind::Item, @@ -772,7 +772,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { self.with_lifetime_rib(LifetimeRibKind::Item, |this| { this.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: foreign_item.id, kind: LifetimeBinderKind::Function, @@ -2078,7 +2078,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_current_self_item(item, |this| { this.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2148,7 +2148,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ItemKind::TyAlias(box TyAlias { ref generics, .. }) => { self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2161,7 +2161,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ItemKind::Fn(box Fn { ref generics, .. }) => { self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Function, @@ -2193,7 +2193,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2217,7 +2217,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2605,7 +2605,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // If applicable, create a rib for the type parameters. self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes), + ItemRibKind(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { span: generics.span, binder: item_id, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9c213da8c2a..eb727debc91 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1945,6 +1945,16 @@ impl<'a> Resolver<'a> { def_id.as_local().map(|def_id| self.source_span[def_id]) } + /// Retrieves the name of the given `DefId`. + #[inline] + pub fn opt_name(&self, def_id: DefId) -> Option<Symbol> { + let def_key = match def_id.as_local() { + Some(def_id) => self.definitions.def_key(def_id), + None => self.cstore().def_key(def_id), + }; + def_key.get_opt_name() + } + /// Checks if an expression refers to a function marked with /// `#[rustc_legacy_const_generics]` and returns the argument index list /// from the attribute. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 156f53ac486..c8978845ffb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -280,6 +280,7 @@ symbols! { StructuralPartialEq, SubdiagnosticMessage, Sync, + T, Target, ToOwned, ToString, diff --git a/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr b/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr index a9f9787d875..e3bf38b702e 100644 --- a/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr +++ b/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr @@ -4,7 +4,7 @@ error[E0401]: can't use generic parameters from outer function LL | fn foo<const X: u32>() { | - const parameter from outer function LL | fn bar() -> u32 { - | --- try adding a local generic parameter in this method instead + | - help: try using a local generic parameter instead: `<X>` LL | X | ^ use of generic parameter from outer function diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 81715621dd9..b0e2ef5b6f7 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function LL | fn foo<T>(x: T) { | - type parameter from outer function LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) { - | --------------------------- ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `T,` error[E0401]: can't use generic parameters from outer function --> $DIR/E0401.rs:9:16 @@ -15,7 +15,7 @@ LL | fn foo<T>(x: T) { | - type parameter from outer function ... LL | fn baz<U, - | --- try adding a local generic parameter in this method instead + | - help: try using a local generic parameter instead: `T,` ... LL | (y: T) { | ^ use of generic parameter from outer function diff --git a/src/test/ui/generics/issue-98432.stderr b/src/test/ui/generics/issue-98432.stderr index afa67b63bd9..c7b5c33618d 100644 --- a/src/test/ui/generics/issue-98432.stderr +++ b/src/test/ui/generics/issue-98432.stderr @@ -5,9 +5,9 @@ LL | impl<T> Struct<T> { | - type parameter from outer function LL | const CONST: fn() = || { LL | struct _Obligation where T:; - | ^ use of generic parameter from outer function - | - = help: try using a local generic parameter instead + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<T>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr index 4d8eb6360e6..aa0b5ce64b4 100644 --- a/src/test/ui/issues/issue-3214.stderr +++ b/src/test/ui/issues/issue-3214.stderr @@ -2,10 +2,9 @@ error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3214.rs:3:12 | LL | fn foo<T>() { - | --- - type parameter from outer function - | | - | try adding a local generic parameter in this method instead + | - type parameter from outer function LL | struct Foo { + | - help: try using a local generic parameter instead: `<T>` LL | x: T, | ^ use of generic parameter from outer function diff --git a/src/test/ui/issues/issue-5997-enum.stderr b/src/test/ui/issues/issue-5997-enum.stderr index 1c58b9c3911..3a79215d3ae 100644 --- a/src/test/ui/issues/issue-5997-enum.stderr +++ b/src/test/ui/issues/issue-5997-enum.stderr @@ -2,11 +2,11 @@ error[E0401]: can't use generic parameters from outer function --> $DIR/issue-5997-enum.rs:2:16 | LL | fn f<Z>() -> bool { - | - - type parameter from outer function - | | - | try adding a local generic parameter in this method instead + | - type parameter from outer function LL | enum E { V(Z) } - | ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<Z>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-5997-struct.stderr b/src/test/ui/issues/issue-5997-struct.stderr index 5b388d16d75..d2e97f76771 100644 --- a/src/test/ui/issues/issue-5997-struct.stderr +++ b/src/test/ui/issues/issue-5997-struct.stderr @@ -2,11 +2,11 @@ error[E0401]: can't use generic parameters from outer function --> $DIR/issue-5997-struct.rs:2:14 | LL | fn f<T>() -> bool { - | - - type parameter from outer function - | | - | try adding a local generic parameter in this method instead + | - type parameter from outer function LL | struct S(T); - | ^ use of generic parameter from outer function + | -^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<T>` error: aborting due to previous error diff --git a/src/test/ui/nested-ty-params.stderr b/src/test/ui/nested-ty-params.stderr index f6741b5e5e8..8f4746f5ec3 100644 --- a/src/test/ui/nested-ty-params.stderr +++ b/src/test/ui/nested-ty-params.stderr @@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function LL | fn hd<U>(v: Vec<U> ) -> U { | - type parameter from outer function LL | fn hd1(w: [U]) -> U { return w[0]; } - | --- ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `hd1<U>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<U>` error[E0401]: can't use generic parameters from outer function --> $DIR/nested-ty-params.rs:3:23 @@ -14,9 +14,9 @@ error[E0401]: can't use generic parameters from outer function LL | fn hd<U>(v: Vec<U> ) -> U { | - type parameter from outer function LL | fn hd1(w: [U]) -> U { return w[0]; } - | --- ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `hd1<U>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<U>` error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/bad-type-env-capture.stderr b/src/test/ui/resolve/bad-type-env-capture.stderr index 6f24c0d8699..b6282c2d070 100644 --- a/src/test/ui/resolve/bad-type-env-capture.stderr +++ b/src/test/ui/resolve/bad-type-env-capture.stderr @@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function LL | fn foo<T>() { | - type parameter from outer function LL | fn bar(b: T) { } - | --- ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `bar<T>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<T>` error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-3021-c.stderr b/src/test/ui/resolve/issue-3021-c.stderr index 8764ac8a856..5176efc3a6b 100644 --- a/src/test/ui/resolve/issue-3021-c.stderr +++ b/src/test/ui/resolve/issue-3021-c.stderr @@ -3,22 +3,22 @@ error[E0401]: can't use generic parameters from outer function | LL | fn siphash<T>() { | - type parameter from outer function -... +LL | +LL | trait U { + | - help: try using a local generic parameter instead: `<T>` LL | fn g(&self, x: T) -> T; - | - ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `g<T>` + | ^ use of generic parameter from outer function error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3021-c.rs:4:30 | LL | fn siphash<T>() { | - type parameter from outer function -... +LL | +LL | trait U { + | - help: try using a local generic parameter instead: `<T>` LL | fn g(&self, x: T) -> T; - | - ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `g<T>` + | ^ use of generic parameter from outer function error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 10a703ee093..0a6d1cc3bcd 100644 --- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -4,8 +4,8 @@ error[E0401]: can't use generic parameters from outer function LL | trait TraitA<A> { | - type parameter from outer function LL | fn outer(&self) { - | ----- try adding a local generic parameter in this method instead LL | enum Foo<B> { + | - help: try using a local generic parameter instead: `A,` LL | Variance(A) | ^ use of generic parameter from outer function @@ -15,9 +15,10 @@ error[E0401]: can't use generic parameters from outer function LL | trait TraitB<A> { | - type parameter from outer function LL | fn outer(&self) { - | ----- try adding a local generic parameter in this method instead LL | struct Foo<B>(A); - | ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `A,` error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 @@ -25,9 +26,10 @@ error[E0401]: can't use generic parameters from outer function LL | trait TraitC<A> { | - type parameter from outer function LL | fn outer(&self) { - | ----- try adding a local generic parameter in this method instead LL | struct Foo<B> { a: A } - | ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `A,` error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 @@ -36,9 +38,9 @@ LL | trait TraitD<A> { | - type parameter from outer function LL | fn outer(&self) { LL | fn foo<B>(a: A) { } - | ------ ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `foo<B, A>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `A,` error: aborting due to 4 previous errors diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr index 0b6283fbc51..7f18b4510f4 100644 --- a/src/test/ui/type/type-arg-out-of-scope.stderr +++ b/src/test/ui/type/type-arg-out-of-scope.stderr @@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function LL | fn foo<T>(x: T) { | - type parameter from outer function LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } - | --- ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `bar<T>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<T>` error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:35 @@ -14,9 +14,9 @@ error[E0401]: can't use generic parameters from outer function LL | fn foo<T>(x: T) { | - type parameter from outer function LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } - | --- ^ use of generic parameter from outer function - | | - | help: try using a local generic parameter instead: `bar<T>` + | - ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `<T>` error: aborting due to 2 previous errors |
