diff --git a/src/main/kotlin/org/rust/lang/core/resolve/ResolveEngine.kt b/src/main/kotlin/org/rust/lang/core/resolve/ResolveEngine.kt index a2138ecb09e..87d0eb5ce8f 100644 --- a/src/main/kotlin/org/rust/lang/core/resolve/ResolveEngine.kt +++ b/src/main/kotlin/org/rust/lang/core/resolve/ResolveEngine.kt @@ -305,7 +305,8 @@ private fun lexicalDeclarations( sequenceOf( itemDeclarations(scope, true, context), injectedCrates(scope), - preludeSymbols(scope.module, context) + preludeSymbols(scope.module, context), + emptySequence()//TODO inject primitive types somewhere around here maybe??? ).flatten() is RsModItem -> diff --git a/src/main/kotlin/org/rust/lang/core/resolve/indexes/RsImplIndex.kt b/src/main/kotlin/org/rust/lang/core/resolve/indexes/RsImplIndex.kt index abce2570f5a..58771b46b4c 100644 --- a/src/main/kotlin/org/rust/lang/core/resolve/indexes/RsImplIndex.kt +++ b/src/main/kotlin/org/rust/lang/core/resolve/indexes/RsImplIndex.kt @@ -13,10 +13,11 @@ import org.rust.lang.core.psi.RsStructOrEnumItemElement import org.rust.lang.core.psi.impl.mixin.isAssocFn import org.rust.lang.core.stubs.RsFileStub import org.rust.lang.core.stubs.RsImplItemStub -import org.rust.lang.core.types.types.RustStructOrEnumTypeBase import org.rust.lang.core.types.RustType import org.rust.lang.core.types.RustTypeFingerprint import org.rust.lang.core.types.type +import org.rust.lang.core.types.types.RustPrimitiveType +import org.rust.lang.core.types.types.RustStructOrEnumTypeBase object RsImplIndex { @@ -32,6 +33,8 @@ object RsImplIndex { fun findImplsFor(target: RustType, project: Project): Sequence { val inherentImpls = if (target is RustStructOrEnumTypeBase) InherentImpls.find(target.item) + else if (target is RustPrimitiveType) + InherentImpls.find(target, project); else emptySequence() @@ -98,6 +101,22 @@ object RsImplIndex { } } + fun find(target: RustPrimitiveType, project: Project): Sequence { + val fingerprint = RustTypeFingerprint.create(target) + ?: return emptySequence() + + return StubIndex.getElements( + InherentImpls.KEY, + fingerprint, + project, + GlobalSearchScope.allScope(project), + RsImplItem::class.java + ).asSequence().filter { impl -> + val ty = impl.typeReference?.type + ty is RustPrimitiveType && ty == target + } + } + fun index(stub: RsImplItemStub, sink: IndexSink) { val type = stub.psi.typeReference ?: return val key = RustTypeFingerprint.create(type) diff --git a/src/main/kotlin/org/rust/lang/core/types/RustTypeFingerprint.kt b/src/main/kotlin/org/rust/lang/core/types/RustTypeFingerprint.kt index 1103402375f..9db6ddec092 100644 --- a/src/main/kotlin/org/rust/lang/core/types/RustTypeFingerprint.kt +++ b/src/main/kotlin/org/rust/lang/core/types/RustTypeFingerprint.kt @@ -3,9 +3,7 @@ package org.rust.lang.core.types import org.rust.lang.core.psi.RsBaseType import org.rust.lang.core.psi.RsRefLikeType import org.rust.lang.core.psi.RsTypeReference -import org.rust.lang.core.types.types.RustEnumType -import org.rust.lang.core.types.types.RustReferenceType -import org.rust.lang.core.types.types.RustStructType +import org.rust.lang.core.types.types.* import java.io.DataInput import java.io.DataOutput @@ -23,6 +21,7 @@ data class RustTypeFingerprint private constructor( is RustStructType -> type.item.name?.let(::RustTypeFingerprint) is RustEnumType -> type.item.name?.let(::RustTypeFingerprint) is RustReferenceType -> create(type.referenced) + is RustPrimitiveType -> type.toString().let(::RustTypeFingerprint) else -> null } } diff --git a/src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt b/src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt index b1abf7b1a84..1403250c49e 100644 --- a/src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt +++ b/src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt @@ -136,4 +136,68 @@ class RsStdlibResolveTest : RsResolveTestBase() { fn main() { use self::m::Some; } //^ unresolved """) + + fun testChar() = stubOnlyResolve(""" + //- main.rs + fn main() { 'Z'.is_lowercase(); } + //^ ...libstd_unicode/char.rs + """) + + fun testCharUFCS() = expect { stubOnlyResolve (""" + //- main.rs + fn main() { char.is_lowercase('Z'); } + //^ ...libstd_unicode/char.rs + """) + } + + fun testStr() = stubOnlyResolve(""" + //- main.rs + fn main() { "Z".to_uppercase(); } + //^ ...libcollections/str.rs + """) + + fun testStrUFCS() = expect { stubOnlyResolve (""" + //- main.rs + fn main() { str::to_uppercase("Z"); } + //^ ...libcollections/str.rs + """) + } + + fun testF32() = stubOnlyResolve(""" + //- main.rs + fn main() { 0.0f32.sqrt(); } + //^ ...libstd/f32.rs + """) + + fun testF32UFCS() = expect { stubOnlyResolve (""" + //- main.rs + fn main() { f32::sqrt(0.0f32); } + //^ ...libstd/f32.rs + """) + } + + fun testF32UFCS2() = expect { stubOnlyResolve (""" + //- main.rs + fn main() { ::sqrt(0.0f32); } + //^ ...libstd/f32.rs + """) + } + + fun testF64() = stubOnlyResolve(""" + //- main.rs + fn main() { 0.0f64.sqrt(); } + //^ ...libstd/f64.rs + """) + + fun testF64UFCS() = expect { stubOnlyResolve (""" + //- main.rs + fn main() { f64::sqrt(0.0f64); } + //^ ...libstd/f64.rs + """) + } + + //TODO add tests for: + // slice, const_ptr, mut_ptr + // u8, u16, u32, u64, u128, usize + // i8, i16, i32, i64, i128, isize }