Sitelet https://github.com/starkware-libs/cairo/commit/daff9bcc0ab74612aac88234399a2b1d34df07bf
Skip to content

Commit daff9bc

Browse files
authored
fix(semantic): report a glob name collision of non-visible items as not-visible, not ambiguous (#10209)
1 parent d83ad6f commit daff9bc

3 files changed

Lines changed: 56 additions & 28 deletions

File tree

‎crates/cairo-lang-semantic/src/diagnostic.rs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,14 @@ impl<'db> DiagnosticEntry<'db> for SemanticDiagnostic<'db> {
707707
"`super` used in macro call top level.".into()
708708
}
709709
SemanticDiagnosticKind::ItemNotVisible(item_id, containing_modules) => {
710+
// Several distinct items may share the name when reached through global uses; in
711+
// that case no single item can be pointed at, so it is reported without a name.
712+
let item = match item_id {
713+
Some(item_id) => format!("Item `{}`", item_id.full_path(db)),
714+
None => "Item".to_string(),
715+
};
710716
format!(
711-
"Item `{}` is not visible in this context{}.",
712-
item_id.full_path(db),
717+
"{item} is not visible in this context{}.",
713718
if containing_modules.is_empty() {
714719
"".to_string()
715720
} else if let [module_id] = &containing_modules[..] {
@@ -1737,7 +1742,7 @@ pub enum SemanticDiagnosticKind<'db> {
17371742
ImplItemForbiddenInTheImpl,
17381743
SuperUsedInRootModule,
17391744
SuperUsedInMacroCallTopLevel,
1740-
ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
1745+
ItemNotVisible(Option<ModuleItemId<'db>>, Vec<ModuleId<'db>>),
17411746
UnusedImport(UseId<'db>),
17421747
RedundantModifier {
17431748
current_modifier: SmolStrId<'db>,

‎crates/cairo-lang-semantic/src/diagnostic_test_data/tests‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,3 +1617,37 @@ error[E0005]: Module file not found. Expected path: non_existent_path.cairo
16171617
_^
16181618
| mod non_existing;
16191619
|_________________^
1620+
1621+
//! > ==========================================================================
1622+
1623+
//! > Testing use star with only invisible candidates.
1624+
1625+
//! > test_runner_name
1626+
test_expr_diagnostics(expect_diagnostics: true)
1627+
1628+
//! > crate_settings
1629+
edition = "2024_07"
1630+
1631+
//! > module_code
1632+
mod a {
1633+
const AMBIGUOUS: u8 = 1;
1634+
}
1635+
1636+
mod b {
1637+
const AMBIGUOUS: u8 = 4;
1638+
}
1639+
use a::*;
1640+
use b::*;
1641+
1642+
//! > function_body
1643+
1644+
//! > expr_code
1645+
AMBIGUOUS
1646+
1647+
//! > expected_semantics
1648+
1649+
//! > expected_diagnostics
1650+
error[E2099]: Item is not visible in this context through any of the modules: `test::a`, `test::b`.
1651+
--> lib.cairo:11:1
1652+
AMBIGUOUS
1653+
^^^^^^^^^

‎crates/cairo-lang-semantic/src/resolve/mod.rs‎

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ enum UseStarResult<'db> {
367367
/// The path was not found, considering only the `use *` imports.
368368
PathNotFound,
369369
/// Item is not visible in the current module, considering only the `use *` imports.
370-
ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
370+
ItemNotVisible(Option<ModuleItemId<'db>>, Vec<ModuleId<'db>>),
371371
}
372372

373373
/// A trait for things that can be interpreted as a path of segments.
@@ -775,7 +775,9 @@ impl<'db> Resolver<'db> {
775775
) -> UseStarResult<'db> {
776776
let mut item_info = None;
777777
let mut module_items_found: OrderedHashSet<ModuleItemId<'_>> = OrderedHashSet::default();
778-
let mut other_containing_modules = vec![];
778+
let mut non_pub_module_items_found: OrderedHashSet<ModuleItemId<'_>> =
779+
OrderedHashSet::default();
780+
let mut non_pub_containing_modules = vec![];
779781
for (item_module_id, info) in self.db.module_imported_modules((), module_id).iter() {
780782
// Not checking the main module to prevent cycles.
781783
if *item_module_id == module_id {
@@ -790,34 +792,21 @@ impl<'db> Resolver<'db> {
790792
item_info = Some(inner_item_info.clone());
791793
module_items_found.insert(inner_item_info.item_id);
792794
} else {
793-
other_containing_modules.push(*item_module_id);
795+
non_pub_containing_modules.push(*item_module_id);
796+
non_pub_module_items_found.insert(inner_item_info.item_id);
794797
}
795798
}
796799
}
797800
if module_items_found.len() > 1 {
798-
return UseStarResult::AmbiguousPath(module_items_found.iter().cloned().collect());
801+
return UseStarResult::AmbiguousPath(module_items_found.into_iter().collect());
799802
}
800803
match item_info {
801804
Some(item_info) => UseStarResult::UniquePathFound(item_info),
802-
None => {
803-
for item_module_id in &other_containing_modules {
804-
if let Some(inner_item_info) =
805-
self.resolve_item_in_module_or_expanded_macro(*item_module_id, ident)
806-
{
807-
item_info = Some(inner_item_info.clone());
808-
module_items_found.insert(inner_item_info.item_id);
809-
}
810-
}
811-
if let Some(item_info) = item_info {
812-
if module_items_found.len() > 1 {
813-
UseStarResult::AmbiguousPath(module_items_found.iter().cloned().collect())
814-
} else {
815-
UseStarResult::ItemNotVisible(item_info.item_id, other_containing_modules)
816-
}
817-
} else {
818-
UseStarResult::PathNotFound
819-
}
820-
}
805+
None => match non_pub_module_items_found.into_iter().exactly_one() {
806+
Ok(item) => UseStarResult::ItemNotVisible(Some(item), non_pub_containing_modules),
807+
Err(err) if err.len() == 0 => UseStarResult::PathNotFound,
808+
Err(_) => UseStarResult::ItemNotVisible(None, non_pub_containing_modules),
809+
},
821810
}
822811
}
823812

@@ -1699,7 +1688,7 @@ enum ResolvedBase<'db> {
16991688
/// The base module is ambiguous.
17001689
Ambiguous(Vec<ModuleItemId<'db>>),
17011690
/// The base module is inaccessible.
1702-
ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
1691+
ItemNotVisible(Option<ModuleItemId<'db>>, Vec<ModuleId<'db>>),
17031692
}
17041693

17051694
/// The callbacks to be used by `resolve_path_inner`.
@@ -2623,7 +2612,7 @@ impl<'db, 'a> Resolution<'db, 'a> {
26232612
) {
26242613
self.diagnostics.report(
26252614
identifier.stable_ptr(self.resolver.db),
2626-
ItemNotVisible(item_info.item_id, vec![]),
2615+
ItemNotVisible(Some(item_info.item_id), vec![]),
26272616
);
26282617
}
26292618

0 commit comments

Comments
 (0)