Skip to content

Commit

Permalink
Merge #6671
Browse files Browse the repository at this point in the history
6671: Fix endless go-to-declaration for invalid self-containing structs r=vlad20012 a=vlad20012

Fixes #6605

changelog: Fix endless go-to-declaration for invalid self-containing structs

Co-authored-by: vlad20012 <beskvlad@gmail.com>
  • Loading branch information
bors[bot] and vlad20012 committed Jan 15, 2021
2 parents b34e272 + 0aa7b7c commit 4fb1485
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 20 deletions.
52 changes: 32 additions & 20 deletions src/main/kotlin/org/rust/lang/core/types/ty/Ty.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,40 @@ fun Ty.getTypeParameter(name: String): TyTypeParameter? {
/**
* See [org.rust.lang.core.type.RsImplicitTraitsTest]
*/
tailrec fun Ty.isSized(): Boolean {
return when (this) {
is TyNumeric,
is TyBool,
is TyChar,
is TyUnit,
is TyNever,
is TyReference,
is TyPointer,
is TyArray,
is TyFunction -> true
is TyStr, is TySlice, is TyTraitObject -> false
is TyTypeParameter -> isSized
is TyAdt -> {
val item = item as? RsStructItem ?: return true
val typeRef = item.fields.lastOrNull()?.typeReference
val type = typeRef?.type?.substitute(typeParameterValues) ?: return true
type.isSized()
fun Ty.isSized(): Boolean {
val ancestors = mutableSetOf(this)

fun Ty.isSizedInner(): Boolean {
return when (this) {
is TyNumeric,
is TyBool,
is TyChar,
is TyUnit,
is TyNever,
is TyReference,
is TyPointer,
is TyArray,
is TyFunction -> true

is TyStr, is TySlice, is TyTraitObject -> false

is TyTypeParameter -> isSized

is TyAdt -> {
val item = item as? RsStructItem ?: return true
val typeRef = item.fields.lastOrNull()?.typeReference
val type = typeRef?.type?.substitute(typeParameterValues) ?: return true
if (!ancestors.add(type)) return true
type.isSizedInner()
}

is TyTuple -> types.last().isSizedInner()

else -> true
}
is TyTuple -> types.last().isSized()
else -> true
}

return isSizedInner()
}

val Ty.isSelf: Boolean
Expand Down
12 changes: 12 additions & 0 deletions src/test/kotlin/org/rust/lang/core/resolve/RsResolveTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,18 @@ class RsResolveTest : RsResolveTestBase() {
//^
""")

fun `test enum Self in impl block for invalid self-containing struct`() = checkByCodeGeneric<RsImplItem>("""
struct E {
value: Self
}
impl E {
//X
fn new() -> Self {
Self
} //^
}
""")

fun `test enum variant 2`() = checkByCode("""
enum E { X, Y(X) }
//^ unresolved
Expand Down
17 changes: 17 additions & 0 deletions src/test/kotlin/org/rust/lang/core/type/RsImplicitTraitsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,23 @@ class RsImplicitTraitsTest : RsTypificationTestBase() {
//^ !Copy
""")

fun `test invalid self-containing struct 1`() = doTest("""
struct S {
field: Self
}
type T = S;
//^ Sized
""")

fun `test invalid self-containing struct 2`() = doTest("""
struct Rc<T>(T);
struct S {
field: Rc<Self>
}
type T = S;
//^ Sized
""")

private fun checkPrimitiveTypes(traitName: String) {
val allIntegers = TyInteger.VALUES.toTypedArray()
val allFloats = TyFloat.VALUES.toTypedArray()
Expand Down

0 comments on commit 4fb1485

Please sign in to comment.