mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #152384 - enthropy7:fix-eii-root-resolution-clean, r=jdonszelmann
Restrict EII declarations to functions at lowering time We tighten EII declaration resolution so that `lower_path_simple_eii` only accepts function‑like items (`Fn, AssocFn, Ctor(_, Fn)`) as valid EII targets. If name resolution points at something else (like a const with the same name), we now emit a direct error (“`externally implementable items must refer to a function`”) at the declaration site, which prevents bad `DefIds` from ever reaching `compare_eii_function_types` and turning into an ICE this is more robust and root-cause oriented fix to rust-lang/rust#152337 issue and an alternate of my more simple PR rust-lang/rust#152365 test included
This commit is contained in:
@@ -441,6 +441,8 @@ pub(crate) enum PathSource<'a, 'ast, 'ra> {
|
||||
TraitItem(Namespace, &'a PathSource<'a, 'ast, 'ra>),
|
||||
/// Paths in delegation item
|
||||
Delegation,
|
||||
/// Paths in externally implementable item declarations.
|
||||
ExternItemImpl,
|
||||
/// An arg in a `use<'a, N>` precise-capturing bound.
|
||||
PreciseCapturingArg(Namespace),
|
||||
/// Paths that end with `(..)`, for return type notation.
|
||||
@@ -465,6 +467,7 @@ fn namespace(self) -> Namespace {
|
||||
| PathSource::Pat
|
||||
| PathSource::TupleStruct(..)
|
||||
| PathSource::Delegation
|
||||
| PathSource::ExternItemImpl
|
||||
| PathSource::ReturnTypeNotation => ValueNS,
|
||||
PathSource::TraitItem(ns, _) => ns,
|
||||
PathSource::PreciseCapturingArg(ns) => ns,
|
||||
@@ -484,6 +487,7 @@ fn defer_to_typeck(self) -> bool {
|
||||
| PathSource::TraitItem(..)
|
||||
| PathSource::DefineOpaques
|
||||
| PathSource::Delegation
|
||||
| PathSource::ExternItemImpl
|
||||
| PathSource::PreciseCapturingArg(..)
|
||||
| PathSource::Macro
|
||||
| PathSource::Module => false,
|
||||
@@ -526,7 +530,9 @@ fn descr_expected(self) -> &'static str {
|
||||
},
|
||||
_ => "value",
|
||||
},
|
||||
PathSource::ReturnTypeNotation | PathSource::Delegation => "function",
|
||||
PathSource::ReturnTypeNotation
|
||||
| PathSource::Delegation
|
||||
| PathSource::ExternItemImpl => "function",
|
||||
PathSource::PreciseCapturingArg(..) => "type or const parameter",
|
||||
PathSource::Macro => "macro",
|
||||
PathSource::Module => "module",
|
||||
@@ -618,6 +624,9 @@ pub(crate) fn is_expected(self, res: Res) -> bool {
|
||||
_ => false,
|
||||
},
|
||||
PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
|
||||
PathSource::ExternItemImpl => {
|
||||
matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..), _))
|
||||
}
|
||||
PathSource::PreciseCapturingArg(ValueNS) => {
|
||||
matches!(res, Res::Def(DefKind::ConstParam, _))
|
||||
}
|
||||
@@ -640,8 +649,12 @@ fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {
|
||||
(PathSource::Type | PathSource::DefineOpaques, false) => E0425,
|
||||
(PathSource::Struct(_), true) => E0574,
|
||||
(PathSource::Struct(_), false) => E0422,
|
||||
(PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
|
||||
(PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425,
|
||||
(PathSource::Expr(..), true)
|
||||
| (PathSource::Delegation, true)
|
||||
| (PathSource::ExternItemImpl, true) => E0423,
|
||||
(PathSource::Expr(..), false)
|
||||
| (PathSource::Delegation, false)
|
||||
| (PathSource::ExternItemImpl, false) => E0425,
|
||||
(PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,
|
||||
(PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
|
||||
(PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, true) => E0575,
|
||||
@@ -1091,7 +1104,7 @@ fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: Node
|
||||
*node_id,
|
||||
&None,
|
||||
&target.foreign_item,
|
||||
PathSource::Expr(None),
|
||||
PathSource::ExternItemImpl,
|
||||
);
|
||||
} else {
|
||||
self.smart_resolve_path(*node_id, &None, &eii_macro_path, PathSource::Macro);
|
||||
@@ -2198,7 +2211,8 @@ fn resolve_elided_lifetimes_in_path(
|
||||
| PathSource::Struct(_)
|
||||
| PathSource::TupleStruct(..)
|
||||
| PathSource::DefineOpaques
|
||||
| PathSource::Delegation => true,
|
||||
| PathSource::Delegation
|
||||
| PathSource::ExternItemImpl => true,
|
||||
};
|
||||
if inferred {
|
||||
// Do not create a parameter for patterns and expressions: type checking can infer
|
||||
@@ -3004,7 +3018,7 @@ fn resolve_item(&mut self, item: &'ast Item) {
|
||||
item.id,
|
||||
&None,
|
||||
extern_item_path,
|
||||
PathSource::Expr(None),
|
||||
PathSource::ExternItemImpl,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Regression test for ICE "unexpected sort of node in fn_sig()" (issue #152337).
|
||||
// When the same name is used for a const and an #[eii] function, the declaration
|
||||
// was incorrectly resolved to the const, causing fn_sig() to be called on a non-function.
|
||||
#![feature(extern_item_impls)]
|
||||
|
||||
const A: () = ();
|
||||
#[eii]
|
||||
fn A() {} //~ ERROR the name `A` is defined multiple times
|
||||
//~^ ERROR expected function, found constant
|
||||
//~| ERROR expected function, found constant
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,27 @@
|
||||
error[E0428]: the name `A` is defined multiple times
|
||||
--> $DIR/eii-declaration-not-fn-issue-152337.rs:8:1
|
||||
|
|
||||
LL | const A: () = ();
|
||||
| ----------------- previous definition of the value `A` here
|
||||
LL | #[eii]
|
||||
LL | fn A() {}
|
||||
| ^^^^^^ `A` redefined here
|
||||
|
|
||||
= note: `A` must be defined only once in the value namespace of this module
|
||||
|
||||
error[E0423]: expected function, found constant `self::A`
|
||||
--> $DIR/eii-declaration-not-fn-issue-152337.rs:8:4
|
||||
|
|
||||
LL | fn A() {}
|
||||
| ^ not a function
|
||||
|
||||
error[E0423]: expected function, found constant `A`
|
||||
--> $DIR/eii-declaration-not-fn-issue-152337.rs:8:4
|
||||
|
|
||||
LL | fn A() {}
|
||||
| ^ not a function
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0423, E0428.
|
||||
For more information about an error, try `rustc --explain E0423`.
|
||||
Reference in New Issue
Block a user