From 1f7ed31634a089df43114a71c805c82fb51f752c Mon Sep 17 00:00:00 2001 From: Peter Oberndorfer Date: Mon, 13 Feb 2017 18:50:50 +0100 Subject: [PATCH] TY: Improve indexing of primitive types impl blocks for primitive types are not correctly indexed. This causes problems with autocompletion and method resolving around primitive types. In Rust primitive types are only allowed a single impl block that must be annotated with the "lang" attribute. The primitive types bool does not have an inherent impl. See https://github.com/rust-lang/rust/pull/23104 and the error code E0390 for more details. Our implementation does not enforce this limitation and also accept user defined impl blocks. --- .../lang/core/stubs/StubImplementations.kt | 2 +- .../org/rust/lang/core/types/TyFingerprint.kt | 2 +- .../kotlin/org/rust/lang/core/types/ty/Ty.kt | 2 +- .../lang/core/resolve/RsStdlibResolveTest.kt | 64 +++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/org/rust/lang/core/stubs/StubImplementations.kt b/src/main/kotlin/org/rust/lang/core/stubs/StubImplementations.kt index 1d80fec2f8d..55ee170f78f 100644 --- a/src/main/kotlin/org/rust/lang/core/stubs/StubImplementations.kt +++ b/src/main/kotlin/org/rust/lang/core/stubs/StubImplementations.kt @@ -24,7 +24,7 @@ class RsFileStub : PsiFileStubImpl { object Type : IStubFileElementType(RsLanguage) { // Bump this number if Stub structure changes - override fun getStubVersion(): Int = 69 + override fun getStubVersion(): Int = 70 override fun getBuilder(): StubBuilder = object : DefaultStubBuilder() { override fun createStubForFile(file: PsiFile): StubElement<*> = RsFileStub(file as RsFile) diff --git a/src/main/kotlin/org/rust/lang/core/types/TyFingerprint.kt b/src/main/kotlin/org/rust/lang/core/types/TyFingerprint.kt index 37c8c9df8f4..e3344385b8d 100644 --- a/src/main/kotlin/org/rust/lang/core/types/TyFingerprint.kt +++ b/src/main/kotlin/org/rust/lang/core/types/TyFingerprint.kt @@ -29,8 +29,8 @@ data class TyFingerprint constructor( is TyStruct -> type.item.name?.let(::TyFingerprint) is TyEnum -> type.item.name?.let(::TyFingerprint) is TySlice -> TyFingerprint("[T]") - is TyStr -> TyFingerprint("str") is TyReference -> create(type.referenced) + is TyPrimitive -> TyFingerprint(type.toString()) else -> null } } diff --git a/src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt b/src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt index 4c3ec4e06a2..a245a2ddf26 100644 --- a/src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt +++ b/src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt @@ -82,7 +82,7 @@ fun findImplsAndTraits(project: Project, ty: Ty): Pair RsImplIndex.findImpls(project, ty).map { impl -> BoundElement(impl) } to noTraits - is TyPrimitive, is TyUnit, is TyUnknown -> noImpls to noTraits + is TyUnit, is TyUnknown -> noImpls to noTraits else -> RsImplIndex.findImpls(project, ty).map { impl -> BoundElement(impl, impl.remapTypeParameters(ty.typeParameterValues).orEmpty()) 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 f3c03636383..3736939de1b 100644 --- a/src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt +++ b/src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt @@ -129,6 +129,70 @@ class RsStdlibResolveTest : RsResolveTestBase() { } """) + fun `test inherent impl char 1`() = stubOnlyResolve(""" + //- main.rs + fn main() { 'Z'.is_lowercase(); } + //^ ...libstd_unicode/char.rs + """) + + fun `test inherent impl char 2`() = expect { + stubOnlyResolve(""" + //- main.rs + fn main() { char::is_lowercase('Z'); } + //^ ...libstd_unicode/char.rs + """) + } + + fun `test inherent impl str 1`() = stubOnlyResolve(""" + //- main.rs + fn main() { "Z".to_uppercase(); } + //^ ...libcollections/str.rs + """) + + fun `test inherent impl str 2`() = expect { + stubOnlyResolve(""" + //- main.rs + fn main() { str::to_uppercase("Z"); } + //^ ...libcollections/str.rs + """) + } + + fun `test inherent impl f32 1`() = stubOnlyResolve(""" + //- main.rs + fn main() { 0.0f32.sqrt(); } + //^ ...libstd/f32.rs + """) + + fun `test inherent impl f32 2`() = expect { + stubOnlyResolve(""" + //- main.rs + fn main() { f32::sqrt(0.0f32); } + //^ ...libstd/f32.rs + """) + } + + fun `test inherent impl f32 3`() = expect { + stubOnlyResolve(""" + //- main.rs + fn main() { ::sqrt(0.0f32); } + //^ ...libstd/f32.rs + """) + } + + fun `test inherent impl f64 1`() = stubOnlyResolve(""" + //- main.rs + fn main() { 0.0f64.sqrt(); } + //^ ...libstd/f64.rs + """) + + fun `test inherent impl f64 2`() = expect { + stubOnlyResolve(""" + //- main.rs + fn main() { f64::sqrt(0.0f64); } + //^ ...libstd/f64.rs + """) + } + fun `test println macro`() = stubOnlyResolve(""" //- main.rs fn main() {