Skip to content

Commit

Permalink
Merge #10066
Browse files Browse the repository at this point in the history
10066: ANN: Add support for E0131, E0197, E0203 r=vlad20012 a=kuksag

<!--
Hello and thank you for the pull request!

We don't have any strict rules about pull requests, but you might check
https://github.com/intellij-rust/intellij-rust/blob/master/CONTRIBUTING.md
for some hints!

Also, please write a short description explaining your change in the following format: `changelog: %description%`
This description will help a lot to create release changelog. 
Drop these lines for internal only changes

:)
-->

changelog:

* Add support for E0131
Error code reference: https://doc.rust-lang.org/error_codes/E0131.html
There's a feature that might be connected to this error code: rust-lang/rust#29633

* Add support for E0197
Error code reference: https://doc.rust-lang.org/error_codes/E0197.html

* Add support for E0203
Error code reference: https://doc.rust-lang.org/error_codes/E0203.html
Compiler implementation: https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_analysis/src/astconv/mod.rs#L877


Co-authored-by: kuksag <georgiy.kuksa@gmail.com>
  • Loading branch information
bors[bot] and kuksag authored Feb 3, 2023
2 parents 03d191d + db602a6 commit 0ed57b3
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 2 deletions.
31 changes: 31 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,16 @@ private fun checkMacroCall(holder: AnnotationHolder, element: RsMacroCall) {
}

private fun checkFunction(holder: AnnotationHolder, fn: RsFunction) {
if (fn.isMain && fn.getGenericParameters().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 { }
""")
}

0 comments on commit 0ed57b3

Please sign in to comment.