1
Fork 0

Rollup merge of #115744 - fmease:fix-e0401, r=compiler-errors

Improve diagnostic for generic params from outer items (E0401)

Generalize the wording of E0401 to talk about *outer items* instead of *outer functions* since the current phrasing is outdated. The outer item can be a function, constant, trait, ADT or impl block (see the new UI test for the more exotic examples).

Further, don't suggest introducing generic parameters to constant items unless the feature `generic_const_items` is enabled.

Lastly, make E0401 translatable while we're at it.

Fixes #115720.
This commit is contained in:
Matthias Krüger 2023-09-11 17:03:32 +02:00 committed by GitHub
commit 8b49731211
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 306 additions and 183 deletions

View file

@ -1,4 +1,4 @@
Inner items do not inherit type or const parameters from the functions Inner items do not inherit the generic parameters from the items
they are embedded in. they are embedded in.
Erroneous code example: Erroneous code example:
@ -32,8 +32,8 @@ fn foo<T>(x: T) {
} }
``` ```
Items inside functions are basically just like top-level items, except Items nested inside other items are basically just like top-level items, except
that they can only be used from the function they are in. that they can only be used from the item they are in.
There are a couple of solutions for this. There are a couple of solutions for this.

View file

@ -68,9 +68,6 @@ resolve_cannot_find_ident_in_this_scope =
resolve_cannot_glob_import_possible_crates = resolve_cannot_glob_import_possible_crates =
cannot glob-import all possible crates cannot glob-import all possible crates
resolve_cannot_use_self_type_here =
can't use `Self` here
resolve_change_import_binding = resolve_change_import_binding =
you can use `as` to change the binding name of the import you can use `as` to change the binding name of the import
@ -90,9 +87,6 @@ resolve_const_not_member_of_trait =
const `{$const_}` is not a member of trait `{$trait_}` const `{$const_}` is not a member of trait `{$trait_}`
.label = not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}`
resolve_const_param_from_outer_fn =
const parameter from outer function
resolve_const_param_in_enum_discriminant = resolve_const_param_in_enum_discriminant =
const parameters may not be used in enum discriminant values const parameters may not be used in enum discriminant values
@ -119,10 +113,19 @@ resolve_forward_declared_generic_param =
generic parameters with a default cannot use forward declared identifiers generic parameters with a default cannot use forward declared identifiers
.label = defaulted generic parameters cannot be forward declared .label = defaulted generic parameters cannot be forward declared
resolve_generic_params_from_outer_function = resolve_generic_params_from_outer_item =
can't use generic parameters from outer function can't use generic parameters from outer item
.label = use of generic parameter from outer function .label = use of generic parameter from outer item
.suggestion = try using a local generic parameter instead .refer_to_type_directly = refer to the type directly here instead
.suggestion = try introducing a local generic parameter here
resolve_generic_params_from_outer_item_const_param = const parameter from outer item
resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl`
resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here
resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
resolve_glob_import_doesnt_reexport = resolve_glob_import_doesnt_reexport =
glob import doesn't reexport anything because no candidate is public enough glob import doesn't reexport anything because no candidate is public enough
@ -277,9 +280,6 @@ resolve_type_not_member_of_trait =
type `{$type_}` is not a member of trait `{$trait_}` type `{$type_}` is not a member of trait `{$trait_}`
.label = not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}`
resolve_type_param_from_outer_fn =
type parameter from outer function
resolve_type_param_in_enum_discriminant = resolve_type_param_in_enum_discriminant =
type parameters may not be used in enum discriminant values type parameters may not be used in enum discriminant values
@ -315,9 +315,6 @@ resolve_unreachable_label_suggestion_use_similarly_named =
resolve_unreachable_label_with_similar_name_exists = resolve_unreachable_label_with_similar_name_exists =
a label with a similar name exists but is unreachable a label with a similar name exists but is unreachable
resolve_use_a_type_here_instead =
use a type here instead
resolve_variable_bound_with_different_mode = resolve_variable_bound_with_different_mode =
variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` variable `{$variable_name}` is bound inconsistently across alternatives separated by `|`
.label = bound in different ways .label = bound in different ways

View file

@ -553,43 +553,40 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
resolution_error: ResolutionError<'a>, resolution_error: ResolutionError<'a>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
match resolution_error { match resolution_error {
ResolutionError::GenericParamsFromOuterFunction(outer_res, has_generic_params) => { ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => {
let mut err = struct_span_err!( use errs::GenericParamsFromOuterItemLabel as Label;
self.tcx.sess, let mut err = errs::GenericParamsFromOuterItem {
span, span,
E0401, label: None,
"can't use generic parameters from outer function", refer_to_type_directly: None,
); sugg: None,
err.span_label(span, "use of generic parameter from outer function"); };
let sm = self.tcx.sess.source_map(); let sm = self.tcx.sess.source_map();
let def_id = match outer_res { let def_id = match outer_res {
Res::SelfTyParam { .. } => { Res::SelfTyParam { .. } => {
err.span_label(span, "can't use `Self` here"); err.label = Some(Label::SelfTyParam(span));
return err; return self.tcx.sess.create_err(err);
} }
Res::SelfTyAlias { alias_to: def_id, .. } => { Res::SelfTyAlias { alias_to: def_id, .. } => {
err.span_label( err.label = Some(Label::SelfTyAlias(reduce_impl_span_to_impl_keyword(
reduce_impl_span_to_impl_keyword(sm, self.def_span(def_id)), sm,
"`Self` type implicitly declared here, by this `impl`", self.def_span(def_id),
); )));
err.span_label(span, "use a type here instead"); err.refer_to_type_directly = Some(span);
return err; return self.tcx.sess.create_err(err);
} }
Res::Def(DefKind::TyParam, def_id) => { Res::Def(DefKind::TyParam, def_id) => {
err.span_label(self.def_span(def_id), "type parameter from outer function"); err.label = Some(Label::TyParam(self.def_span(def_id)));
def_id def_id
} }
Res::Def(DefKind::ConstParam, def_id) => { Res::Def(DefKind::ConstParam, def_id) => {
err.span_label( err.label = Some(Label::ConstParam(self.def_span(def_id)));
self.def_span(def_id),
"const parameter from outer function",
);
def_id def_id
} }
_ => { _ => {
bug!( bug!(
"GenericParamsFromOuterFunction should only be used with \ "GenericParamsFromOuterItem should only be used with \
Res::SelfTyParam, Res::SelfTyAlias, DefKind::TyParam or \ Res::SelfTyParam, Res::SelfTyAlias, DefKind::TyParam or \
DefKind::ConstParam" DefKind::ConstParam"
); );
@ -597,9 +594,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}; };
if let HasGenericParams::Yes(span) = 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";
let name = self.tcx.item_name(def_id); let name = self.tcx.item_name(def_id);
let (span, snippet) = if span.is_empty() { let (span, snippet) = if span.is_empty() {
let snippet = format!("<{name}>"); let snippet = format!("<{name}>");
@ -609,11 +603,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let snippet = format!("{name}, "); let snippet = format!("{name}, ");
(span, snippet) (span, snippet)
}; };
// Suggest the modification to the user err.sugg = Some(errs::GenericParamsFromOuterItemSugg { span, snippet });
err.span_suggestion(span, sugg_msg, snippet, Applicability::MaybeIncorrect);
} }
err self.tcx.sess.create_err(err)
} }
ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self
.tcx .tcx

View file

@ -32,6 +32,40 @@ pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate)
#[diag(resolve_crate_root_imports_must_be_named_explicitly)] #[diag(resolve_crate_root_imports_must_be_named_explicitly)]
pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span); pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span);
#[derive(Diagnostic)]
#[diag(resolve_generic_params_from_outer_item, code = "E0401")]
pub(crate) struct GenericParamsFromOuterItem {
#[primary_span]
#[label]
pub(crate) span: Span,
#[subdiagnostic]
pub(crate) label: Option<GenericParamsFromOuterItemLabel>,
#[label(resolve_refer_to_type_directly)]
pub(crate) refer_to_type_directly: Option<Span>,
#[subdiagnostic]
pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>,
}
#[derive(Subdiagnostic)]
pub(crate) enum GenericParamsFromOuterItemLabel {
#[label(resolve_generic_params_from_outer_item_self_ty_param)]
SelfTyParam(#[primary_span] Span),
#[label(resolve_generic_params_from_outer_item_self_ty_alias)]
SelfTyAlias(#[primary_span] Span),
#[label(resolve_generic_params_from_outer_item_ty_param)]
TyParam(#[primary_span] Span),
#[label(resolve_generic_params_from_outer_item_const_param)]
ConstParam(#[primary_span] Span),
}
#[derive(Subdiagnostic)]
#[suggestion(resolve_suggestion, code = "{snippet}", applicability = "maybe-incorrect")]
pub(crate) struct GenericParamsFromOuterItemSugg {
#[primary_span]
pub(crate) span: Span,
pub(crate) snippet: String,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")] #[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")]
pub(crate) struct NameAlreadyUsedInParameterList { pub(crate) struct NameAlreadyUsedInParameterList {

View file

@ -1229,10 +1229,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize { if let Some(span) = finalize {
self.report_error( self.report_error(
span, span,
ResolutionError::GenericParamsFromOuterFunction( ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
res,
has_generic_params,
),
); );
} }
return Res::Err; return Res::Err;
@ -1296,10 +1293,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize { if let Some(span) = finalize {
self.report_error( self.report_error(
span, span,
ResolutionError::GenericParamsFromOuterFunction( ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
res,
has_generic_params,
),
); );
} }
return Res::Err; return Res::Err;

View file

@ -2450,7 +2450,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => { ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
self.with_generic_param_rib( self.with_generic_param_rib(
&generics.params, &generics.params,
RibKind::Item(HasGenericParams::Yes(generics.span)), RibKind::Item(if self.r.tcx.features().generic_const_items {
HasGenericParams::Yes(generics.span)
} else {
HasGenericParams::No
}),
LifetimeRibKind::Generics { LifetimeRibKind::Generics {
binder: item.id, binder: item.id,
kind: LifetimeBinderKind::ConstItem, kind: LifetimeBinderKind::ConstItem,

View file

@ -186,8 +186,8 @@ struct BindingError {
#[derive(Debug)] #[derive(Debug)]
enum ResolutionError<'a> { enum ResolutionError<'a> {
/// Error E0401: can't use type or const parameters from outer function. /// Error E0401: can't use type or const parameters from outer item.
GenericParamsFromOuterFunction(Res, HasGenericParams), GenericParamsFromOuterItem(Res, HasGenericParams),
/// Error E0403: the name is already used for a type or const parameter in this generic /// Error E0403: the name is already used for a type or const parameter in this generic
/// parameter list. /// parameter list.
NameAlreadyUsedInParameterList(Symbol, Span), NameAlreadyUsedInParameterList(Symbol, Span),

View file

@ -1,6 +1,6 @@
fn foo<const X: u32>() { fn foo<const X: u32>() {
fn bar() -> u32 { fn bar() -> u32 {
X //~ ERROR can't use generic parameters from outer function X //~ ERROR can't use generic parameters from outer item
} }
} }

View file

@ -1,12 +1,12 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/const-param-from-outer-fn.rs:3:9 --> $DIR/const-param-from-outer-fn.rs:3:9
| |
LL | fn foo<const X: u32>() { LL | fn foo<const X: u32>() {
| - const parameter from outer function | - const parameter from outer item
LL | fn bar() -> u32 { LL | fn bar() -> u32 {
| - help: try using a local generic parameter instead: `<X>` | - help: try introducing a local generic parameter here: `<X>`
LL | X LL | X
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,26 +1,26 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/E0401.rs:4:39 --> $DIR/E0401.rs:4:39
| |
LL | fn foo<T>(x: T) { LL | fn foo<T>(x: T) {
| - type parameter from outer function | - type parameter from outer item
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) { LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `T,` | help: try introducing a local generic parameter here: `T,`
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/E0401.rs:9:16 --> $DIR/E0401.rs:9:16
| |
LL | fn foo<T>(x: T) { LL | fn foo<T>(x: T) {
| - type parameter from outer function | - type parameter from outer item
... ...
LL | fn baz<U, LL | fn baz<U,
| - help: try using a local generic parameter instead: `T,` | - help: try introducing a local generic parameter here: `T,`
... ...
LL | (y: T) { LL | (y: T) {
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/E0401.rs:24:25 --> $DIR/E0401.rs:24:25
| |
LL | impl<T> Iterator for A<T> { LL | impl<T> Iterator for A<T> {
@ -29,8 +29,8 @@ LL | impl<T> Iterator for A<T> {
LL | fn helper(sel: &Self) -> u8 { LL | fn helper(sel: &Self) -> u8 {
| ^^^^ | ^^^^
| | | |
| use of generic parameter from outer function | use of generic parameter from outer item
| use a type here instead | refer to the type directly here instead
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/E0401.rs:11:5 --> $DIR/E0401.rs:11:5

View file

@ -4,7 +4,7 @@
fn<EFBFBD>a<e>(){fn<EFBFBD>p(){e}} //~ ERROR unknown start of token: \u{fffd} fn<EFBFBD>a<e>(){fn<EFBFBD>p(){e}} //~ ERROR unknown start of token: \u{fffd}
//~^ ERROR unknown start of token: \u{fffd} //~^ ERROR unknown start of token: \u{fffd}
//~^^ ERROR can't use generic parameters from outer function [E0401] //~^^ ERROR can't use generic parameters from outer item [E0401]
//~^^^ WARN type parameter `e` should have an upper camel case name //~^^^ WARN type parameter `e` should have an upper camel case name
fn main(){} fn main(){}

View file

@ -2,7 +2,7 @@ struct Struct<T>(T);
impl<T> Struct<T> { impl<T> Struct<T> {
const CONST: fn() = || { const CONST: fn() = || {
struct _Obligation where T:; //~ ERROR can't use generic parameters from outer function struct _Obligation where T:; //~ ERROR can't use generic parameters from outer item
}; };
} }

View file

@ -1,13 +1,13 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-98432.rs:5:34 --> $DIR/issue-98432.rs:5:34
| |
LL | impl<T> Struct<T> { LL | impl<T> Struct<T> {
| - type parameter from outer function | - type parameter from outer item
LL | const CONST: fn() = || { LL | const CONST: fn() = || {
LL | struct _Obligation where T:; LL | struct _Obligation where T:;
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<T>` | help: try introducing a local generic parameter here: `<T>`
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,7 @@ enum Bar<T> { What } //~ ERROR parameter `T` is never used
fn foo<T>() { fn foo<T>() {
static a: Bar<T> = Bar::What; static a: Bar<T> = Bar::What;
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
fn main() { fn main() {

View file

@ -1,10 +1,10 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/inner-static-type-parameter.rs:6:19 --> $DIR/inner-static-type-parameter.rs:6:19
| |
LL | fn foo<T>() { LL | fn foo<T>() {
| - type parameter from outer function | - type parameter from outer item
LL | static a: Bar<T> = Bar::What; LL | static a: Bar<T> = Bar::What;
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0392]: parameter `T` is never used error[E0392]: parameter `T` is never used
--> $DIR/inner-static-type-parameter.rs:3:10 --> $DIR/inner-static-type-parameter.rs:3:10

View file

@ -1,6 +1,6 @@
fn foo<T>() { fn foo<T>() {
struct Foo { struct Foo {
x: T, //~ ERROR can't use generic parameters from outer function x: T, //~ ERROR can't use generic parameters from outer item
} }
impl<T> Drop for Foo<T> { impl<T> Drop for Foo<T> {

View file

@ -1,12 +1,12 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-3214.rs:3:12 --> $DIR/issue-3214.rs:3:12
| |
LL | fn foo<T>() { LL | fn foo<T>() {
| - type parameter from outer function | - type parameter from outer item
LL | struct Foo { LL | struct Foo {
| - help: try using a local generic parameter instead: `<T>` | - help: try introducing a local generic parameter here: `<T>`
LL | x: T, LL | x: T,
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-3214.rs:6:22 --> $DIR/issue-3214.rs:6:22

View file

@ -1,6 +1,6 @@
fn f<Z>() -> bool { fn f<Z>() -> bool {
enum E { V(Z) } enum E { V(Z) }
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
true true
} }

View file

@ -1,12 +1,12 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-5997-enum.rs:2:16 --> $DIR/issue-5997-enum.rs:2:16
| |
LL | fn f<Z>() -> bool { LL | fn f<Z>() -> bool {
| - type parameter from outer function | - type parameter from outer item
LL | enum E { V(Z) } LL | enum E { V(Z) }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<Z>` | help: try introducing a local generic parameter here: `<Z>`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,5 +1,5 @@
fn f<T>() -> bool { fn f<T>() -> bool {
struct S(T); //~ ERROR can't use generic parameters from outer function struct S(T); //~ ERROR can't use generic parameters from outer item
true true
} }

View file

@ -1,12 +1,12 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-5997-struct.rs:2:14 --> $DIR/issue-5997-struct.rs:2:14
| |
LL | fn f<T>() -> bool { LL | fn f<T>() -> bool {
| - type parameter from outer function | - type parameter from outer item
LL | struct S(T); LL | struct S(T);
| -^ use of generic parameter from outer function | -^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<T>` | help: try introducing a local generic parameter here: `<T>`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,4 +1,4 @@
// error-pattern:can't use generic parameters from outer function // error-pattern:can't use generic parameters from outer item
fn hd<U>(v: Vec<U> ) -> U { fn hd<U>(v: Vec<U> ) -> U {
fn hd1(w: [U]) -> U { return w[0]; } fn hd1(w: [U]) -> U { return w[0]; }

View file

@ -1,22 +1,22 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/nested-ty-params.rs:3:16 --> $DIR/nested-ty-params.rs:3:16
| |
LL | fn hd<U>(v: Vec<U> ) -> U { LL | fn hd<U>(v: Vec<U> ) -> U {
| - type parameter from outer function | - type parameter from outer item
LL | fn hd1(w: [U]) -> U { return w[0]; } LL | fn hd1(w: [U]) -> U { return w[0]; }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<U>` | help: try introducing a local generic parameter here: `<U>`
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/nested-ty-params.rs:3:23 --> $DIR/nested-ty-params.rs:3:23
| |
LL | fn hd<U>(v: Vec<U> ) -> U { LL | fn hd<U>(v: Vec<U> ) -> U {
| - type parameter from outer function | - type parameter from outer item
LL | fn hd1(w: [U]) -> U { return w[0]; } LL | fn hd1(w: [U]) -> U { return w[0]; }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<U>` | help: try introducing a local generic parameter here: `<U>`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,12 +1,12 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/bad-type-env-capture.rs:2:15 --> $DIR/bad-type-env-capture.rs:2:15
| |
LL | fn foo<T>() { LL | fn foo<T>() {
| - type parameter from outer function | - type parameter from outer item
LL | fn bar(b: T) { } LL | fn bar(b: T) { }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<T>` | help: try introducing a local generic parameter here: `<T>`
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,28 @@
error[E0401]: can't use generic parameters from outer item
--> $DIR/generic-params-from-outer-item-in-const-item.rs:12:20
|
LL | fn outer<T: Tr>() { // outer function
| - type parameter from outer item
LL | const K: u32 = T::C;
| ^^^^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer item
--> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
|
LL | impl<T> Tr for T { // outer impl block
| - type parameter from outer item
LL | const C: u32 = {
LL | const I: u32 = T::C;
| ^^^^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer item
--> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
|
LL | struct S<T: Tr>(U32<{ // outer struct
| - type parameter from outer item
LL | const _: u32 = T::C;
| ^^^^ use of generic parameter from outer item
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0401`.

View file

@ -0,0 +1,34 @@
error[E0401]: can't use generic parameters from outer item
--> $DIR/generic-params-from-outer-item-in-const-item.rs:12:20
|
LL | fn outer<T: Tr>() { // outer function
| - type parameter from outer item
LL | const K: u32 = T::C;
| - ^^^^ use of generic parameter from outer item
| |
| help: try introducing a local generic parameter here: `<T>`
error[E0401]: can't use generic parameters from outer item
--> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
|
LL | impl<T> Tr for T { // outer impl block
| - type parameter from outer item
LL | const C: u32 = {
LL | const I: u32 = T::C;
| - ^^^^ use of generic parameter from outer item
| |
| help: try introducing a local generic parameter here: `<T>`
error[E0401]: can't use generic parameters from outer item
--> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
|
LL | struct S<T: Tr>(U32<{ // outer struct
| - type parameter from outer item
LL | const _: u32 = T::C;
| - ^^^^ use of generic parameter from outer item
| |
| help: try introducing a local generic parameter here: `<T>`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0401`.

View file

@ -0,0 +1,39 @@
// Regression test for issue #115720.
// If a const item contains generic params from an outer items, only suggest
// turning the const item generic if the feature `generic_const_items` is enabled.
// revisions: default generic_const_items
#![cfg_attr(generic_const_items, feature(generic_const_items))]
#![feature(generic_const_exprs)] // only used for the test case "outer struct"
#![allow(incomplete_features)]
fn outer<T: Tr>() { // outer function
const K: u32 = T::C;
//~^ ERROR can't use generic parameters from outer item
//[generic_const_items]~| HELP try introducing a local generic parameter here
}
impl<T> Tr for T { // outer impl block
const C: u32 = {
const I: u32 = T::C;
//~^ ERROR can't use generic parameters from outer item
//[generic_const_items]~| HELP try introducing a local generic parameter here
I
};
}
struct S<T: Tr>(U32<{ // outer struct
const _: u32 = T::C;
//~^ ERROR can't use generic parameters from outer item
//[generic_const_items]~| HELP try introducing a local generic parameter here
0
}>);
trait Tr {
const C: u32;
}
struct U32<const N: u32>;
fn main() {}

View file

@ -1,7 +1,7 @@
trait Trait { trait Trait {
fn outer(&self) { fn outer(&self) {
fn inner(_: &Self) { fn inner(_: &Self) {
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }
} }

View file

@ -1,10 +1,10 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-12796.rs:3:22 --> $DIR/issue-12796.rs:3:22
| |
LL | fn inner(_: &Self) { LL | fn inner(_: &Self) {
| ^^^^ | ^^^^
| | | |
| use of generic parameter from outer function | use of generic parameter from outer item
| can't use `Self` here | can't use `Self` here
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,8 +1,8 @@
fn siphash<T>() { fn siphash<T>() {
trait U { trait U {
fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer item
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }

View file

@ -1,24 +1,24 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-3021-c.rs:4:24 --> $DIR/issue-3021-c.rs:4:24
| |
LL | fn siphash<T>() { LL | fn siphash<T>() {
| - type parameter from outer function | - type parameter from outer item
LL | LL |
LL | trait U { LL | trait U {
| - help: try using a local generic parameter instead: `<T>` | - help: try introducing a local generic parameter here: `<T>`
LL | fn g(&self, x: T) -> T; LL | fn g(&self, x: T) -> T;
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-3021-c.rs:4:30 --> $DIR/issue-3021-c.rs:4:30
| |
LL | fn siphash<T>() { LL | fn siphash<T>() {
| - type parameter from outer function | - type parameter from outer item
LL | LL |
LL | trait U { LL | trait U {
| - help: try using a local generic parameter instead: `<T>` | - help: try introducing a local generic parameter here: `<T>`
LL | fn g(&self, x: T) -> T; LL | fn g(&self, x: T) -> T;
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,7 +1,7 @@
unsafe fn foo<A>() { unsafe fn foo<A>() {
extern "C" { extern "C" {
static baz: *const A; static baz: *const A;
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
let bar: *const u64 = core::mem::transmute(&baz); let bar: *const u64 = core::mem::transmute(&baz);

View file

@ -1,11 +1,11 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-65025-extern-static-parent-generics.rs:3:28 --> $DIR/issue-65025-extern-static-parent-generics.rs:3:28
| |
LL | unsafe fn foo<A>() { LL | unsafe fn foo<A>() {
| - type parameter from outer function | - type parameter from outer item
LL | extern "C" { LL | extern "C" {
LL | static baz: *const A; LL | static baz: *const A;
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,26 +1,26 @@
fn f<T>() { fn f<T>() {
extern "C" { extern "C" {
static a: *const T; static a: *const T;
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }
fn g<T: Default>() { fn g<T: Default>() {
static a: *const T = Default::default(); static a: *const T = Default::default();
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
fn h<const N: usize>() { fn h<const N: usize>() {
extern "C" { extern "C" {
static a: [u8; N]; static a: [u8; N];
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }
fn i<const N: usize>() { fn i<const N: usize>() {
static a: [u8; N] = [0; N]; static a: [u8; N] = [0; N];
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
//~| ERROR can't use generic parameters from outer function //~| ERROR can't use generic parameters from outer item
} }
fn main() {} fn main() {}

View file

@ -1,44 +1,44 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-65035-static-with-parent-generics.rs:3:26 --> $DIR/issue-65035-static-with-parent-generics.rs:3:26
| |
LL | fn f<T>() { LL | fn f<T>() {
| - type parameter from outer function | - type parameter from outer item
LL | extern "C" { LL | extern "C" {
LL | static a: *const T; LL | static a: *const T;
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-65035-static-with-parent-generics.rs:9:22 --> $DIR/issue-65035-static-with-parent-generics.rs:9:22
| |
LL | fn g<T: Default>() { LL | fn g<T: Default>() {
| - type parameter from outer function | - type parameter from outer item
LL | static a: *const T = Default::default(); LL | static a: *const T = Default::default();
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-65035-static-with-parent-generics.rs:15:24 --> $DIR/issue-65035-static-with-parent-generics.rs:15:24
| |
LL | fn h<const N: usize>() { LL | fn h<const N: usize>() {
| - const parameter from outer function | - const parameter from outer item
LL | extern "C" { LL | extern "C" {
LL | static a: [u8; N]; LL | static a: [u8; N];
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-65035-static-with-parent-generics.rs:21:20 --> $DIR/issue-65035-static-with-parent-generics.rs:21:20
| |
LL | fn i<const N: usize>() { LL | fn i<const N: usize>() {
| - const parameter from outer function | - const parameter from outer item
LL | static a: [u8; N] = [0; N]; LL | static a: [u8; N] = [0; N];
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/issue-65035-static-with-parent-generics.rs:21:29 --> $DIR/issue-65035-static-with-parent-generics.rs:21:29
| |
LL | fn i<const N: usize>() { LL | fn i<const N: usize>() {
| - const parameter from outer function | - const parameter from outer item
LL | static a: [u8; N] = [0; N]; LL | static a: [u8; N] = [0; N];
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error: aborting due to 5 previous errors error: aborting due to 5 previous errors

View file

@ -6,7 +6,7 @@ trait TraitA<A> {
fn outer(&self) { fn outer(&self) {
enum Foo<B> { enum Foo<B> {
Variance(A) Variance(A)
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }
} }
@ -14,21 +14,21 @@ trait TraitA<A> {
trait TraitB<A> { trait TraitB<A> {
fn outer(&self) { fn outer(&self) {
struct Foo<B>(A); struct Foo<B>(A);
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }
trait TraitC<A> { trait TraitC<A> {
fn outer(&self) { fn outer(&self) {
struct Foo<B> { a: A } struct Foo<B> { a: A }
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }
trait TraitD<A> { trait TraitD<A> {
fn outer(&self) { fn outer(&self) {
fn foo<B>(a: A) { } fn foo<B>(a: A) { }
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
} }
} }

View file

@ -1,46 +1,46 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/resolve-type-param-in-item-in-trait.rs:8:22 --> $DIR/resolve-type-param-in-item-in-trait.rs:8:22
| |
LL | trait TraitA<A> { LL | trait TraitA<A> {
| - type parameter from outer function | - type parameter from outer item
LL | fn outer(&self) { LL | fn outer(&self) {
LL | enum Foo<B> { LL | enum Foo<B> {
| - help: try using a local generic parameter instead: `A,` | - help: try introducing a local generic parameter here: `A,`
LL | Variance(A) LL | Variance(A)
| ^ use of generic parameter from outer function | ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23
| |
LL | trait TraitB<A> { LL | trait TraitB<A> {
| - type parameter from outer function | - type parameter from outer item
LL | fn outer(&self) { LL | fn outer(&self) {
LL | struct Foo<B>(A); LL | struct Foo<B>(A);
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `A,` | help: try introducing a local generic parameter here: `A,`
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28
| |
LL | trait TraitC<A> { LL | trait TraitC<A> {
| - type parameter from outer function | - type parameter from outer item
LL | fn outer(&self) { LL | fn outer(&self) {
LL | struct Foo<B> { a: A } LL | struct Foo<B> { a: A }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `A,` | help: try introducing a local generic parameter here: `A,`
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22
| |
LL | trait TraitD<A> { LL | trait TraitD<A> {
| - type parameter from outer function | - type parameter from outer item
LL | fn outer(&self) { LL | fn outer(&self) {
LL | fn foo<B>(a: A) { } LL | fn foo<B>(a: A) { }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `A,` | help: try introducing a local generic parameter here: `A,`
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -4,9 +4,9 @@ impl A {
//~^ NOTE `Self` type implicitly declared here, by this `impl` //~^ NOTE `Self` type implicitly declared here, by this `impl`
fn banana(&mut self) { fn banana(&mut self) {
fn peach(this: &Self) { fn peach(this: &Self) {
//~^ ERROR can't use generic parameters from outer function //~^ ERROR can't use generic parameters from outer item
//~| NOTE use of generic parameter from outer function //~| NOTE use of generic parameter from outer item
//~| NOTE use a type here instead //~| NOTE refer to the type directly here instead
} }
} }
} }

View file

@ -1,4 +1,4 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/use-self-in-inner-fn.rs:6:25 --> $DIR/use-self-in-inner-fn.rs:6:25
| |
LL | impl A { LL | impl A {
@ -7,8 +7,8 @@ LL | impl A {
LL | fn peach(this: &Self) { LL | fn peach(this: &Self) {
| ^^^^ | ^^^^
| | | |
| use of generic parameter from outer function | use of generic parameter from outer item
| use a type here instead | refer to the type directly here instead
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,4 +1,4 @@
// error-pattern:can't use generic parameters from outer function // error-pattern:can't use generic parameters from outer item
fn foo<T>(x: T) { fn foo<T>(x: T) {
fn bar(f: Box<dyn FnMut(T) -> T>) { } fn bar(f: Box<dyn FnMut(T) -> T>) { }
} }

View file

@ -1,22 +1,22 @@
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/type-arg-out-of-scope.rs:3:29 --> $DIR/type-arg-out-of-scope.rs:3:29
| |
LL | fn foo<T>(x: T) { LL | fn foo<T>(x: T) {
| - type parameter from outer function | - type parameter from outer item
LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } LL | fn bar(f: Box<dyn FnMut(T) -> T>) { }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<T>` | help: try introducing a local generic parameter here: `<T>`
error[E0401]: can't use generic parameters from outer function error[E0401]: can't use generic parameters from outer item
--> $DIR/type-arg-out-of-scope.rs:3:35 --> $DIR/type-arg-out-of-scope.rs:3:35
| |
LL | fn foo<T>(x: T) { LL | fn foo<T>(x: T) {
| - type parameter from outer function | - type parameter from outer item
LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } LL | fn bar(f: Box<dyn FnMut(T) -> T>) { }
| - ^ use of generic parameter from outer function | - ^ use of generic parameter from outer item
| | | |
| help: try using a local generic parameter instead: `<T>` | help: try introducing a local generic parameter here: `<T>`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors