Skip to content

Commit

Permalink
TY: Improve indexing of primitive types
Browse files Browse the repository at this point in the history
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 rust-lang/rust#23104
and the error code E0390 for more details.

Our implementation does not enforce this limitation
and also accept user defined impl blocks.
  • Loading branch information
kumbayo committed May 21, 2017
1 parent 58f2091 commit 1f7ed31
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class RsFileStub : PsiFileStubImpl<RsFile> {

object Type : IStubFileElementType<RsFileStub>(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)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/org/rust/lang/core/types/TyFingerprint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fun findImplsAndTraits(project: Project, ty: Ty): Pair<Collection<BoundElement<R

// XXX: TyStr is TyPrimitive, but we want to handle it separately
is TyStr -> 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())
Expand Down
64 changes: 64 additions & 0 deletions src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<IllegalStateException> {
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<IllegalStateException> {
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<IllegalStateException> {
stubOnlyResolve("""
//- main.rs
fn main() { f32::sqrt(0.0f32); }
//^ ...libstd/f32.rs
""")
}

fun `test inherent impl f32 3`() = expect<IllegalStateException> {
stubOnlyResolve("""
//- main.rs
fn main() { <f32>::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<IllegalStateException> {
stubOnlyResolve("""
//- main.rs
fn main() { f64::sqrt(0.0f64); }
//^ ...libstd/f64.rs
""")
}

fun `test println macro`() = stubOnlyResolve("""
//- main.rs
fn main() {
Expand Down

0 comments on commit 1f7ed31

Please sign in to comment.