diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-10-30 14:42:53 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-30 14:42:53 +0000 |
| commit | 7765c1a94f4e93e76f0977a52b434f673aa97831 (patch) | |
| tree | b11cec330f779f14cf96429e113bd52edf62386a | |
| parent | 3ad83cc08db5123401fd6786a10319f540879a8e (diff) | |
| parent | c93983e76f0617d495053913d96e557d72f66c81 (diff) | |
| download | rust-7765c1a94f4e93e76f0977a52b434f673aa97831.tar.gz rust-7765c1a94f4e93e76f0977a52b434f673aa97831.zip | |
Merge #10668
10668: fix: Fix for-loop expressions breaking with BlockExpr iterable r=Veykril a=Veykril Fixes https://github.com/rust-analyzer/rust-analyzer/issues/10665 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
| -rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 24 | ||||
| -rw-r--r-- | crates/syntax/src/ast/generated/nodes.rs | 1 | ||||
| -rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 9 | ||||
| -rw-r--r-- | crates/syntax/src/tests/sourcegen_ast.rs | 15 |
4 files changed, 44 insertions, 5 deletions
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 67952edca38..4a0a5d6fa1f 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -1221,3 +1221,27 @@ fn mamba(a: U32!(), p: u32) -> u32 { "#, ) } + +#[test] +fn for_loop_block_expr_iterable() { + check_infer( + r#" +fn test() { + for _ in { let x = 0; } { + let y = 0; + } +} + "#, + expect![[r#" + 10..68 '{ ... } }': () + 16..66 'for _ ... }': () + 20..21 '_': {unknown} + 25..39 '{ let x = 0; }': () + 31..32 'x': i32 + 35..36 '0': i32 + 40..66 '{ ... }': () + 54..55 'y': i32 + 58..59 '0': i32 + "#]], + ); +} diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 005e78c48a1..18a6e1410dd 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -850,7 +850,6 @@ pub struct ForExpr { pub(crate) syntax: SyntaxNode, } impl ast::HasAttrs for ForExpr {} -impl ast::HasLoopBody for ForExpr {} impl ForExpr { pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) } pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) } diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 2e6544f090e..98d142da3f7 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -754,6 +754,15 @@ impl ast::GenericParamList { } } +impl ast::HasLoopBody for ast::ForExpr { + fn loop_body(&self) -> Option<ast::BlockExpr> { + let mut exprs = support::children(self.syntax()); + let first = exprs.next(); + let second = exprs.next(); + second.or(first) + } +} + impl ast::HasDocComments for ast::SourceFile {} impl ast::HasDocComments for ast::Fn {} impl ast::HasDocComments for ast::Struct {} diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs index 36fedd2f0bc..dcd813bbe03 100644 --- a/crates/syntax/src/tests/sourcegen_ast.rs +++ b/crates/syntax/src/tests/sourcegen_ast.rs @@ -81,10 +81,17 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { .map(|node| { let name = format_ident!("{}", node.name); let kind = format_ident!("{}", to_upper_snake_case(&node.name)); - let traits = node.traits.iter().map(|trait_name| { - let trait_name = format_ident!("{}", trait_name); - quote!(impl ast::#trait_name for #name {}) - }); + let traits = node + .traits + .iter() + .filter(|trait_name| { + // For loops have two expressions so this might collide, therefor manual impl it + node.name != "ForExpr" || trait_name.as_str() != "HasLoopBody" + }) + .map(|trait_name| { + let trait_name = format_ident!("{}", trait_name); + quote!(impl ast::#trait_name for #name {}) + }); let methods = node.fields.iter().map(|field| { let method_name = field.method_name(); |
