aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/lib.rs12
-rw-r--r--crates/hir_def/src/body/lower.rs8
-rw-r--r--crates/hir_def/src/body/tests.rs2
-rw-r--r--crates/hir_def/src/diagnostics.rs5
-rw-r--r--crates/hir_def/src/lib.rs17
-rw-r--r--crates/hir_def/src/nameres.rs13
-rw-r--r--crates/hir_def/src/nameres/collector.rs9
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs8
-rw-r--r--crates/hir_def/src/nameres/tests/diagnostics.rs4
-rw-r--r--crates/hir_ty/src/lib.rs1
-rw-r--r--crates/hir_ty/src/tests/simple.rs18
-rw-r--r--crates/hir_ty/src/utils.rs2
-rw-r--r--crates/ide/src/diagnostics.rs2
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs22
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs23
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs22
-rw-r--r--crates/syntax/src/ast/make.rs18
17 files changed, 142 insertions, 44 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index eba46a056..0acfa582a 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2066,6 +2066,18 @@ impl Type {
2066 self.ty.dyn_trait().map(Into::into) 2066 self.ty.dyn_trait().map(Into::into)
2067 } 2067 }
2068 2068
2069 /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type,
2070 /// or an empty iterator otherwise.
2071 pub fn applicable_inherent_traits<'a>(
2072 &'a self,
2073 db: &'a dyn HirDatabase,
2074 ) -> impl Iterator<Item = Trait> + 'a {
2075 self.autoderef(db)
2076 .filter_map(|derefed_type| derefed_type.ty.dyn_trait())
2077 .flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db.upcast(), dyn_trait_id))
2078 .map(Trait::from)
2079 }
2080
2069 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2081 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2070 self.ty.impl_trait_bounds(db).map(|it| { 2082 self.ty.impl_trait_bounds(db).map(|it| {
2071 it.into_iter() 2083 it.into_iter()
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index ed07d6928..c0b0b7841 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -568,9 +568,13 @@ impl ExprCollector<'_> {
568 568
569 let res = match res { 569 let res = match res {
570 Ok(res) => res, 570 Ok(res) => res,
571 Err(UnresolvedMacro) => { 571 Err(UnresolvedMacro { path }) => {
572 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall( 572 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall(
573 UnresolvedMacroCall { file: outer_file, node: syntax_ptr.cast().unwrap() }, 573 UnresolvedMacroCall {
574 file: outer_file,
575 node: syntax_ptr.cast().unwrap(),
576 path,
577 },
574 )); 578 ));
575 collector(self, None); 579 collector(self, None);
576 return; 580 return;
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs
index c1d3e998f..63f5fe88d 100644
--- a/crates/hir_def/src/body/tests.rs
+++ b/crates/hir_def/src/body/tests.rs
@@ -180,7 +180,7 @@ fn unresolved_macro_diag() {
180 r#" 180 r#"
181fn f() { 181fn f() {
182 m!(); 182 m!();
183 //^^^^ unresolved macro call 183 //^^^^ unresolved macro `m!`
184} 184}
185 "#, 185 "#,
186 ); 186 );
diff --git a/crates/hir_def/src/diagnostics.rs b/crates/hir_def/src/diagnostics.rs
index 97abf8653..a71ae2668 100644
--- a/crates/hir_def/src/diagnostics.rs
+++ b/crates/hir_def/src/diagnostics.rs
@@ -8,7 +8,7 @@ use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink};
8use hir_expand::{HirFileId, InFile}; 8use hir_expand::{HirFileId, InFile};
9use syntax::{ast, AstPtr, SyntaxNodePtr, TextRange}; 9use syntax::{ast, AstPtr, SyntaxNodePtr, TextRange};
10 10
11use crate::{db::DefDatabase, DefWithBodyId}; 11use crate::{db::DefDatabase, path::ModPath, DefWithBodyId};
12 12
13pub fn validate_body(db: &dyn DefDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { 13pub fn validate_body(db: &dyn DefDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) {
14 let source_map = db.body_with_source_map(owner).1; 14 let source_map = db.body_with_source_map(owner).1;
@@ -103,6 +103,7 @@ impl Diagnostic for UnresolvedImport {
103pub struct UnresolvedMacroCall { 103pub struct UnresolvedMacroCall {
104 pub file: HirFileId, 104 pub file: HirFileId,
105 pub node: AstPtr<ast::MacroCall>, 105 pub node: AstPtr<ast::MacroCall>,
106 pub path: ModPath,
106} 107}
107 108
108impl Diagnostic for UnresolvedMacroCall { 109impl Diagnostic for UnresolvedMacroCall {
@@ -110,7 +111,7 @@ impl Diagnostic for UnresolvedMacroCall {
110 DiagnosticCode("unresolved-macro-call") 111 DiagnosticCode("unresolved-macro-call")
111 } 112 }
112 fn message(&self) -> String { 113 fn message(&self) -> String {
113 "unresolved macro call".to_string() 114 format!("unresolved macro `{}!`", self.path)
114 } 115 }
115 fn display_source(&self) -> InFile<SyntaxNodePtr> { 116 fn display_source(&self) -> InFile<SyntaxNodePtr> {
116 InFile::new(self.file, self.node.clone().into()) 117 InFile::new(self.file, self.node.clone().into())
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index ffee05500..000567d99 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -66,6 +66,7 @@ use hir_expand::{
66}; 66};
67use la_arena::Idx; 67use la_arena::Idx;
68use nameres::DefMap; 68use nameres::DefMap;
69use path::ModPath;
69use syntax::ast; 70use syntax::ast;
70 71
71use crate::builtin_type::BuiltinType; 72use crate::builtin_type::BuiltinType;
@@ -675,7 +676,9 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
675 } 676 }
676} 677}
677 678
678pub struct UnresolvedMacro; 679pub struct UnresolvedMacro {
680 pub path: ModPath,
681}
679 682
680fn macro_call_as_call_id( 683fn macro_call_as_call_id(
681 call: &AstIdWithPath<ast::MacroCall>, 684 call: &AstIdWithPath<ast::MacroCall>,
@@ -684,7 +687,8 @@ fn macro_call_as_call_id(
684 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 687 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
685 error_sink: &mut dyn FnMut(mbe::ExpandError), 688 error_sink: &mut dyn FnMut(mbe::ExpandError),
686) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { 689) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
687 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?; 690 let def: MacroDefId =
691 resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
688 692
689 let res = if let MacroDefKind::BuiltInEager(..) = def.kind { 693 let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
690 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast())); 694 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
@@ -714,8 +718,13 @@ fn derive_macro_as_call_id(
714 krate: CrateId, 718 krate: CrateId,
715 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 719 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
716) -> Result<MacroCallId, UnresolvedMacro> { 720) -> Result<MacroCallId, UnresolvedMacro> {
717 let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?; 721 let def: MacroDefId = resolver(item_attr.path.clone())
718 let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?; 722 .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
723 let last_segment = item_attr
724 .path
725 .segments()
726 .last()
727 .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
719 let res = def 728 let res = def
720 .as_lazy_macro( 729 .as_lazy_macro(
721 db.upcast(), 730 db.upcast(),
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 9e181751c..542f190a1 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -481,7 +481,7 @@ mod diagnostics {
481 481
482 UnresolvedProcMacro { ast: MacroCallKind }, 482 UnresolvedProcMacro { ast: MacroCallKind },
483 483
484 UnresolvedMacroCall { ast: AstId<ast::MacroCall> }, 484 UnresolvedMacroCall { ast: AstId<ast::MacroCall>, path: ModPath },
485 485
486 MacroError { ast: MacroCallKind, message: String }, 486 MacroError { ast: MacroCallKind, message: String },
487 } 487 }
@@ -546,8 +546,9 @@ mod diagnostics {
546 pub(super) fn unresolved_macro_call( 546 pub(super) fn unresolved_macro_call(
547 container: LocalModuleId, 547 container: LocalModuleId,
548 ast: AstId<ast::MacroCall>, 548 ast: AstId<ast::MacroCall>,
549 path: ModPath,
549 ) -> Self { 550 ) -> Self {
550 Self { in_module: container, kind: DiagnosticKind::UnresolvedMacroCall { ast } } 551 Self { in_module: container, kind: DiagnosticKind::UnresolvedMacroCall { ast, path } }
551 } 552 }
552 553
553 pub(super) fn add_to( 554 pub(super) fn add_to(
@@ -662,9 +663,13 @@ mod diagnostics {
662 }); 663 });
663 } 664 }
664 665
665 DiagnosticKind::UnresolvedMacroCall { ast } => { 666 DiagnosticKind::UnresolvedMacroCall { ast, path } => {
666 let node = ast.to_node(db.upcast()); 667 let node = ast.to_node(db.upcast());
667 sink.push(UnresolvedMacroCall { file: ast.file_id, node: AstPtr::new(&node) }); 668 sink.push(UnresolvedMacroCall {
669 file: ast.file_id,
670 node: AstPtr::new(&node),
671 path: path.clone(),
672 });
668 } 673 }
669 674
670 DiagnosticKind::MacroError { ast, message } => { 675 DiagnosticKind::MacroError { ast, message } => {
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index fb4ddff5e..05ceb1efb 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -829,7 +829,7 @@ impl DefCollector<'_> {
829 res = ReachedFixedPoint::No; 829 res = ReachedFixedPoint::No;
830 return false; 830 return false;
831 } 831 }
832 Err(UnresolvedMacro) | Ok(Err(_)) => {} 832 Err(UnresolvedMacro { .. }) | Ok(Err(_)) => {}
833 } 833 }
834 } 834 }
835 MacroDirectiveKind::Derive { ast_id, derive_attr } => { 835 MacroDirectiveKind::Derive { ast_id, derive_attr } => {
@@ -845,7 +845,7 @@ impl DefCollector<'_> {
845 res = ReachedFixedPoint::No; 845 res = ReachedFixedPoint::No;
846 return false; 846 return false;
847 } 847 }
848 Err(UnresolvedMacro) => (), 848 Err(UnresolvedMacro { .. }) => (),
849 } 849 }
850 } 850 }
851 } 851 }
@@ -943,10 +943,11 @@ impl DefCollector<'_> {
943 &mut |_| (), 943 &mut |_| (),
944 ) { 944 ) {
945 Ok(_) => (), 945 Ok(_) => (),
946 Err(UnresolvedMacro) => { 946 Err(UnresolvedMacro { path }) => {
947 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( 947 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
948 directive.module_id, 948 directive.module_id,
949 ast_id.ast_id, 949 ast_id.ast_id,
950 path,
950 )); 951 ));
951 } 952 }
952 }, 953 },
@@ -1530,7 +1531,7 @@ impl ModCollector<'_, '_> {
1530 )); 1531 ));
1531 return; 1532 return;
1532 } 1533 }
1533 Err(UnresolvedMacro) => (), 1534 Err(UnresolvedMacro { .. }) => (),
1534 } 1535 }
1535 1536
1536 // Case 2: resolve in module scope, expand during name resolution. 1537 // Case 2: resolve in module scope, expand during name resolution.
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index ccc9f22eb..c984148c3 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -387,7 +387,13 @@ impl DefMap {
387 .get_legacy_macro(name) 387 .get_legacy_macro(name)
388 .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public)); 388 .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
389 let from_scope = self[module].scope.get(name); 389 let from_scope = self[module].scope.get(name);
390 let from_builtin = BUILTIN_SCOPE.get(name).copied().unwrap_or_else(PerNs::none); 390 let from_builtin = match self.block {
391 Some(_) => {
392 // Only resolve to builtins in the root `DefMap`.
393 PerNs::none()
394 }
395 None => BUILTIN_SCOPE.get(name).copied().unwrap_or_else(PerNs::none),
396 };
391 let from_scope_or_builtin = match shadow { 397 let from_scope_or_builtin = match shadow {
392 BuiltinShadowMode::Module => from_scope.or(from_builtin), 398 BuiltinShadowMode::Module => from_scope.or(from_builtin),
393 BuiltinShadowMode::Other => { 399 BuiltinShadowMode::Other => {
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs
index 1ac88fc89..543975e07 100644
--- a/crates/hir_def/src/nameres/tests/diagnostics.rs
+++ b/crates/hir_def/src/nameres/tests/diagnostics.rs
@@ -170,7 +170,7 @@ fn unresolved_legacy_scope_macro() {
170 170
171 m!(); 171 m!();
172 m2!(); 172 m2!();
173 //^^^^^^ unresolved macro call 173 //^^^^^^ unresolved macro `self::m2!`
174 "#, 174 "#,
175 ); 175 );
176} 176}
@@ -187,7 +187,7 @@ fn unresolved_module_scope_macro() {
187 187
188 self::m!(); 188 self::m!();
189 self::m2!(); 189 self::m2!();
190 //^^^^^^^^^^^^ unresolved macro call 190 //^^^^^^^^^^^^ unresolved macro `self::m2!`
191 "#, 191 "#,
192 ); 192 );
193} 193}
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 113234fa4..0505fa4ae 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -56,6 +56,7 @@ pub use mapping::{
56 to_foreign_def_id, to_placeholder_idx, 56 to_foreign_def_id, to_placeholder_idx,
57}; 57};
58pub use traits::TraitEnvironment; 58pub use traits::TraitEnvironment;
59pub use utils::all_super_traits;
59pub use walk::TypeWalk; 60pub use walk::TypeWalk;
60 61
61pub use chalk_ir::{ 62pub use chalk_ir::{
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 84c5c05fd..5948d0bc2 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1765,6 +1765,24 @@ fn main() {
1765} 1765}
1766 1766
1767#[test] 1767#[test]
1768fn shadowing_primitive_with_inner_items() {
1769 check_types(
1770 r#"
1771struct i32;
1772struct Foo;
1773
1774impl i32 { fn foo(&self) -> Foo { Foo } }
1775
1776fn main() {
1777 fn inner() {}
1778 let x: i32 = i32;
1779 x.foo();
1780 //^ Foo
1781}"#,
1782 );
1783}
1784
1785#[test]
1768fn not_shadowing_primitive_by_module() { 1786fn not_shadowing_primitive_by_module() {
1769 check_types( 1787 check_types(
1770 r#" 1788 r#"
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 5f6cb052a..2f04ee57a 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -78,7 +78,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
78 78
79/// Returns an iterator over the whole super trait hierarchy (including the 79/// Returns an iterator over the whole super trait hierarchy (including the
80/// trait itself). 80/// trait itself).
81pub(super) fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 81pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
82 // we need to take care a bit here to avoid infinite loops in case of cycles 82 // we need to take care a bit here to avoid infinite loops in case of cycles
83 // (i.e. if we have `trait A: B; trait B: A;`) 83 // (i.e. if we have `trait A: B; trait B: A;`)
84 let mut result = vec![trait_]; 84 let mut result = vec![trait_];
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index 9a883acb9..1c911a8b2 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -725,7 +725,7 @@ fn test_fn() {
725 expect![[r#" 725 expect![[r#"
726 [ 726 [
727 Diagnostic { 727 Diagnostic {
728 message: "unresolved macro call", 728 message: "unresolved macro `foo::bar!`",
729 range: 5..8, 729 range: 5..8,
730 severity: Error, 730 severity: Error,
731 fix: None, 731 fix: None,
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index 878b3a3fa..80bd1b7e8 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -71,12 +71,6 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
71 return None; 71 return None;
72 } 72 }
73 73
74 // We do not currently support filling match arms for a tuple
75 // containing a single enum.
76 if enum_defs.len() < 2 {
77 return None;
78 }
79
80 // When calculating the match arms for a tuple of enums, we want 74 // When calculating the match arms for a tuple of enums, we want
81 // to create a match arm for each possible combination of enum 75 // to create a match arm for each possible combination of enum
82 // values. The `multi_cartesian_product` method transforms 76 // values. The `multi_cartesian_product` method transforms
@@ -514,10 +508,7 @@ fn main() {
514 508
515 #[test] 509 #[test]
516 fn fill_match_arms_single_element_tuple_of_enum() { 510 fn fill_match_arms_single_element_tuple_of_enum() {
517 // For now we don't hande the case of a single element tuple, but 511 check_assist(
518 // we could handle this in the future if `make::tuple_pat` allowed
519 // creating a tuple with a single pattern.
520 check_assist_not_applicable(
521 fill_match_arms, 512 fill_match_arms,
522 r#" 513 r#"
523 enum A { One, Two } 514 enum A { One, Two }
@@ -528,6 +519,17 @@ fn main() {
528 } 519 }
529 } 520 }
530 "#, 521 "#,
522 r#"
523 enum A { One, Two }
524
525 fn main() {
526 let a = A::One;
527 match (a, ) {
528 $0(A::One,) => {}
529 (A::Two,) => {}
530 }
531 }
532 "#,
531 ); 533 );
532 } 534 }
533 535
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index 5e61ecb4d..8e211ae1e 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -1127,4 +1127,27 @@ impl Bar for Foo {
1127 expect![[r#""#]], 1127 expect![[r#""#]],
1128 ); 1128 );
1129 } 1129 }
1130
1131 #[test]
1132 fn no_inherent_candidates_proposed() {
1133 check(
1134 r#"
1135mod baz {
1136 pub trait DefDatabase {
1137 fn method1(&self);
1138 }
1139 pub trait HirDatabase: DefDatabase {
1140 fn method2(&self);
1141 }
1142}
1143
1144mod bar {
1145 fn test(db: &dyn crate::baz::HirDatabase) {
1146 db.metho$0
1147 }
1148}
1149 "#,
1150 expect![[r#""#]],
1151 );
1152 }
1130} 1153}
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs
index 8ce648367..91d6a4665 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/helpers/import_assets.rs
@@ -436,6 +436,8 @@ fn trait_applicable_items(
436 }) 436 })
437 .collect(); 437 .collect();
438 438
439 let related_dyn_traits =
440 trait_candidate.receiver_ty.applicable_inherent_traits(db).collect::<FxHashSet<_>>();
439 let mut located_imports = FxHashSet::default(); 441 let mut located_imports = FxHashSet::default();
440 442
441 if trait_assoc_item { 443 if trait_assoc_item {
@@ -451,12 +453,16 @@ fn trait_applicable_items(
451 return None; 453 return None;
452 } 454 }
453 } 455 }
456 let located_trait = assoc.containing_trait(db)?;
457 if related_dyn_traits.contains(&located_trait) {
458 return None;
459 }
454 460
455 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); 461 let trait_item = ItemInNs::from(ModuleDef::from(located_trait));
456 let original_item = assoc_to_item(assoc); 462 let original_item = assoc_to_item(assoc);
457 located_imports.insert(LocatedImport::new( 463 located_imports.insert(LocatedImport::new(
458 mod_path(item)?, 464 mod_path(trait_item)?,
459 item, 465 trait_item,
460 original_item, 466 original_item,
461 mod_path(original_item), 467 mod_path(original_item),
462 )); 468 ));
@@ -473,11 +479,15 @@ fn trait_applicable_items(
473 |_, function| { 479 |_, function| {
474 let assoc = function.as_assoc_item(db)?; 480 let assoc = function.as_assoc_item(db)?;
475 if required_assoc_items.contains(&assoc) { 481 if required_assoc_items.contains(&assoc) {
476 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); 482 let located_trait = assoc.containing_trait(db)?;
483 if related_dyn_traits.contains(&located_trait) {
484 return None;
485 }
486 let trait_item = ItemInNs::from(ModuleDef::from(located_trait));
477 let original_item = assoc_to_item(assoc); 487 let original_item = assoc_to_item(assoc);
478 located_imports.insert(LocatedImport::new( 488 located_imports.insert(LocatedImport::new(
479 mod_path(item)?, 489 mod_path(trait_item)?,
480 item, 490 trait_item,
481 original_item, 491 original_item,
482 mod_path(original_item), 492 mod_path(original_item),
483 )); 493 ));
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index c6a7b99b7..94d4f2cf0 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -29,9 +29,13 @@ pub fn ty(text: &str) -> ast::Type {
29pub fn ty_unit() -> ast::Type { 29pub fn ty_unit() -> ast::Type {
30 ty("()") 30 ty("()")
31} 31}
32// FIXME: handle types of length == 1
33pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { 32pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
34 let contents = types.into_iter().join(", "); 33 let mut count: usize = 0;
34 let mut contents = types.into_iter().inspect(|_| count += 1).join(", ");
35 if count == 1 {
36 contents.push(',');
37 }
38
35 ty(&format!("({})", contents)) 39 ty(&format!("({})", contents))
36} 40}
37// FIXME: handle path to type 41// FIXME: handle path to type
@@ -292,11 +296,13 @@ pub fn wildcard_pat() -> ast::WildcardPat {
292 296
293/// Creates a tuple of patterns from an iterator of patterns. 297/// Creates a tuple of patterns from an iterator of patterns.
294/// 298///
295/// Invariant: `pats` must be length > 1 299/// Invariant: `pats` must be length > 0
296///
297/// FIXME handle `pats` length == 1
298pub fn tuple_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat { 300pub fn tuple_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat {
299 let pats_str = pats.into_iter().map(|p| p.to_string()).join(", "); 301 let mut count: usize = 0;
302 let mut pats_str = pats.into_iter().inspect(|_| count += 1).join(", ");
303 if count == 1 {
304 pats_str.push(',');
305 }
300 return from_text(&format!("({})", pats_str)); 306 return from_text(&format!("({})", pats_str));
301 307
302 fn from_text(text: &str) -> ast::TuplePat { 308 fn from_text(text: &str) -> ast::TuplePat {