intellij-rust/intellij-rust 3543
Rust plugin for the IntelliJ Platform
intellij-rust/intellij-rust.github.io 64
Official website of IntelliJ-Rust project
jetbrains-academy/rustlings-course 50
Small exercises to get you used to reading and writing Rust code!
A roguelike game written in Kotlin using AsciiPanel
QuickCheck for Kotlin
Converter 2Dplans to LaTex code.
mchernyavsky/au-hp-fall-2017 0
Repository to store student's practical works on high performance computing course
created tagintellij-rust/intellij-rust
Rust plugin for the IntelliJ Platform
created time in 7 minutes
push eventintellij-rust/intellij-rust
commit sha 8fb826305576760d2db336df8080a36cd10b8fb6
INT: add intention to create a tuple struct
commit sha 927e613fb604dc1efb5f653dfb460c2dc646a87d
TYPE: highlight all 'await' when under the caret
commit sha dde4ea195969b73f2f8fbd44a825b9fe1b634c51
ANN: add quick fix to add function parameter from function call
commit sha 1a75e9ddad73bfcc76be10435daa12de4944ca02
RUN: Fix validation of input file
commit sha 5776c858acda4209cb3d63c45119084bcf669ead
INT: Introduce extract dependency in a separate table intention
commit sha c3da59df2f09739ca2f44492d204d89ca23294f9
GRAM: Parse asm! macro as expression This is needed to wrap an `asm!(...)` macro call into `RsExprStmt`. As a result, now `expandedStmtsAndTailExpr` contains `asm!(...)` macro calls.
commit sha 2ae13647b1d01cf0a8a27fb8465dbda21d9fcf8d
#7282: Process functions with built-in macro calls in liveness analysis Liveness analysis ignored functions containing built-in macro calls since https://github.com/intellij-rust/intellij-rust/pull/6876 because such macro calls do not have `expansion` anymore
commit sha b70d1166c3b8852393f3c77e01e337fbed89d718
#7213: Handle asm! macro calls in control flow Add very initial handling of `asm!(...)` macro calls during control flow graph building. Previously, `asm!(...)` macro calls caused `java.lang.IllegalStateException: unreachable`
commit sha 6b8f8e6a33ab557bc2431cfc8a8a0b9bd2a0d41b
#6045: Ignore functions with asm! macro calls during data-flow analysis Disable data-flow analysis on functions containing `asm!(...)` macro calls in order not to provide false positive errors and warnings, for example https://github.com/intellij-rust/intellij-rust/issues/5815 https://github.com/intellij-rust/intellij-rust/issues/6937
commit sha b403d8633dc12752d8fb07e75d4decfe79fe9ccc
Merge #7003 7003: INT: Introduce extract dependency in a separate table intention r=ortem a=avrong Depends on #6960 Part of #4869 Introduces intention to extract dependency specification written as an inline table to a separate table below. ### TODO - [x] Fix tests by providing a correct intention test base for TOML changelog: Add intention to extract dependency specification in a separate table in `Cargo.toml` Co-authored-by: Aleksei Trifonov <[email protected]>
commit sha de7a605cdc7f7ce7310b2328ec0b3bd5eea475c7
COMP: deduplicate method completion variants by name and trait
commit sha 4f262d2034ce76e749fd078c88015bccb5afbb24
Merge #7301 7301: COMP: deduplicate method completion variants by name and trait r=ortem a=vlad20012 Fixes #7238 changelog: Fix method duplication issue in completion list Co-authored-by: vlad20012 <[email protected]>
commit sha e8e81c36955b55277e20a7e0b2ad355062ad247e
REPL: Fix for Evcxr 0.10.0
commit sha 9513a040da54e97277cf879f09404e324f6a71eb
Update 212 dependencies and fix incompatibilities
commit sha d55d269d5df562b658718c79e0e101f419d45558
T: update Grazie tests
commit sha 6ef1661b894de104e8d7e11bb798c79eca9af23e
T: check rendering items of `Goto Implementation` action popup Including test for changes from #4676
commit sha 398cb6c03089cd22570d55cfe98093f9e4cefc1d
ACT: fix rendering items for `Goto Implementation` action on 2021.2 Also, use simple renderer for `Goto Implementation` action and line markers provided by `RsImplsLineMarkerProvider`
commit sha 72c7d6fde8fd75f4c87d95e214dc933e76598a70
Apply changes from #7271 and #7268 for 2021.2 sources
commit sha 5a43096e1b61e6b61febd63c2b21736a74a015fd
T: disable some move tests for 212 platform We will fix them later
commit sha 94728012b2852f0ac4f59b6aff94a830ee370014
Merge #7310 7310: Update 212 dependencies and fix incompatibilities r=Undin a=Undin Co-authored-by: Arseniy Pendryak <[email protected]>
push time in 7 hours
PR opened intellij-rust/intellij-rust
Previously, we tried to push into repo via https://{actor}:{token}@github.com/{repo}.git url. Found out that it doesn't work as expected and token provided in actions/checkout is used instead.
Now we:
- set proper token during checkout
- use intellij-rust-bot machine account to generate PAT and push such changes into repo
pr created time in 7 hours
create barnchintellij-rust/intellij-rust
created branch time in 7 hours
issue commentintellij-rust/intellij-rust
Tracking issue for procedural macro support
@webern Thank you for your example. I've filed a separate issue #7365 with it
comment created time in 7 hours
issue openedintellij-rust/intellij-rust
Support items generated by snafu derive macro
Here is the use-case:
Cargo.toml:
[package]
name = "snafu-jetbrains"
version = "0.1.0"
edition = "2018"
[dependencies]
snafu = "0.6"
main.rs
use snafu::Snafu;
/// The error type for this library.
#[derive(Debug, Snafu)]
enum Error {
#[snafu(display("This is always an error:: {}", message))]
AlwaysError { message: String },
}
fn hello_world() -> Result<(), Error> {
AlwaysError {
message: "this is a struct created by snafu",
}
.fail()
}
fn main() {
hello_world().unwrap()
}
Problem:

Desired behavior: code completion should be available for the struct AlwaysError:

Desired behavior: context actions should provide the ability to fill in missing struct fields for the AlwaysError struct.

Thank you! 🚀
Originally posted by @webern in https://github.com/intellij-rust/intellij-rust/issues/6908#issuecomment-860922178
created time in 7 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(target.getIcon(0))+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(target.getIcon(0))+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(target.getIcon(0))+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsFunction>() ?: return@withInsertHandler+ val body = element.block?.expr ?: return@withInsertHandler+ selectElement(body, context.editor)+ }
Thanks, I added it in https://github.com/intellij-rust/intellij-rust/pull/6342/commits/3d0807248d7e77a730f2fcf8e5c7393e3d32f2f8.
comment created time in 8 hours
issue commentintellij-rust/intellij-rust
Highlight other languages in macros and strings
I was experimenting a bit with this and IntelliJ Rust does support comments to hint at code injection. Like this:
// language=sql let query = "SELECT id FROM users;"Fortunately, this works on freestanding lines, but unfortunately, it doesn't work in
sqlxmacros because the argument must be a static string literal, which it no longer is when assigned to a variable. I tried putting the comment inline in the macro in a variety of ways, but couldn't get it to work.
Actually, this approach seems to work for literals themselves:

comment created time in 8 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.CONSTANT)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.TYPE_ALIAS)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(RsIcons.FUNCTION)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsFunction>() ?: return@withInsertHandler+ val body = element.block?.expr ?: return@withInsertHandler+ selectElement(body, context.editor)+ }+ .withPresentableText("$signature { ... }")
Good catch. What about ignoring where clauses (and maybe also generics, which can also be quite long)? By doing something like this:
fun RsFunction.getSignatureText(
subst: Substitution,
trait: BoundElement<RsTraitItem>,
impl: RsImplItem,
withWhereClause: Boolean = true,
withGenerics: Boolean = true
): String? {
comment created time in 9 hours
pull request commentintellij-rust/intellij-rust
ANN: correctly fill empty function call arguments
I rebased over master and changed the highlighting. Now the whole argument range offers the quick fix, but only the right parenthesis gets error annotation to reduce visual clutter. The changes in parsing also add additional error highlight to successive commas, which gets us the best of both worlds I think.
Can you take another look please @ortem? :) If you like it, I'll re-bless tests.

comment created time in 9 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.CONSTANT)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.TYPE_ALIAS)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(RsIcons.FUNCTION)
Yeah, I thought about icon for completed item that's why I wrote about some refactoring. But actually, I don't think it's important enough to make a lot of changes so let's use parent icon for now
comment created time in 9 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.CONSTANT)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.TYPE_ALIAS)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(RsIcons.FUNCTION)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsFunction>() ?: return@withInsertHandler+ val body = element.block?.expr ?: return@withInsertHandler+ selectElement(body, context.editor)+ }+ .withPresentableText("$signature { ... }")
Do we actually want to use raw $signature as presentable text?
It may produce quite weird text

comment created time in 9 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(target.getIcon(0))+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(target.getIcon(0))+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(target.getIcon(0))+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsFunction>() ?: return@withInsertHandler+ val body = element.block?.expr ?: return@withInsertHandler+ selectElement(body, context.editor)+ }
What's about auto import here?
For example, try to complete take method of std::io::Read
Currently, Take is not imported
But don't insist to do it in this PR
comment created time in 9 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.CONSTANT)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.TYPE_ALIAS)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(RsIcons.FUNCTION)
It's straightforward to use the icon of the parent item (https://github.com/intellij-rust/intellij-rust/pull/6342/commits/08aecd6a413fb5fc5957ec1bb44b5c019668d444). I'm not sure if it's better to show the parent or the completed item icon.
But for the latter, to reuse getIcon properly, we would probably need to construct a fake PSI element on the completed location and then get it's icon. It sounds hacky. Or we would need to refactor getIcon so that it doesn't need an existing PSI element.
comment created time in 9 hours
Pull request review commentintellij-rust/intellij-rust
COMP: add completion for impl trait items
+/*+ * Use of this source code is governed by the MIT license that can be+ * found in the LICENSE file.+ */++package org.rust.lang.core.completion++import com.intellij.codeInsight.completion.CompletionParameters+import com.intellij.codeInsight.completion.CompletionResultSet+import com.intellij.codeInsight.lookup.LookupElementBuilder+import com.intellij.patterns.ElementPattern+import com.intellij.psi.PsiElement+import com.intellij.psi.util.parentOfType+import com.intellij.util.ProcessingContext+import org.rust.ide.icons.RsIcons+import org.rust.ide.presentation.renderInsertionSafe+import org.rust.ide.refactoring.implementMembers.getSignatureText+import org.rust.lang.core.psi.*+import org.rust.lang.core.psi.ext.*+import org.rust.lang.core.resolve.knownItems+import org.rust.lang.core.types.BoundElement+import org.rust.lang.core.types.Substitution+import org.rust.lang.core.types.infer.substitute+import org.rust.lang.core.types.type+import org.rust.openapiext.selectElement++object RsImplTraitMemberCompletionProvider : RsCompletionProvider() {+ override val elementPattern: ElementPattern<PsiElement>+ get() {+ val contributor = RsKeywordCompletionContributor()+ return contributor.traitOrImplDeclarationPattern()+ }++ override fun addCompletions(+ parameters: CompletionParameters,+ context: ProcessingContext,+ result: CompletionResultSet+ ) {+ val element = parameters.position+ val implBlock = element.parentOfType<RsImplItem>() ?: return+ if (implBlock.traitRef == null) return++ val trait = implBlock.implementedTrait ?: return+ val members = trait.element.members ?: return++ val parentItems = members.expandedMembers.toMutableSet()+ for (item in implBlock.expandedMembers) {+ parentItems.removeIf { it.javaClass == item.javaClass && it.name == item.name }+ }++ for (item in parentItems) {+ val lookup = getCompletion(item, trait, implBlock) ?: continue+ result.addElement(+ lookup.withPriority(KEYWORD_PRIORITY + 1)+ )+ }+ }+}++private fun getCompletion(+ target: RsAbstractable,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder? {+ val substitution = trait.subst+ return when (target) {+ is RsConstant -> completeConstant(target, substitution)+ is RsTypeAlias -> completeType(target)+ is RsFunction -> completeFunction(target, trait, impl)+ else -> error("unreachable")+ }+}++private fun completeConstant(target: RsConstant, substitution: Substitution): LookupElementBuilder? {+ val text = buildString {+ append("const ")+ append(target.name)+ val type = target.typeReference?.type?.substitute(substitution) ?: return null+ append(": ")+ append(type.renderInsertionSafe())+ val builder = RsDefaultValueBuilder(target.knownItems, target.containingMod, RsPsiFactory(target.project))+ append(" = ")+ append(builder.buildFor(type, mapOf()).text)+ append(';')+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.CONSTANT)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsConstant>() ?: return@withInsertHandler+ val expr = element.expr ?: return@withInsertHandler+ selectElement(expr, context.editor)+ }+}++private fun completeType(target: RsTypeAlias): LookupElementBuilder {+ val text = buildString {+ append("type ")+ append(target.name)+ append(" = ();")+ }+ return LookupElementBuilder.create(text)+ .withIcon(RsIcons.TYPE_ALIAS)+ .withInsertHandler { context, _ ->+ val element = context.getElementOfType<RsTypeAlias>() ?: return@withInsertHandler+ val typeReference = element.typeReference ?: return@withInsertHandler+ selectElement(typeReference, context.editor)+ }+}++private fun completeFunction(+ target: RsFunction,+ trait: BoundElement<RsTraitItem>,+ impl: RsImplItem+): LookupElementBuilder {+ val substitution = trait.subst+ val signature = target.getSignatureText(substitution, trait, impl) ?: ""+ val text = "$signature{\n unimplemented!()\n }"+ return LookupElementBuilder+ .create(text)+ .withIcon(RsIcons.FUNCTION)
Maybe we can keep it simpler, because we know that the completion will only be in a certain situation? The owner will always be a trait, the abstractable will therefore always be public and non-abstract.
Ideally, I'd prefer a single place for such logic because if we decide to change something related to icons in the future, it would be great to modify only single place
But if you want, I can also extract these methods. What should I use as the flags in that case? Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS?
We use 0 during completion (see org.rust.lang.core.completion.LookupElementsKt#getLookupElementBuilder) so I suppose it's ok to use 0 here as well
comment created time in 9 hours
delete branch intellij-rust/intellij-rust
delete branch : format-specifier-color
delete time in 11 hours
delete branch intellij-rust/intellij-rust
delete branch : fix-rustdoc-whitespace-parsing
delete time in 11 hours
PR merged intellij-rust/intellij-rust
Previously, whitespace on the second line of this fragment was incorrectly parsed as 2 PsiWhiteSpace elements (" " and "\n"). Now it is parsed as a single " \n" whitespace element. The bug is since #6455
Replace . to a space
///.Extra space here:
///.
///
fn foo() {}
changelog: Should not be mentioned if in the same release as #6455
pr closed time in 11 hours
PR merged intellij-rust/intellij-rust
As discussed in https://github.com/intellij-rust/intellij-rust/pull/7243#issuecomment-863359497, rename FORMAT_SPECIFIER color to FORMAT_PARAMETER and introduce FORMAT_SPECIFIER color
https://user-images.githubusercontent.com/3221931/122535107-e63f2080-d02b-11eb-9554-b525f69b9690.mp4
pr closed time in 11 hours
pull request commentintellij-rust/intellij-rust
ANN: introduce a color for `std::fmt` format specifiers
Build succeeded:
comment created time in 11 hours
push eventintellij-rust/intellij-rust
commit sha 2debe2667c6a76f6c6e41c52adbf2f869658d10b
Fix rustdoc whitespace parsing Previously, whitespace on the second line of this fragment was incorrectly parsed as 2 `PsiWhiteSpace` elements (" " and "\n"). Now it is parsed as a single " \n" whitespace element. Replace `.` to a space ``` ///.Extra space here: ///. /// fn foo() {} ```
commit sha da1cb58fc86427d2639f9b9623fe2d8d3de294a8
ANN: introduce a color for `std::fmt` format specifiers
commit sha b43f45e658a8d50c298ee7cb31d307e2c0eef373
Merge #7362 #7364 7362: ANN: introduce a color for `std::fmt` format specifiers r=Kobzol a=vlad20012 As discussed in https://github.com/intellij-rust/intellij-rust/pull/7243#issuecomment-863359497, rename `FORMAT_SPECIFIER` color to `FORMAT_PARAMETER` and introduce `FORMAT_SPECIFIER` color https://user-images.githubusercontent.com/3221931/122535107-e63f2080-d02b-11eb-9554-b525f69b9690.mp4 7364: Fix rustdoc whitespace parsing r=vlad20012 a=vlad20012 Previously, whitespace on the second line of this fragment was incorrectly parsed as 2 `PsiWhiteSpace` elements (" " and "\n"). Now it is parsed as a single " \n" whitespace element. The bug is since #6455 Replace `.` to a space ``` ///.Extra space here: ///. /// fn foo() {} ``` changelog: Should not be mentioned if in the same release as #6455 Co-authored-by: vlad20012 <[email protected]>
push time in 11 hours
pull request commentintellij-rust/intellij-rust
Fix rustdoc whitespace parsing
Build succeeded:
comment created time in 11 hours
pull request commentintellij-rust/intellij-rust
Parse&resolve&complete rust paths in rustdoc links
I think that this closes https://github.com/intellij-rust/intellij-rust/issues/3591 and https://github.com/intellij-rust/intellij-rust/issues/4518?
comment created time in 12 hours
push eventintellij-rust/intellij-rust
commit sha 2debe2667c6a76f6c6e41c52adbf2f869658d10b
Fix rustdoc whitespace parsing Previously, whitespace on the second line of this fragment was incorrectly parsed as 2 `PsiWhiteSpace` elements (" " and "\n"). Now it is parsed as a single " \n" whitespace element. Replace `.` to a space ``` ///.Extra space here: ///. /// fn foo() {} ```
commit sha da1cb58fc86427d2639f9b9623fe2d8d3de294a8
ANN: introduce a color for `std::fmt` format specifiers
commit sha b43f45e658a8d50c298ee7cb31d307e2c0eef373
Merge #7362 #7364 7362: ANN: introduce a color for `std::fmt` format specifiers r=Kobzol a=vlad20012 As discussed in https://github.com/intellij-rust/intellij-rust/pull/7243#issuecomment-863359497, rename `FORMAT_SPECIFIER` color to `FORMAT_PARAMETER` and introduce `FORMAT_SPECIFIER` color https://user-images.githubusercontent.com/3221931/122535107-e63f2080-d02b-11eb-9554-b525f69b9690.mp4 7364: Fix rustdoc whitespace parsing r=vlad20012 a=vlad20012 Previously, whitespace on the second line of this fragment was incorrectly parsed as 2 `PsiWhiteSpace` elements (" " and "\n"). Now it is parsed as a single " \n" whitespace element. The bug is since #6455 Replace `.` to a space ``` ///.Extra space here: ///. /// fn foo() {} ``` changelog: Should not be mentioned if in the same release as #6455 Co-authored-by: vlad20012 <[email protected]>
push time in 12 hours
push eventintellij-rust/intellij-rust
commit sha 2debe2667c6a76f6c6e41c52adbf2f869658d10b
Fix rustdoc whitespace parsing Previously, whitespace on the second line of this fragment was incorrectly parsed as 2 `PsiWhiteSpace` elements (" " and "\n"). Now it is parsed as a single " \n" whitespace element. Replace `.` to a space ``` ///.Extra space here: ///. /// fn foo() {} ```
commit sha 50d013798b0bcd46992a38629667f2704a054cb6
[ci skip][skip ci][skip netlify] -bors-staging-tmp-7364
push time in 12 hours
push eventintellij-rust/intellij-rust
commit sha da1cb58fc86427d2639f9b9623fe2d8d3de294a8
ANN: introduce a color for `std::fmt` format specifiers
commit sha 846831e8a7c2e95cba376d254cf906ee115347fe
[ci skip][skip ci][skip netlify] -bors-staging-tmp-7362
push time in 12 hours
pull request commentintellij-rust/intellij-rust
Fix rustdoc whitespace parsing
bors r+
comment created time in 12 hours