about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonas.schievink@ferrous-systems.com>2022-04-14 15:51:38 +0200
committerJonas Schievink <jonas.schievink@ferrous-systems.com>2022-04-14 15:51:38 +0200
commitd764e134d5e63c8e802afc51d26536f5aca3f954 (patch)
treec2275713b476151cbb2aaaee13c7c198d5c96302
parent63573d47aaf841abb803af26dadc95e86f1fe572 (diff)
downloadrust-d764e134d5e63c8e802afc51d26536f5aca3f954.tar.gz
rust-d764e134d5e63c8e802afc51d26536f5aca3f954.zip
Fallback to primitive when path doesn't resolve
-rw-r--r--crates/hir_def/src/builtin_type.rs4
-rw-r--r--crates/hir_def/src/resolver.rs12
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs23
3 files changed, 39 insertions, 0 deletions
diff --git a/crates/hir_def/src/builtin_type.rs b/crates/hir_def/src/builtin_type.rs
index 7cbaf30b858..25a408036ff 100644
--- a/crates/hir_def/src/builtin_type.rs
+++ b/crates/hir_def/src/builtin_type.rs
@@ -68,6 +68,10 @@ impl BuiltinType {
         (name![f32], BuiltinType::Float(BuiltinFloat::F32)),
         (name![f64], BuiltinType::Float(BuiltinFloat::F64)),
     ];
+
+    pub fn by_name(name: &Name) -> Option<Self> {
+        Self::ALL.iter().find_map(|(n, ty)| if n == name { Some(*ty) } else { None })
+    }
 }
 
 impl AsName for BuiltinType {
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index fe0100fb8cc..2a990765eaa 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -317,6 +317,18 @@ impl Resolver {
             }
         }
 
+        // If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
+        // to resolving to the primitive type, to allow this to still work in the presence of
+        // `use core::u16;`.
+        if path.kind == PathKind::Plain && path.segments().len() > 1 {
+            match BuiltinType::by_name(&path.segments()[0]) {
+                Some(builtin) => {
+                    return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
+                }
+                None => {}
+            }
+        }
+
         None
     }
 
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index d97147541ad..68463dc068b 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -1767,3 +1767,26 @@ fn foo() {
 "#,
     );
 }
+
+#[test]
+fn primitive_assoc_fn_shadowed_by_use() {
+    check_types(
+        r#"
+//- /lib.rs crate:lib deps:core
+use core::u16;
+
+fn f() -> u16 {
+    let x = u16::from_le_bytes();
+      x
+    //^ u16
+}
+
+//- /core.rs crate:core
+pub mod u16 {}
+
+impl u16 {
+    pub fn from_le_bytes() -> Self { 0 }
+}
+        "#,
+    )
+}