Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ANN: Add support for E0131, E0197, E0203 #10

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/main/kotlin/org/rust/ide/annotator/RsSyntaxErrorsAnnotator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.text.SemVer
import org.rust.cargo.util.parseSemVer
import com.intellij.psi.util.parentOfType
import org.rust.ide.annotator.fixes.AddTypeFix
import org.rust.ide.annotator.fixes.RemoveElementFix
import org.rust.ide.inspections.fixes.SubstituteTextFix
import org.rust.lang.core.CompilerFeature.Companion.C_VARIADIC
import org.rust.lang.core.macros.MacroExpansion
import org.rust.lang.core.psi.*
import org.rust.lang.core.psi.ext.*
import org.rust.lang.core.types.ty.Mutability
import org.rust.lang.core.types.infer.constGenerics
import org.rust.lang.core.types.type
import org.rust.lang.utils.RsDiagnostic
import org.rust.lang.utils.addToHolder
Expand All @@ -40,6 +43,7 @@ class RsSyntaxErrorsAnnotator : AnnotatorBase() {
is RsFunction -> checkFunction(holder, element)
is RsStructItem -> checkStructItem(holder, element)
is RsTypeAlias -> checkTypeAlias(holder, element)
is RsImplItem -> checkImplItem(holder, element)
is RsConstant -> checkConstant(holder, element)
is RsModItem -> checkModItem(holder, element)
is RsModDeclItem -> checkModDeclItem(holder, element)
Expand All @@ -51,13 +55,30 @@ class RsSyntaxErrorsAnnotator : AnnotatorBase() {
is RsValueParameterList -> checkValueParameterList(holder, element)
is RsValueParameter -> checkValueParameter(holder, element)
is RsTypeParameterList -> checkTypeParameterList(holder, element)
is RsTypeParameter -> checkTypeParameter(holder, element)
is RsTypeArgumentList -> checkTypeArgumentList(holder, element)
is RsLetExpr -> checkLetExpr(holder, element)
is RsPatRange -> checkPatRange(holder, element)
}
}
}

private fun checkTypeParameter(holder: AnnotationHolder, item: RsTypeParameter) {
if (item.bounds.count { it.hasQ } > 1) {
RsDiagnostic.MultipleRelaxedBoundsError(item).addToHolder(holder)
}
}

private fun checkImplItem(holder: AnnotationHolder, item: RsImplItem) {
val unsafe = item.unsafe
if (unsafe != null && item.traitRef == null) {
val typeReference = item.typeReference ?: return
RsDiagnostic.UnsafeInherentImplError(
typeReference, listOf(RemoveElementFix(unsafe))
).addToHolder(holder)
}
}

private fun checkItem(holder: AnnotationHolder, item: RsItemElement) {
checkItemOrMacro(item, item.itemKindName.pluralize().capitalized(), item.itemDefKeyword, holder)
}
Expand Down Expand Up @@ -93,6 +114,17 @@ private fun checkMacroCall(holder: AnnotationHolder, element: RsMacroCall) {
}

private fun checkFunction(holder: AnnotationHolder, fn: RsFunction) {
if (fn.isMain &&
(fn.typeParameters.isNotEmpty() || fn.lifetimeParameters.isNotEmpty() || fn.constParameters.isNotEmpty())) {
val typeParameterList = fn.typeParameterList ?: fn
RsDiagnostic.MainWithGenericsError(
typeParameterList, listOf(
RemoveElementFix(
typeParameterList
)
)
).addToHolder(holder)
}
when (fn.owner) {
is RsAbstractableOwner.Free -> {
require(fn.block, holder, "${fn.title} must have a body", fn.lastChild)
Expand Down
38 changes: 36 additions & 2 deletions src/main/kotlin/org/rust/lang/utils/RsDiagnostic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1625,12 +1625,46 @@ sealed class RsDiagnostic(
"Patterns aren't allowed in functions without bodies",
)
}

class UnsafeInherentImplError(
element: PsiElement,
private val fixes: List<LocalQuickFix>
) : RsDiagnostic(element) {
override fun prepare() = PreparedAnnotation (
ERROR,
E0197,
"Inherent impls cannot be unsafe",
fixes = fixes
)
}

class MainWithGenericsError(
element: PsiElement,
private val fixes: List<LocalQuickFix>
) : RsDiagnostic(element) {
override fun prepare() = PreparedAnnotation (
ERROR,
E0131,
"`main` function is not allowed to have generic parameters",
fixes = fixes
)
}

class MultipleRelaxedBoundsError(
element: PsiElement
) : RsDiagnostic(element) {
override fun prepare() = PreparedAnnotation(
ERROR,
E0203,
"Type parameter has more than one relaxed default bound, only one is supported"
)
}
}

enum class RsErrorCode {
E0004, E0013, E0015, E0023, E0025, E0026, E0027, E0040, E0044, E0046, E0049, E0050, E0054, E0057, E0060, E0061, E0069, E0081, E0084,
E0106, E0107, E0116, E0117, E0118, E0120, E0121, E0124, E0130, E0132, E0133, E0184, E0185, E0186, E0191, E0198, E0199,
E0200, E0201, E0220, E0252, E0254, E0255, E0259, E0260, E0261, E0262, E0263, E0267, E0268, E0277,
E0106, E0107, E0116, E0117, E0118, E0120, E0121, E0124, E0130, E0131, E0132, E0133, E0184, E0185, E0186, E0191, E0197, E0198, E0199,
E0200, E0201, E0203, E0220, E0252, E0254, E0255, E0259, E0260, E0261, E0262, E0263, E0267, E0268, E0277,
E0308, E0322, E0328, E0364, E0365, E0379, E0384,
E0403, E0404, E0407, E0415, E0416, E0424, E0426, E0428, E0429, E0430, E0431, E0433, E0434, E0435, E0437, E0438, E0449, E0451, E0463,
E0517, E0518, E0537, E0552, E0554, E0562, E0569, E0583, E0586, E0594,
Expand Down
25 changes: 25 additions & 0 deletions src/test/kotlin/org/rust/ide/annotator/RsMainWithGenericsTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

package org.rust.ide.annotator

class RsMainWithGenericsTest: RsAnnotatorTestBase(RsSyntaxErrorsAnnotator::class) {
fun `test E0131 type parameter`() = checkByText("""
fn main<error descr="`main` function is not allowed to have generic parameters [E0131]"><T></error>() { }
""")

fun `test E0131 lifetime parameter`() = checkByText("""
fn main<error descr="`main` function is not allowed to have generic parameters [E0131]"><'a></error>() { }
""")


fun `test E0131 const parameter`() = checkByText("""
fn main<error descr="`main` function is not allowed to have generic parameters [E0131]"><const A: i32></error>() { }
""")

fun `test E0131 without type parameters`() = checkByText("""
fn main() { }
""")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

package org.rust.ide.annotator

class RsMultipleRelaxedBoundsTest: RsAnnotatorTestBase(RsSyntaxErrorsAnnotator::class) {
fun `test E0203 sample`() = checkByText("""
struct Bad<<error descr="Type parameter has more than one relaxed default bound, only one is supported [E0203]">T: ?Sized + ?Send</error>>{
inner: T
}
""")

fun `test E0203 compiler test -- no-patterns-in-args-macro`() = checkByText("""
struct S5<<error descr="Type parameter has more than one relaxed default bound, only one is supported [E0203]">T</error>>(*const T) where T: ?Trait<'static> + ?Sized;
""")

fun `test E0203 where clause`() = checkByText("""
struct Bad<<error descr="Type parameter has more than one relaxed default bound, only one is supported [E0203]">T: ?Sized</error>> where T: ?Sized {
inner: T
}
""")
}
19 changes: 19 additions & 0 deletions src/test/kotlin/org/rust/ide/annotator/RsUnsafeInherentImplTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

package org.rust.ide.annotator

class RsUnsafeInherentImplTest: RsAnnotatorTestBase(RsSyntaxErrorsAnnotator::class) {
fun `test E0197`() = checkByText("""
struct Foo;
unsafe impl <error descr="Inherent impls cannot be unsafe [E0197]">Foo</error> { }
""")

fun `test E0197 unsafe with trait`() = checkByText("""
struct Foo;
unsafe trait Bar { }
unsafe impl Kek for Foo { }
""")
}