Merge pull request #18779 from ChayimFriedman2/enum-variant

fix: Consider `Enum::Variant` even when it comes from a different crate
This commit is contained in:
Lukas Wirth 2024-12-29 09:58:16 +00:00 committed by GitHub
commit 02d1bf31a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 66 additions and 39 deletions

View file

@ -38,7 +38,7 @@ use crate::{
attr_resolution::{attr_macro_as_call_id, derive_macro_as_call_id},
diagnostics::DefDiagnostic,
mod_resolution::ModDir,
path_resolution::{ReachedFixedPoint, ResolvePathResultPrefixInfo},
path_resolution::ReachedFixedPoint,
proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroDef, ProcMacroKind},
sub_namespace_match, BuiltinShadowMode, DefMap, MacroSubNs, ModuleData, ModuleOrigin,
ResolveMode,
@ -797,7 +797,7 @@ impl DefCollector<'_> {
return PartialResolvedImport::Unresolved;
}
if let ResolvePathResultPrefixInfo::DifferingCrate = res.prefix_info {
if res.prefix_info.differing_crate {
return PartialResolvedImport::Resolved(
def.filter_visibility(|v| matches!(v, Visibility::Public)),
);

View file

@ -46,12 +46,11 @@ pub(super) struct ResolvePathResult {
pub(super) prefix_info: ResolvePathResultPrefixInfo,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResolvePathResultPrefixInfo {
None,
DifferingCrate,
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ResolvePathResultPrefixInfo {
pub(crate) differing_crate: bool,
/// Path of the form `Enum::Variant` (and not `Variant` alone).
Enum,
pub enum_variant: bool,
}
impl ResolvePathResult {
@ -60,7 +59,7 @@ impl ResolvePathResult {
PerNs::none(),
reached_fixedpoint,
None,
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
)
}
@ -170,17 +169,8 @@ impl DefMap {
if result.reached_fixedpoint == ReachedFixedPoint::No {
result.reached_fixedpoint = new.reached_fixedpoint;
}
result.prefix_info = match (result.prefix_info, new.prefix_info) {
(ResolvePathResultPrefixInfo::None, it) => it,
(ResolvePathResultPrefixInfo::DifferingCrate, _) => {
ResolvePathResultPrefixInfo::DifferingCrate
}
(
ResolvePathResultPrefixInfo::Enum,
ResolvePathResultPrefixInfo::DifferingCrate,
) => ResolvePathResultPrefixInfo::DifferingCrate,
(ResolvePathResultPrefixInfo::Enum, _) => ResolvePathResultPrefixInfo::Enum,
};
result.prefix_info.differing_crate |= new.prefix_info.differing_crate;
result.prefix_info.enum_variant |= new.prefix_info.enum_variant;
result.segment_index = match (result.segment_index, new.segment_index) {
(Some(idx), None) => Some(idx),
(Some(old), Some(new)) => Some(old.max(new)),
@ -460,13 +450,22 @@ impl DefMap {
// because `macro_use` and other preludes should be taken into account. At
// this point, we know we're resolving a multi-segment path so macro kind
// expectation is discarded.
let (def, s) =
defp_map.resolve_path(db, module.local_id, &path, shadow, None);
let resolution = defp_map.resolve_path_fp_with_macro(
db,
ResolveMode::Other,
module.local_id,
&path,
shadow,
None,
);
return ResolvePathResult::new(
def,
resolution.resolved_def,
ReachedFixedPoint::Yes,
s.map(|s| s + i),
ResolvePathResultPrefixInfo::DifferingCrate,
resolution.segment_index.map(|s| s + i),
ResolvePathResultPrefixInfo {
differing_crate: true,
enum_variant: resolution.prefix_info.enum_variant,
},
);
}
@ -522,7 +521,10 @@ impl DefMap {
res,
ReachedFixedPoint::Yes,
None,
ResolvePathResultPrefixInfo::Enum,
ResolvePathResultPrefixInfo {
enum_variant: true,
..ResolvePathResultPrefixInfo::default()
},
)
}
}
@ -530,7 +532,7 @@ impl DefMap {
PerNs::types(e.into(), curr.vis, curr.import),
ReachedFixedPoint::Yes,
Some(i),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
),
};
}
@ -547,7 +549,7 @@ impl DefMap {
PerNs::types(s, curr.vis, curr.import),
ReachedFixedPoint::Yes,
Some(i),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
);
}
};
@ -560,7 +562,7 @@ impl DefMap {
curr_per_ns,
ReachedFixedPoint::Yes,
None,
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
)
}

View file

@ -293,7 +293,7 @@ impl Resolver {
},
None,
),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
))
}
Path::LangItem(l, Some(_)) => {
@ -310,7 +310,7 @@ impl Resolver {
};
return Some((
ResolveValueResult::Partial(type_ns, 1, None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
};
@ -346,7 +346,7 @@ impl Resolver {
ValueNs::LocalBinding(e.binding()),
None,
),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}
@ -370,7 +370,7 @@ impl Resolver {
let val = ValueNs::GenericParam(id);
return Some((
ResolveValueResult::ValueNs(val, None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}
@ -378,7 +378,7 @@ impl Resolver {
if *first_name == sym::Self_.clone() {
return Some((
ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}
@ -400,7 +400,7 @@ impl Resolver {
let ty = TypeNs::GenericParam(id);
return Some((
ResolveValueResult::Partial(ty, 1, None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}
@ -408,7 +408,7 @@ impl Resolver {
if *first_name == sym::Self_.clone() {
return Some((
ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1, None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}
@ -417,7 +417,7 @@ impl Resolver {
let ty = TypeNs::AdtSelfType(*adt);
return Some((
ResolveValueResult::Partial(ty, 1, None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}
@ -441,7 +441,7 @@ impl Resolver {
if let Some(builtin) = BuiltinType::by_name(first_name) {
return Some((
ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None),
ResolvePathResultPrefixInfo::None,
ResolvePathResultPrefixInfo::default(),
));
}
}

View file

@ -32,7 +32,7 @@ use hir_def::{
WherePredicateTypeTarget,
},
lang_item::LangItem,
nameres::{MacroSubNs, ResolvePathResultPrefixInfo},
nameres::MacroSubNs,
path::{GenericArg, GenericArgs, ModPath, Path, PathKind, PathSegment, PathSegments},
resolver::{HasResolver, LifetimeNs, ResolveValueResult, Resolver, TypeNs, ValueNs},
type_ref::{
@ -826,7 +826,7 @@ impl<'a> TyLoweringContext<'a> {
(segments.take(unresolved_segment - 1), None)
}
ResolveValueResult::ValueNs(ValueNs::EnumVariantId(_), _)
if prefix_info == ResolvePathResultPrefixInfo::Enum =>
if prefix_info.enum_variant =>
{
(segments.strip_last_two(), segments.len().checked_sub(2))
}

View file

@ -575,6 +575,31 @@ fn bar() {
// ^^^^^^ 💡 error: generic arguments are not allowed on modules
let _: &foo::<()>::Trait;
// ^^^^^^ 💡 error: generic arguments are not allowed on modules
}
"#,
);
}
#[test]
fn regression_18768() {
check_diagnostics(
r#"
//- minicore: result
//- /foo.rs crate:foo edition:2018
pub mod lib {
mod core {
pub use core::*;
}
pub use self::core::result;
}
pub mod __private {
pub use crate::lib::result::Result::{self, Err, Ok};
}
//- /bar.rs crate:bar deps:foo edition:2018
fn bar() {
_ = foo::__private::Result::<(), ()>::Ok;
}
"#,
);