From 664e1a18c9fb2f5ca4f5122b748073f2da5af396 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 28 Dec 2024 22:43:51 +0200 Subject: [PATCH] Consider `Enum::Variant` even when it comes from a different crate --- crates/hir-def/src/nameres/collector.rs | 4 +- crates/hir-def/src/nameres/path_resolution.rs | 54 ++++++++++--------- crates/hir-def/src/resolver.rs | 18 +++---- crates/hir-ty/src/lower.rs | 4 +- .../src/handlers/generic_args_prohibited.rs | 25 +++++++++ 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 318a8d5aa1..5d19b849a7 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -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)), ); diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 9573697a87..47c08d3d1d 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -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(), ) } diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 4f15c8091c..82da57a9bb 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -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(), )); } } diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 4bfa51c849..7a74694887 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -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)) } diff --git a/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs b/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs index a6d2ed3223..2b59c1a22f 100644 --- a/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs +++ b/crates/ide-diagnostics/src/handlers/generic_args_prohibited.rs @@ -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; } "#, );