Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
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
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from o
.label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
.suggestion = replace `Self` with the actual type

hir_typeck_self_ctor_from_outer_item_inner_item = `Self` used in this inner item

hir_typeck_slicing_suggestion = consider slicing here

hir_typeck_struct_expr_non_exhaustive =
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,15 @@ pub(crate) struct SelfCtorFromOuterItem {
pub impl_span: Span,
#[subdiagnostic]
pub sugg: Option<ReplaceWithName>,
#[subdiagnostic]
pub item: Option<InnerItem>,
}

#[derive(Subdiagnostic)]
#[label(hir_typeck_self_ctor_from_outer_item_inner_item)]
pub(crate) struct InnerItem {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
Expand All @@ -987,6 +996,8 @@ pub(crate) struct SelfCtorFromOuterItemLint {
pub impl_span: Span,
#[subdiagnostic]
pub sugg: Option<ReplaceWithName>,
#[subdiagnostic]
pub item: Option<InnerItem>,
}

#[derive(Subdiagnostic)]
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: path_span,
name: self.tcx.item_name(def.did()).to_ident_string(),
});
let item = match self
.tcx
.hir_node_by_def_id(self.tcx.hir_get_parent_item(hir_id).def_id)
{
hir::Node::Item(item) => Some(errors::InnerItem {
span: item.kind.ident().map(|i| i.span).unwrap_or(item.span),
}),
_ => None,
};
if ty.raw.has_param() {
let guar = self.dcx().emit_err(errors::SelfCtorFromOuterItem {
span: path_span,
impl_span: tcx.def_span(impl_def_id),
sugg,
item,
});
return (Ty::new_error(self.tcx, guar), res);
} else {
Expand All @@ -1109,6 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
errors::SelfCtorFromOuterItemLint {
impl_span: tcx.def_span(impl_def_id),
sugg,
item,
},
);
}
Expand Down
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
10 changes: 9 additions & 1 deletion compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use crate::errors::{
MaybeMissingMacroRulesName,
};
use crate::imports::{Import, ImportKind};
use crate::late::{PatternSource, Rib};
use crate::late::{DiagMetadata, PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
Expand Down 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 @@ -2401,6 +2406,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module: Option<ModuleOrUniformRoot<'ra>>,
failed_segment_idx: usize,
ident: Ident,
diag_metadata: Option<&DiagMetadata<'_>>,
) -> (String, Option<Suggestion>) {
let is_last = failed_segment_idx == path.len() - 1;
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
Expand Down Expand Up @@ -2506,6 +2512,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
&ribs[ns_to_try],
ignore_binding,
diag_metadata,
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Some(binding),
Expand Down Expand Up @@ -2556,6 +2563,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
&ribs[ValueNS],
ignore_binding,
diag_metadata,
)
} else {
None
Expand Down
17 changes: 16 additions & 1 deletion 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 All @@ -47,7 +57,12 @@ pub(crate) enum GenericParamsFromOuterItemLabel {
}

#[derive(Subdiagnostic)]
#[suggestion(resolve_suggestion, code = "{snippet}", applicability = "maybe-incorrect")]
#[suggestion(
resolve_suggestion,
code = "{snippet}",
applicability = "maybe-incorrect",
style = "verbose"
)]
pub(crate) struct GenericParamsFromOuterItemSugg {
#[primary_span]
pub(crate) span: Span,
Expand Down
38 changes: 37 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 @@ -1466,12 +1484,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

// This was an attempt to use a const parameter outside its scope.
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 @@ -1501,6 +1532,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
None,
ignore_import,
None,
)
}
#[instrument(level = "debug", skip(self))]
Expand All @@ -1522,6 +1554,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
ignore_binding,
ignore_import,
None,
)
}

Expand All @@ -1535,6 +1568,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 +1709,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 Expand Up @@ -1800,6 +1835,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module,
segment_idx,
ident,
diag_metadata,
)
},
);
Expand Down
7 changes: 5 additions & 2 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 @@ -1457,6 +1457,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
None,
&self.ribs[ns],
None,
Some(&self.diag_metadata),
)
}

Expand All @@ -1474,6 +1475,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
finalize,
&self.ribs[ns],
ignore_binding,
Some(&self.diag_metadata),
)
}

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

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
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ error[E0401]: can't use generic parameters from outer item
LL | fn foo<const X: u32>() {
| - const parameter from outer item
LL | fn bar() -> u32 {
| - help: try introducing a local generic parameter here: `<X>`
| --- generic parameter used in this inner function
LL | X
| ^ use of generic parameter from outer item
|
help: try introducing a local generic parameter here
|
LL | fn bar<X>() -> u32 {
| +++

error: aborting due to 1 previous error

Expand Down
7 changes: 6 additions & 1 deletion tests/ui/delegation/target-expr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ 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 {
| - help: try introducing a local generic parameter here: `T,`
| ------------- generic parameter used in this inner delegated function
LL |
LL | let _ = T::Default();
| ^^^^^^^^^^ use of generic parameter from outer item
|
help: try introducing a local generic parameter here
|
LL | reuse Trait::static_methodT, {
| ++
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing mistake with delegation suggestion, we just make it obvious now. This needs to be fixed separately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there already an issue for this? If not lets make one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it in last commit


error[E0434]: can't capture dynamic environment in a fn item
--> $DIR/target-expr.rs:26:17
Expand Down
Loading
Loading