From 03eeb8aae3b5bcefcd5b85c87bac01df516f7d79 Mon Sep 17 00:00:00 2001 From: kuksag Date: Fri, 20 Jan 2023 18:22:34 +0100 Subject: [PATCH] ANN: Add support for E0131, E0197, E0203 --- .../ide/annotator/RsSyntaxErrorsAnnotator.kt | 32 ++++++++++++++++ .../org/rust/lang/utils/RsDiagnostic.kt | 38 ++++++++++++++++++- .../ide/annotator/RsMainWithGenericsTest.kt | 25 ++++++++++++ .../annotator/RsMultipleRelaxedBoundsTest.kt | 24 ++++++++++++ .../ide/annotator/RsUnsafeInherentImplTest.kt | 19 ++++++++++ 5 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 src/test/kotlin/org/rust/ide/annotator/RsMainWithGenericsTest.kt create mode 100644 src/test/kotlin/org/rust/ide/annotator/RsMultipleRelaxedBoundsTest.kt create mode 100644 src/test/kotlin/org/rust/ide/annotator/RsUnsafeInherentImplTest.kt diff --git a/src/main/kotlin/org/rust/ide/annotator/RsSyntaxErrorsAnnotator.kt b/src/main/kotlin/org/rust/ide/annotator/RsSyntaxErrorsAnnotator.kt index 796977d0392..5315ecd0f36 100644 --- a/src/main/kotlin/org/rust/ide/annotator/RsSyntaxErrorsAnnotator.kt +++ b/src/main/kotlin/org/rust/ide/annotator/RsSyntaxErrorsAnnotator.kt @@ -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 @@ -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) @@ -51,6 +55,7 @@ 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) @@ -58,6 +63,22 @@ class RsSyntaxErrorsAnnotator : AnnotatorBase() { } } +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) } @@ -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) diff --git a/src/main/kotlin/org/rust/lang/utils/RsDiagnostic.kt b/src/main/kotlin/org/rust/lang/utils/RsDiagnostic.kt index ffb94c0acee..af8d0e208db 100644 --- a/src/main/kotlin/org/rust/lang/utils/RsDiagnostic.kt +++ b/src/main/kotlin/org/rust/lang/utils/RsDiagnostic.kt @@ -1625,12 +1625,46 @@ sealed class RsDiagnostic( "Patterns aren't allowed in functions without bodies", ) } + + class UnsafeInherentImplError( + element: PsiElement, + private val fixes: List + ) : RsDiagnostic(element) { + override fun prepare() = PreparedAnnotation ( + ERROR, + E0197, + "Inherent impls cannot be unsafe", + fixes = fixes + ) + } + + class MainWithGenericsError( + element: PsiElement, + private val fixes: List + ) : 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, diff --git a/src/test/kotlin/org/rust/ide/annotator/RsMainWithGenericsTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsMainWithGenericsTest.kt new file mode 100644 index 00000000000..711a1d7da48 --- /dev/null +++ b/src/test/kotlin/org/rust/ide/annotator/RsMainWithGenericsTest.kt @@ -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() { } + """) + + fun `test E0131 lifetime parameter`() = checkByText(""" + fn main<'a>() { } + """) + + + fun `test E0131 const parameter`() = checkByText(""" + fn main() { } + """) + + fun `test E0131 without type parameters`() = checkByText(""" + fn main() { } + """) +} diff --git a/src/test/kotlin/org/rust/ide/annotator/RsMultipleRelaxedBoundsTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsMultipleRelaxedBoundsTest.kt new file mode 100644 index 00000000000..b62d7c5950f --- /dev/null +++ b/src/test/kotlin/org/rust/ide/annotator/RsMultipleRelaxedBoundsTest.kt @@ -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<T: ?Sized + ?Send>{ + inner: T + } + """) + + fun `test E0203 compiler test -- no-patterns-in-args-macro`() = checkByText(""" + struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; + """) + + fun `test E0203 where clause`() = checkByText(""" + struct Bad<T: ?Sized> where T: ?Sized { + inner: T + } + """) +} diff --git a/src/test/kotlin/org/rust/ide/annotator/RsUnsafeInherentImplTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsUnsafeInherentImplTest.kt new file mode 100644 index 00000000000..812ff93be35 --- /dev/null +++ b/src/test/kotlin/org/rust/ide/annotator/RsUnsafeInherentImplTest.kt @@ -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 Foo { } + """) + + fun `test E0197 unsafe with trait`() = checkByText(""" + struct Foo; + unsafe trait Bar { } + unsafe impl Kek for Foo { } + """) +}