Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ resolve_generic_params_from_outer_item_const = a `const` is a separate item from

resolve_generic_params_from_outer_item_const_param = const parameter from outer item

resolve_generic_params_from_outer_item_inner_item = {$is_self ->
[true] `Self`
*[false] generic parameter
} used in this inner {$descr}

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
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
outer_res,
has_generic_params,
def_kind,
item,
) => {
use errs::GenericParamsFromOuterItemLabel as Label;
let static_or_const = match def_kind {
Expand All @@ -575,6 +576,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
sugg: None,
static_or_const,
is_self,
item: item.map(|(span, descr)| errs::GenericParamsFromOuterItemInnerItem {
span,
descr,
}),
};

let sm = self.tcx.sess.source_map();
Expand Down Expand Up @@ -2506,6 +2511,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
&ribs[ns_to_try],
ignore_binding,
None,
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Some(binding),
Expand Down Expand Up @@ -2556,6 +2562,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
&ribs[ValueNS],
ignore_binding,
None,
)
} else {
None
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ pub(crate) struct GenericParamsFromOuterItem {
#[subdiagnostic]
pub(crate) static_or_const: Option<GenericParamsFromOuterItemStaticOrConst>,
pub(crate) is_self: bool,
#[subdiagnostic]
pub(crate) item: Option<GenericParamsFromOuterItemInnerItem>,
}

#[derive(Subdiagnostic)]
#[label(resolve_generic_params_from_outer_item_inner_item)]
pub(crate) struct GenericParamsFromOuterItemInnerItem {
#[primary_span]
pub(crate) span: Span,
pub(crate) descr: String,
}

#[derive(Subdiagnostic)]
Expand Down
25 changes: 24 additions & 1 deletion compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use tracing::{debug, instrument};

use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use crate::imports::{Import, NameResolution};
use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
use crate::late::{
ConstantHasGenerics, DiagMetadata, NoConstantGenericsReason, PathSource, Rib, RibKind,
};
use crate::macros::{MacroRulesScope, sub_namespace_match};
use crate::{
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy,
Expand Down Expand Up @@ -295,6 +297,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
finalize: Option<Finalize>,
ribs: &[Rib<'ra>],
ignore_binding: Option<NameBinding<'ra>>,
diag_metadata: Option<&DiagMetadata<'_>>,
) -> Option<LexicalScopeBinding<'ra>> {
assert!(ns == TypeNS || ns == ValueNS);
let orig_ident = ident;
Expand Down Expand Up @@ -326,6 +329,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
finalize.map(|finalize| finalize.path_span),
*original_rib_ident_def,
ribs,
diag_metadata,
)));
} else if let RibKind::Block(Some(module)) = rib.kind
&& let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted(
Expand Down Expand Up @@ -1193,6 +1197,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
finalize: Option<Span>,
original_rib_ident_def: Ident,
all_ribs: &[Rib<'ra>],
diag_metadata: Option<&DiagMetadata<'_>>,
) -> Res {
debug!("validate_res_from_ribs({:?})", res);
let ribs = &all_ribs[rib_index + 1..];
Expand Down Expand Up @@ -1391,12 +1396,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
};

if let Some(span) = finalize {
let item = if let Some(diag_metadata) = diag_metadata
&& let Some(current_item) = diag_metadata.current_item
{
let span = current_item
.kind
.ident()
.map(|i| i.span)
.unwrap_or(current_item.span);
Some((span, current_item.kind.descr().to_string()))
} else {
None
};
self.report_error(
span,
ResolutionError::GenericParamsFromOuterItem(
res,
has_generic_params,
def_kind,
item,
),
);
}
Expand Down Expand Up @@ -1472,6 +1490,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
res,
has_generic_params,
def_kind,
None,
),
);
}
Expand Down Expand Up @@ -1501,6 +1520,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
None,
ignore_import,
None,
)
}
#[instrument(level = "debug", skip(self))]
Expand All @@ -1522,6 +1542,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
ignore_binding,
ignore_import,
None,
)
}

Expand All @@ -1535,6 +1556,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'ra>>,
diag_metadata: Option<&DiagMetadata<'_>>,
) -> PathResult<'ra> {
let mut module = None;
let mut module_had_parse_errors = false;
Expand Down Expand Up @@ -1675,6 +1697,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
finalize,
&ribs[ns],
ignore_binding,
diag_metadata,
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
Expand Down
15 changes: 10 additions & 5 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ pub(crate) struct UnnecessaryQualification<'ra> {
}

#[derive(Default, Debug)]
struct DiagMetadata<'ast> {
pub(crate) struct DiagMetadata<'ast> {
/// The current trait's associated items' ident, used for diagnostic suggestions.
current_trait_assoc_items: Option<&'ast [Box<AssocItem>]>,

Expand All @@ -678,7 +678,7 @@ struct DiagMetadata<'ast> {
current_self_item: Option<NodeId>,

/// The current trait (used to suggest).
current_item: Option<&'ast Item>,
pub(crate) current_item: Option<&'ast Item>,

/// When processing generic arguments and encountering an unresolved ident not found,
/// suggest introducing a type or const param depending on the context.
Expand Down Expand Up @@ -885,6 +885,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
TypeNS,
Some(Finalize::new(ty.id, ty.span)),
None,
None,
)
.map_or(Res::Err, |d| d.res());
self.r.record_partial_res(ty.id, PartialRes::new(res));
Expand Down Expand Up @@ -1457,6 +1458,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
None,
&self.ribs[ns],
None,
None,
)
}

Expand All @@ -1466,6 +1468,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
ns: Namespace,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'ra>>,
diag_metadata: Option<&crate::late::DiagMetadata<'_>>,
) -> Option<LexicalScopeBinding<'ra>> {
self.r.resolve_ident_in_lexical_scope(
ident,
Expand All @@ -1474,6 +1477,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
finalize,
&self.ribs[ns],
ignore_binding,
diag_metadata,
)
}

Expand All @@ -1493,6 +1497,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
Some(&self.ribs),
None,
None,
Some(&self.diag_metadata),
)
}

Expand Down Expand Up @@ -2551,8 +2556,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
report_error(self, ns);
}
Some(LexicalScopeBinding::Item(binding)) => {
if let Some(LexicalScopeBinding::Res(..)) =
self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding))
if let Some(LexicalScopeBinding::Res(..)) = self
.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding), None)
{
report_error(self, ns);
}
Expand Down Expand Up @@ -5105,7 +5110,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// use the type namespace
let ns = if i + 1 == path.len() { ns } else { TypeNS };
let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None, None)?;
(res == binding.res()).then_some((seg, binding))
});

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ struct BindingError {
#[derive(Debug)]
enum ResolutionError<'ra> {
/// Error E0401: can't use type or const parameters from outer item.
GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
GenericParamsFromOuterItem(Res, HasGenericParams, DefKind, Option<(Span, String)>),
/// Error E0403: the name is already used for a type or const parameter in this generic
/// parameter list.
NameAlreadyUsedInParameterList(Ident, Span),
Expand Down
4 changes: 3 additions & 1 deletion tests/ui/delegation/target-expr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ error[E0401]: can't use generic parameters from outer item
|
LL | fn bar<T: Default>(_: T) {
| - type parameter from outer item
...
LL | reuse Trait::static_method {
| ------------- generic parameter used in this inner delegated function
LL |
LL | let _ = T::Default();
| ^^^^^^^^^^ use of generic parameter from outer item
|
Expand Down
16 changes: 11 additions & 5 deletions tests/ui/error-codes/E0401.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item
LL | fn foo<T>(x: T) {
| - type parameter from outer item
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
| ^ use of generic parameter from outer item
| ---- ^ use of generic parameter from outer item
| |
| generic parameter used in this inner function
|
help: try introducing a local generic parameter here
|
Expand All @@ -17,6 +19,9 @@ error[E0401]: can't use generic parameters from outer item
LL | fn foo<T>(x: T) {
| - type parameter from outer item
...
LL | fn baz<U,
| --- generic parameter used in this inner function
...
LL | (y: T) {
| ^ use of generic parameter from outer item
|
Expand All @@ -32,10 +37,11 @@ LL | impl<T> Iterator for A<T> {
| ---- `Self` type implicitly declared here, by this `impl`
...
LL | fn helper(sel: &Self) -> u8 {
| ^^^^
| |
| use of `Self` from outer item
| refer to the type directly here instead
| ------ ^^^^
| | |
| | use of `Self` from outer item
| | refer to the type directly here instead
| `Self` used in this inner function

error: aborting due to 3 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item
LL | fn f<Z>() -> bool {
| - type parameter from outer item
LL | enum E { V(Z) }
| ^ use of generic parameter from outer item
| - ^ use of generic parameter from outer item
| |
| generic parameter used in this inner enum
|
help: try introducing a local generic parameter here
|
Expand Down
8 changes: 6 additions & 2 deletions tests/ui/generics/generic-params-nested-fn-scope-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item
LL | fn foo<U>(v: Vec<U>) -> U {
| - type parameter from outer item
LL | fn bar(w: [U]) -> U {
| ^ use of generic parameter from outer item
| --- ^ use of generic parameter from outer item
| |
| generic parameter used in this inner function
|
help: try introducing a local generic parameter here
|
Expand All @@ -17,7 +19,9 @@ error[E0401]: can't use generic parameters from outer item
LL | fn foo<U>(v: Vec<U>) -> U {
| - type parameter from outer item
LL | fn bar(w: [U]) -> U {
| ^ use of generic parameter from outer item
| --- ^ use of generic parameter from outer item
| |
| generic parameter used in this inner function
|
help: try introducing a local generic parameter here
|
Expand Down
4 changes: 3 additions & 1 deletion tests/ui/generics/issue-98432.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ LL | impl<T> Struct<T> {
| - type parameter from outer item
LL | const CONST: fn() = || {
LL | struct _Obligation where T:;
| ^ use of generic parameter from outer item
| ----------- ^ use of generic parameter from outer item
| |
| generic parameter used in this inner struct
|
help: try introducing a local generic parameter here
|
Expand Down
4 changes: 3 additions & 1 deletion tests/ui/resolve/bad-type-env-capture.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item
LL | fn foo<T>() {
| - type parameter from outer item
LL | fn bar(b: T) { }
| ^ use of generic parameter from outer item
| --- ^ use of generic parameter from outer item
| |
| generic parameter used in this inner function
|
help: try introducing a local generic parameter here
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item
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
| - ^^^^ use of generic parameter from outer item
| |
| generic parameter used in this inner constant item
|
= note: a `const` is a separate item from the item that contains it

Expand All @@ -15,7 +17,9 @@ 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
| - ^^^^ use of generic parameter from outer item
| |
| generic parameter used in this inner constant item
|
= note: a `const` is a separate item from the item that contains it

Expand All @@ -25,7 +29,9 @@ error[E0401]: can't use generic parameters from outer item
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
| - ^^^^ use of generic parameter from outer item
| |
| generic parameter used in this inner constant item
|
= note: a `const` is a separate item from the item that contains it

Expand Down
Loading