aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_def/src/nameres/collector.rs6
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs22
-rw-r--r--crates/ide_assists/src/handlers/add_explicit_type.rs25
3 files changed, 46 insertions, 7 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 0e741194b..be645a25d 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -367,6 +367,8 @@ impl DefCollector<'_> {
367 /// This improves UX when proc macros are turned off or don't work, and replicates the behavior 367 /// This improves UX when proc macros are turned off or don't work, and replicates the behavior
368 /// before we supported proc. attribute macros. 368 /// before we supported proc. attribute macros.
369 fn reseed_with_unresolved_attributes(&mut self) -> ReachedFixedPoint { 369 fn reseed_with_unresolved_attributes(&mut self) -> ReachedFixedPoint {
370 cov_mark::hit!(unresolved_attribute_fallback);
371
370 let mut added_items = false; 372 let mut added_items = false;
371 let unexpanded_macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); 373 let unexpanded_macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
372 for directive in &unexpanded_macros { 374 for directive in &unexpanded_macros {
@@ -391,7 +393,9 @@ impl DefCollector<'_> {
391 added_items = true; 393 added_items = true;
392 } 394 }
393 } 395 }
394 self.unexpanded_macros = unexpanded_macros; 396
397 // The collection above might add new unresolved macros (eg. derives), so merge the lists.
398 self.unexpanded_macros.extend(unexpanded_macros);
395 399
396 if added_items { 400 if added_items {
397 // Continue name resolution with the new data. 401 // Continue name resolution with the new data.
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index c37f915ab..b34ba885d 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -686,6 +686,27 @@ pub trait Clone {}
686} 686}
687 687
688#[test] 688#[test]
689fn builtin_derive_with_unresolved_attributes_fall_back() {
690 // Tests that we still resolve derives after ignoring an unresolved attribute.
691 cov_mark::check!(unresolved_attribute_fallback);
692 let map = compute_crate_def_map(
693 r#"
694 //- /main.rs crate:main deps:core
695 use core::Clone;
696
697 #[derive(Clone)]
698 #[unresolved]
699 struct Foo;
700
701 //- /core.rs crate:core
702 #[rustc_builtin_macro]
703 pub macro Clone {}
704 "#,
705 );
706 assert_eq!(map.modules[map.root].scope.impls().len(), 1);
707}
708
709#[test]
689fn macro_expansion_overflow() { 710fn macro_expansion_overflow() {
690 cov_mark::check!(macro_expansion_overflow); 711 cov_mark::check!(macro_expansion_overflow);
691 check( 712 check(
@@ -842,7 +863,6 @@ fn collects_derive_helpers() {
842fn resolve_macro_def() { 863fn resolve_macro_def() {
843 check( 864 check(
844 r#" 865 r#"
845//- /lib.rs
846pub macro structs($($i:ident),*) { 866pub macro structs($($i:ident),*) {
847 $(struct $i { field: u32 } )* 867 $(struct $i { field: u32 } )*
848} 868}
diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs
index 36589203d..b7617ca3d 100644
--- a/crates/ide_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ide_assists/src/handlers/add_explicit_type.rs
@@ -1,6 +1,6 @@
1use hir::HirDisplay; 1use hir::HirDisplay;
2use syntax::{ 2use syntax::{
3 ast::{self, AstNode, LetStmt, NameOwner}, 3 ast::{self, AstNode, LetStmt},
4 TextRange, 4 TextRange,
5}; 5};
6 6
@@ -31,9 +31,6 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
31 _ => return None, 31 _ => return None,
32 }; 32 };
33 let pat_range = pat.syntax().text_range(); 33 let pat_range = pat.syntax().text_range();
34 // The binding must have a name
35 let name = pat.name()?;
36 let name_range = name.syntax().text_range();
37 34
38 // Assist should only be applicable if cursor is between 'let' and '=' 35 // Assist should only be applicable if cursor is between 'let' and '='
39 let cursor_in_range = { 36 let cursor_in_range = {
@@ -74,7 +71,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
74 builder.replace(ascribed_ty.syntax().text_range(), inferred_type); 71 builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
75 } 72 }
76 None => { 73 None => {
77 builder.insert(name_range.end(), format!(": {}", inferred_type)); 74 builder.insert(pat_range.end(), format!(": {}", inferred_type));
78 } 75 }
79 }, 76 },
80 ) 77 )
@@ -246,4 +243,22 @@ fn main() {
246"#, 243"#,
247 ); 244 );
248 } 245 }
246
247 #[test]
248 fn type_should_be_added_after_pattern() {
249 // LetStmt = Attr* 'let' Pat (':' Type)? '=' initializer:Expr ';'
250 check_assist(
251 add_explicit_type,
252 r#"
253fn main() {
254 let $0test @ () = ();
255}
256"#,
257 r#"
258fn main() {
259 let test @ (): () = ();
260}
261"#,
262 );
263 }
249} 264}