Repository: starkware-libs/cairo (language: rust)

Issue:
bug: glob imports `*` conflicts prelude items with module's non-visible items
# Bug Report

**Cairo version:**
2.9.2
<!-- Please specify commit or tag version. -->

**Current behavior:**
```
use core::keccak::*;

fn main(){
 let input: Span<u256> = array![0, 1, 2].span();
 assert!(keccak_u256s_le_inputs(input) == 0xf005473605efc7d8ff67d9f23fe2e4a4f23454c12b49b38822ed362e0a92a0a6);
}
```

This fails to compile because of

```
error: Item `core::keccak::Span` is not visible in this context through module `core::keccak`.
 --> /Users/msaug/workspace/sandbox/tmp/src/lib.cairo:6:13
 let input: Span<u256> = array![0, 1, 2].span();
            ^**^
```


There seems to be a conflict between the items imported from the prelude and from the global imports.



Discussion / hints:

Fix patch:
diff --git a/crates/cairo-lang-semantic/src/resolve/mod.rs b/crates/cairo-lang-semantic/src/resolve/mod.rs
index 839d419f408..320fea705a9 100644
--- a/crates/cairo-lang-semantic/src/resolve/mod.rs
+++ b/crates/cairo-lang-semantic/src/resolve/mod.rs
@@ -1129,40 +1129,44 @@ impl<'db> Resolver<'db> {
         let mut item_info = None;
         let mut module_items_found: OrderedHashSet<ModuleItemId> = OrderedHashSet::default();
         let imported_modules = self.db.priv_module_use_star_modules(module_id);
-        let mut containing_modules = vec![];
-        let mut is_accessible = false;
         for (star_module_id, item_module_id) in &imported_modules.accessible {
             if let Some(inner_item_info) =
                 self.resolve_item_in_imported_module(*item_module_id, identifier)
             {
-                item_info = Some(inner_item_info.clone());
-                is_accessible |=
-                    self.is_item_visible(*item_module_id, &inner_item_info, *star_module_id)
-                        && self.is_item_feature_usable(&inner_item_info);
-                module_items_found.insert(inner_item_info.item_id);
-            }
-        }
-        for star_module_id in &imported_modules.all {
-            if let Some(inner_item_info) =
-                self.resolve_item_in_imported_module(*star_module_id, identifier)
-            {
-                item_info = Some(inner_item_info.clone());
-                module_items_found.insert(inner_item_info.item_id);
-                containing_modules.push(*star_module_id);
+                if self.is_item_visible(*item_module_id, &inner_item_info, *star_module_id)
+                    && self.is_item_feature_usable(&inner_item_info)
+                {
+                    item_info = Some(inner_item_info.clone());
+                    module_items_found.insert(inner_item_info.item_id);
+                }
             }
         }
         if module_items_found.len() > 1 {
             return UseStarResult::AmbiguousPath(module_items_found.iter().cloned().collect());
         }
         match item_info {
-            Some(item_info) => {
-                if is_accessible {
-                    UseStarResult::UniquePathFound(item_info)
+            Some(item_info) => UseStarResult::UniquePathFound(item_info),
+            None => {
+                let mut containing_modules = vec![];
+                for star_module_id in &imported_modules.all {
+                    if let Some(inner_item_info) =
+                        self.resolve_item_in_imported_module(*star_module_id, identifier)
+                    {
+                        item_info = Some(inner_item_info.clone());
+                        module_items_found.insert(inner_item_info.item_id);
+                        containing_modules.push(*star_module_id);
+                    }
+                }
+                if let Some(item_info) = item_info {
+                    if module_items_found.len() > 1 {
+                        UseStarResult::AmbiguousPath(module_items_found.iter().cloned().collect())
+                    } else {
+                        UseStarResult::ItemNotVisible(item_info.item_id, containing_modules)
+                    }
                 } else {
-                    UseStarResult::ItemNotVisible(item_info.item_id, containing_modules)
+                    UseStarResult::PathNotFound
                 }
             }
-            None => UseStarResult::PathNotFound,
         }
     }
 
@@ -1305,6 +1309,10 @@ impl<'db> Resolver<'db> {
             }
             UseStarResult::PathNotFound => {}
             UseStarResult::ItemNotVisible(module_item_id, containing_modules) => {
+                let prelude = self.prelude_submodule();
+                if let Ok(Some(_)) = self.db.module_item_by_name(prelude, ident) {
+                    return ResolvedBase::Module(prelude);
+                }
                 return ResolvedBase::ItemNotVisible(module_item_id, containing_modules);
             }
         }


Test patch:
diff --git a/corelib/src/test/language_features/glob_use_test.cairo b/corelib/src/test/language_features/glob_use_test.cairo
index 549117200ec..c5df881479b 100644
--- a/corelib/src/test/language_features/glob_use_test.cairo
+++ b/corelib/src/test/language_features/glob_use_test.cairo
@@ -1,13 +1,27 @@
-pub mod a {
+mod a {
     pub const NON_SHADOWED: felt252 = 'non_shadowed';
     pub const SHADOWED: felt252 = 'original_shadowed';
+    pub const PUBLISHED_ONCE: felt252 = 'published_once';
+}
+
+mod b {
+    const PUBLISHED_ONCE: felt252 = 'ignored';
+    #[allow(unused_imports)]
+    use core::array::Span;
 }
 
 pub const SHADOWED: felt252 = 'new_shadowed';
 use a::*;
+use b::*;
 
 #[test]
 fn test_use_star_shadowing() {
     assert_eq!(NON_SHADOWED, 'non_shadowed');
     assert_eq!(SHADOWED, 'new_shadowed');
 }
+
+#[test]
+fn test_use_star_non_pub() {
+    assert_eq!(PUBLISHED_ONCE, 'published_once');
+    let _x: Span<felt252> = [].span();
+}