Skip to content

Commit c34c4cb

Browse files
committed
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 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.
1 parent 58f2091 commit c34c4cb

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

src/main/kotlin/org/rust/lang/core/stubs/StubImplementations.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class RsFileStub : PsiFileStubImpl<RsFile> {
2424

2525
object Type : IStubFileElementType<RsFileStub>(RsLanguage) {
2626
// Bump this number if Stub structure changes
27-
override fun getStubVersion(): Int = 69
27+
override fun getStubVersion(): Int = 70
2828

2929
override fun getBuilder(): StubBuilder = object : DefaultStubBuilder() {
3030
override fun createStubForFile(file: PsiFile): StubElement<*> = RsFileStub(file as RsFile)

src/main/kotlin/org/rust/lang/core/types/TyFingerprint.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ data class TyFingerprint constructor(
2929
is TyStruct -> type.item.name?.let(::TyFingerprint)
3030
is TyEnum -> type.item.name?.let(::TyFingerprint)
3131
is TySlice -> TyFingerprint("[T]")
32-
is TyStr -> TyFingerprint("str")
3332
is TyReference -> create(type.referenced)
33+
is TyPrimitive -> TyFingerprint(type.toString())
3434
else -> null
3535
}
3636
}

src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ fun findImplsAndTraits(project: Project, ty: Ty): Pair<Collection<BoundElement<R
8282

8383
// XXX: TyStr is TyPrimitive, but we want to handle it separately
8484
is TyStr -> RsImplIndex.findImpls(project, ty).map { impl -> BoundElement(impl) } to noTraits
85-
is TyPrimitive, is TyUnit, is TyUnknown -> noImpls to noTraits
85+
is TyUnit, is TyUnknown -> noImpls to noTraits
8686

8787
else -> RsImplIndex.findImpls(project, ty).map { impl ->
8888
BoundElement(impl, impl.remapTypeParameters(ty.typeParameterValues).orEmpty())

src/test/kotlin/org/rust/lang/core/resolve/RsStdlibResolveTest.kt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,70 @@ class RsStdlibResolveTest : RsResolveTestBase() {
129129
}
130130
""")
131131

132+
fun `test inherent impl char 1`() = stubOnlyResolve("""
133+
//- main.rs
134+
fn main() { 'Z'.is_lowercase(); }
135+
//^ .../char.rs
136+
""")
137+
138+
fun `test inherent impl char 2`() = expect<IllegalStateException> {
139+
stubOnlyResolve("""
140+
//- main.rs
141+
fn main() { char::is_lowercase('Z'); }
142+
//^ .../char.rs
143+
""")
144+
}
145+
146+
fun `test inherent impl str 1`() = stubOnlyResolve("""
147+
//- main.rs
148+
fn main() { "Z".to_uppercase(); }
149+
//^ ...libcollections/str.rs
150+
""")
151+
152+
fun `test inherent impl str 2`() = expect<IllegalStateException> {
153+
stubOnlyResolve("""
154+
//- main.rs
155+
fn main() { str::to_uppercase("Z"); }
156+
//^ ...libcollections/str.rs
157+
""")
158+
}
159+
160+
fun `test inherent impl f32 1`() = stubOnlyResolve("""
161+
//- main.rs
162+
fn main() { 0.0f32.sqrt(); }
163+
//^ .../f32.rs
164+
""")
165+
166+
fun `test inherent impl f32 2`() = expect<IllegalStateException> {
167+
stubOnlyResolve("""
168+
//- main.rs
169+
fn main() { f32::sqrt(0.0f32); }
170+
//^ .../f32.rs
171+
""")
172+
}
173+
174+
fun `test inherent impl f32 3`() = expect<IllegalStateException> {
175+
stubOnlyResolve("""
176+
//- main.rs
177+
fn main() { <f32>::sqrt(0.0f32); }
178+
//^ .../f32.rs
179+
""")
180+
}
181+
182+
fun `test inherent impl f64 1`() = stubOnlyResolve("""
183+
//- main.rs
184+
fn main() { 0.0f64.sqrt(); }
185+
//^ .../f64.rs
186+
""")
187+
188+
fun `test inherent impl f64 2`() = expect<IllegalStateException> {
189+
stubOnlyResolve("""
190+
//- main.rs
191+
fn main() { f64::sqrt(0.0f64); }
192+
//^ .../f64.rs
193+
""")
194+
}
195+
132196
fun `test println macro`() = stubOnlyResolve("""
133197
//- main.rs
134198
fn main() {

0 commit comments

Comments
 (0)