Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22465 from Veykril/push-loxpxnnrkruk
internal: Improve syntax mapping in for loop desugaring
| -rw-r--r-- | crates/hir-def/src/expr_store/lower.rs | 39 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/macros.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/never_type.rs | 12 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/patterns.rs | 4 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression.rs | 8 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/unimplemented_trait.rs | 16 | ||||
| -rw-r--r-- | crates/test-utils/src/lib.rs | 2 |
7 files changed, 56 insertions, 33 deletions
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index ef88188572..21b5b19986 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -2159,16 +2159,21 @@ impl<'db> ExprCollector<'db> { ) else { return self.missing_expr(); }; - let head = self.collect_expr_opt(e.iterable()); - let into_iter_fn_expr = self.alloc_expr(Expr::Path(into_iter_fn), syntax_ptr); - let iterator = self.alloc_expr( + let iterable = e.iterable(); + let syntax_ptr_iterable = iterable.as_ref().map_or(syntax_ptr, AstPtr::new); + let loop_body = e.loop_body().map(|it| it.into()); + let head = self.collect_expr_opt(iterable); + let into_iter_fn_expr = + self.alloc_expr_desugared_with_ptr(Expr::Path(into_iter_fn), syntax_ptr_iterable); + let iterator = self.alloc_expr_desugared_with_ptr( Expr::Call { callee: into_iter_fn_expr, args: Box::new([head]) }, - syntax_ptr, + syntax_ptr_iterable, ); let none_arm = MatchArm { pat: self.alloc_pat_desugared(Pat::Path(option_none)), guard: None, - expr: self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr), + expr: self + .alloc_expr_desugared_with_ptr(Expr::Break { expr: None, label: None }, syntax_ptr), }; let some_pat = Pat::TupleStruct { path: option_some, @@ -2181,26 +2186,26 @@ impl<'db> ExprCollector<'db> { let some_arm = MatchArm { pat: self.alloc_pat_desugared(some_pat), guard: None, - expr: self.with_opt_labeled_rib(label, |this| { - this.collect_expr_opt(e.loop_body().map(|it| it.into())) - }), + expr: self.with_opt_labeled_rib(label, |this| this.collect_expr_opt(loop_body)), }; let iter_name = self.generate_new_name(); - let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr); - let iter_expr_mut = self.alloc_expr( + let iter_expr = self + .alloc_expr_desugared_with_ptr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr); + let iter_expr_mut = self.alloc_expr_desugared_with_ptr( Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut }, syntax_ptr, ); - let iter_next_fn_expr = self.alloc_expr(Expr::Path(iter_next_fn), syntax_ptr); - let iter_next_expr = self.alloc_expr( + let iter_next_fn_expr = + self.alloc_expr_desugared_with_ptr(Expr::Path(iter_next_fn), syntax_ptr); + let iter_next_expr = self.alloc_expr_desugared_with_ptr( Expr::Call { callee: iter_next_fn_expr, args: Box::new([iter_expr_mut]) }, syntax_ptr, ); - let loop_inner = self.alloc_expr( + let loop_inner = self.alloc_expr_desugared_with_ptr( Expr::Match { expr: iter_next_expr, arms: Box::new([none_arm, some_arm]) }, syntax_ptr, ); - let loop_inner = self.alloc_expr( + let loop_inner = self.alloc_expr_desugared_with_ptr( Expr::Block { id: None, statements: Box::default(), @@ -2209,8 +2214,10 @@ impl<'db> ExprCollector<'db> { }, syntax_ptr, ); - let loop_outer = self - .alloc_expr(Expr::Loop { body: loop_inner, label: label.map(|it| it.1) }, syntax_ptr); + let loop_outer = self.alloc_expr_desugared_with_ptr( + Expr::Loop { body: loop_inner, label: label.map(|it| it.1) }, + syntax_ptr, + ); let iter_binding = self.alloc_binding(iter_name, BindingAnnotation::Mutable, HygieneId::ROOT); let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None }); diff --git a/crates/hir-ty/src/tests/macros.rs b/crates/hir-ty/src/tests/macros.rs index 28a688d4a3..f81028c174 100644 --- a/crates/hir-ty/src/tests/macros.rs +++ b/crates/hir-ty/src/tests/macros.rs @@ -196,8 +196,6 @@ fn expr_macro_def_expanded_in_various_places() { !0..6 '1isize': isize 39..442 '{ ...!(); }': {unknown} 73..94 'spam!(...am!())': {unknown} - 100..119 'for _ ...!() {}': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter - 100..119 'for _ ...!() {}': <isize as IntoIterator>::IntoIter 100..119 'for _ ...!() {}': ! 100..119 'for _ ...!() {}': {unknown} 100..119 'for _ ...!() {}': &'? mut {unknown} @@ -208,6 +206,8 @@ fn expr_macro_def_expanded_in_various_places() { 100..119 'for _ ...!() {}': () 100..119 'for _ ...!() {}': () 104..105 '_': {unknown} + 109..116 'spam!()': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter + 109..116 'spam!()': <isize as IntoIterator>::IntoIter 117..119 '{}': () 124..134 '|| spam!()': impl Fn() -> isize 140..156 'while ...!() {}': ! @@ -290,8 +290,6 @@ fn expr_macro_rules_expanded_in_various_places() { !0..6 '1isize': isize 53..456 '{ ...!(); }': {unknown} 87..108 'spam!(...am!())': {unknown} - 114..133 'for _ ...!() {}': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter - 114..133 'for _ ...!() {}': <isize as IntoIterator>::IntoIter 114..133 'for _ ...!() {}': ! 114..133 'for _ ...!() {}': {unknown} 114..133 'for _ ...!() {}': &'? mut {unknown} @@ -302,6 +300,8 @@ fn expr_macro_rules_expanded_in_various_places() { 114..133 'for _ ...!() {}': () 114..133 'for _ ...!() {}': () 118..119 '_': {unknown} + 123..130 'spam!()': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter + 123..130 'spam!()': <isize as IntoIterator>::IntoIter 131..133 '{}': () 138..148 '|| spam!()': impl Fn() -> isize 154..170 'while ...!() {}': ! diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs index 91273cd177..19a6a6b486 100644 --- a/crates/hir-ty/src/tests/never_type.rs +++ b/crates/hir-ty/src/tests/never_type.rs @@ -361,8 +361,6 @@ fn diverging_expression_3_break() { 97..343 '{ ...; }; }': () 140..141 'x': u32 149..175 '{ for ...; }; }': u32 - 151..172 'for a ...eak; }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter - 151..172 'for a ...eak; }': <{unknown} as IntoIterator>::IntoIter 151..172 'for a ...eak; }': ! 151..172 'for a ...eak; }': {unknown} 151..172 'for a ...eak; }': &'? mut {unknown} @@ -374,12 +372,12 @@ fn diverging_expression_3_break() { 151..172 'for a ...eak; }': () 155..156 'a': {unknown} 160..161 'b': {unknown} + 160..161 'b': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter + 160..161 'b': <{unknown} as IntoIterator>::IntoIter 162..172 '{ break; }': () 164..169 'break': ! 226..227 'x': u32 235..253 '{ for ... {}; }': u32 - 237..250 'for a in b {}': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter - 237..250 'for a in b {}': <{unknown} as IntoIterator>::IntoIter 237..250 'for a in b {}': ! 237..250 'for a in b {}': {unknown} 237..250 'for a in b {}': &'? mut {unknown} @@ -391,11 +389,11 @@ fn diverging_expression_3_break() { 237..250 'for a in b {}': () 241..242 'a': {unknown} 246..247 'b': {unknown} + 246..247 'b': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter + 246..247 'b': <{unknown} as IntoIterator>::IntoIter 248..250 '{}': () 304..305 'x': u32 313..340 '{ for ...; }; }': u32 - 315..337 'for a ...urn; }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter - 315..337 'for a ...urn; }': <{unknown} as IntoIterator>::IntoIter 315..337 'for a ...urn; }': ! 315..337 'for a ...urn; }': {unknown} 315..337 'for a ...urn; }': &'? mut {unknown} @@ -407,6 +405,8 @@ fn diverging_expression_3_break() { 315..337 'for a ...urn; }': () 319..320 'a': {unknown} 324..325 'b': {unknown} + 324..325 'b': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter + 324..325 'b': <{unknown} as IntoIterator>::IntoIter 326..337 '{ return; }': () 328..334 'return': ! 149..175: expected u32, got () diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs index e719f43e74..c48112ee81 100644 --- a/crates/hir-ty/src/tests/patterns.rs +++ b/crates/hir-ty/src/tests/patterns.rs @@ -47,8 +47,6 @@ fn infer_pattern() { 82..94 '(1, "hello")': (i32, &'? str) 83..84 '1': i32 86..93 '"hello"': &'static str - 101..150 'for (e... }': fn into_iter<[(i32, i32); 1]>([(i32, i32); 1]) -> <[(i32, i32); 1] as IntoIterator>::IntoIter - 101..150 'for (e... }': IntoIter<(i32, i32), 1> 101..150 'for (e... }': ! 101..150 'for (e... }': IntoIter<(i32, i32), 1> 101..150 'for (e... }': &'? mut IntoIter<(i32, i32), 1> @@ -62,6 +60,8 @@ fn infer_pattern() { 106..107 'e': i32 109..110 'f': i32 115..123 '[(0, 1)]': [(i32, i32); 1] + 115..123 '[(0, 1)]': fn into_iter<[(i32, i32); 1]>([(i32, i32); 1]) -> <[(i32, i32); 1] as IntoIterator>::IntoIter + 115..123 '[(0, 1)]': IntoIter<(i32, i32), 1> 116..122 '(0, 1)': (i32, i32) 117..118 '0': i32 120..121 '1': i32 diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index 5a90e700ac..c1c714f8d4 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -270,8 +270,6 @@ fn infer_std_crash_5() { "#, expect![[r#" 26..322 '{ ... } }': () - 32..320 'for co... }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter - 32..320 'for co... }': <{unknown} as IntoIterator>::IntoIter 32..320 'for co... }': ! 32..320 'for co... }': {unknown} 32..320 'for co... }': &'? mut {unknown} @@ -283,6 +281,8 @@ fn infer_std_crash_5() { 32..320 'for co... }': () 36..43 'content': &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? {unknown} 47..60 'doesnt_matter': {unknown} + 47..60 'doesnt_matter': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter + 47..60 'doesnt_matter': <{unknown} as IntoIterator>::IntoIter 61..320 '{ ... }': () 75..79 'name': &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? {unknown} 82..166 'if doe... }': &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? &'? {unknown} @@ -1261,8 +1261,6 @@ fn test() { "#, expect![[r#" 10..68 '{ ... } }': () - 16..66 'for _ ... }': fn into_iter<()>(()) -> <() as IntoIterator>::IntoIter - 16..66 'for _ ... }': <() as IntoIterator>::IntoIter 16..66 'for _ ... }': ! 16..66 'for _ ... }': {unknown} 16..66 'for _ ... }': &'? mut {unknown} @@ -1274,6 +1272,8 @@ fn test() { 16..66 'for _ ... }': () 20..21 '_': {unknown} 25..39 '{ let x = 0; }': () + 25..39 '{ let x = 0; }': fn into_iter<()>(()) -> <() as IntoIterator>::IntoIter + 25..39 '{ let x = 0; }': <() as IntoIterator>::IntoIter 31..32 'x': i32 35..36 '0': i32 40..66 '{ ... }': () diff --git a/crates/ide-diagnostics/src/handlers/unimplemented_trait.rs b/crates/ide-diagnostics/src/handlers/unimplemented_trait.rs index d94ceef642..4a253bc831 100644 --- a/crates/ide-diagnostics/src/handlers/unimplemented_trait.rs +++ b/crates/ide-diagnostics/src/handlers/unimplemented_trait.rs @@ -69,4 +69,20 @@ fn foo() { "#, ); } + + #[test] + fn for_iterable() { + check_diagnostics( + r#" +//- minicore: iterator +fn foo() { + for _ in () {} + // ^^ error: the trait bound `(): Iterator` is not satisfied + // ^^ error: the trait bound `(): Iterator` is not satisfied + // | required by the bound `(): IntoIterator` +} + + "#, + ); + } } diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs index 62867fd5b5..4eab7f4b18 100644 --- a/crates/test-utils/src/lib.rs +++ b/crates/test-utils/src/lib.rs @@ -260,7 +260,7 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { let &(_, idx) = prev_line_annotations .iter() .find(|&&(off, _idx)| off == offset) - .unwrap(); + .expect("annotation continuation not found"); res[idx].1.push('\n'); res[idx].1.push_str(&content); res[idx].1.push('\n'); |