aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/base_db/src/input.rs2
-rw-r--r--crates/cfg/src/dnf.rs8
-rw-r--r--crates/hir/src/display.rs2
-rw-r--r--crates/hir/src/lib.rs153
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/hir_def/src/nameres/collector.rs13
-rw-r--r--crates/hir_def/src/nameres/mod_resolution.rs13
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs21
-rw-r--r--crates/hir_def/src/resolver.rs2
-rw-r--r--crates/hir_expand/src/builtin_macro.rs66
-rw-r--r--crates/hir_expand/src/db.rs2
-rw-r--r--crates/hir_expand/src/eager.rs13
-rw-r--r--crates/hir_expand/src/lib.rs23
-rw-r--r--crates/hir_expand/src/name.rs5
-rw-r--r--crates/hir_ty/src/autoderef.rs51
-rw-r--r--crates/hir_ty/src/db.rs11
-rw-r--r--crates/hir_ty/src/display.rs59
-rw-r--r--crates/hir_ty/src/infer.rs2
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs27
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs66
-rw-r--r--crates/hir_ty/src/lib.rs105
-rw-r--r--crates/hir_ty/src/lower.rs73
-rw-r--r--crates/hir_ty/src/method_resolution.rs53
-rw-r--r--crates/hir_ty/src/tests.rs69
-rw-r--r--crates/hir_ty/src/tests/macros.rs23
-rw-r--r--crates/hir_ty/src/tests/patterns.rs22
-rw-r--r--crates/hir_ty/src/tests/traits.rs50
-rw-r--r--crates/hir_ty/src/traits.rs17
-rw-r--r--crates/hir_ty/src/traits/chalk.rs12
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs124
-rw-r--r--crates/hir_ty/src/utils.rs2
-rw-r--r--crates/ide/src/extend_selection.rs7
-rw-r--r--crates/ide_assists/src/handlers/convert_comment_block.rs5
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs19
-rw-r--r--crates/ide_assists/src/handlers/reorder_impl.rs2
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs31
-rw-r--r--crates/ide_completion/src/context.rs6
-rw-r--r--crates/ide_completion/src/patterns.rs2
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs4
-rw-r--r--crates/ide_ssr/src/parsing.rs2
-rw-r--r--crates/mbe/src/expander/matcher.rs9
-rw-r--r--crates/mbe/src/lib.rs2
-rw-r--r--crates/mbe/src/parser.rs2
-rw-r--r--crates/mbe/src/syntax_bridge.rs2
-rw-r--r--crates/mbe/src/tests/expand.rs3
-rw-r--r--crates/project_model/src/build_data.rs91
-rw-r--r--crates/rust-analyzer/src/caps.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs3
-rw-r--r--crates/rust-analyzer/src/main_loop.rs7
-rw-r--r--crates/rust-analyzer/src/reload.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs6
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs2
-rw-r--r--crates/syntax/src/algo.rs4
-rw-r--r--crates/syntax/src/ast/edit.rs8
-rw-r--r--crates/syntax/src/ast/expr_ext.rs44
-rw-r--r--crates/syntax/src/ast/make.rs2
-rw-r--r--crates/syntax/src/ast/node_ext.rs19
-rw-r--r--crates/syntax/src/ast/token_ext.rs5
-rw-r--r--crates/syntax/src/fuzz.rs2
-rw-r--r--crates/syntax/src/validation.rs4
-rw-r--r--crates/tt/src/lib.rs3
63 files changed, 923 insertions, 508 deletions
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index d0def2181..e9e8dfc2e 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -410,7 +410,7 @@ impl CrateId {
410 410
411impl CrateData { 411impl CrateData {
412 fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { 412 fn add_dep(&mut self, name: CrateName, crate_id: CrateId) {
413 self.dependencies.push(Dependency { name, crate_id }) 413 self.dependencies.push(Dependency { crate_id, name })
414 } 414 }
415} 415}
416 416
diff --git a/crates/cfg/src/dnf.rs b/crates/cfg/src/dnf.rs
index 30f4bcdf7..75ded9aa1 100644
--- a/crates/cfg/src/dnf.rs
+++ b/crates/cfg/src/dnf.rs
@@ -255,9 +255,9 @@ impl Builder {
255fn make_dnf(expr: CfgExpr) -> CfgExpr { 255fn make_dnf(expr: CfgExpr) -> CfgExpr {
256 match expr { 256 match expr {
257 CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr, 257 CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr,
258 CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(|expr| make_dnf(expr)).collect()), 258 CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(make_dnf).collect()),
259 CfgExpr::All(e) => { 259 CfgExpr::All(e) => {
260 let e = e.into_iter().map(|expr| make_nnf(expr)).collect::<Vec<_>>(); 260 let e = e.into_iter().map(make_nnf).collect::<Vec<_>>();
261 261
262 CfgExpr::Any(distribute_conj(&e)) 262 CfgExpr::Any(distribute_conj(&e))
263 } 263 }
@@ -300,8 +300,8 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
300fn make_nnf(expr: CfgExpr) -> CfgExpr { 300fn make_nnf(expr: CfgExpr) -> CfgExpr {
301 match expr { 301 match expr {
302 CfgExpr::Invalid | CfgExpr::Atom(_) => expr, 302 CfgExpr::Invalid | CfgExpr::Atom(_) => expr,
303 CfgExpr::Any(expr) => CfgExpr::Any(expr.into_iter().map(|expr| make_nnf(expr)).collect()), 303 CfgExpr::Any(expr) => CfgExpr::Any(expr.into_iter().map(make_nnf).collect()),
304 CfgExpr::All(expr) => CfgExpr::All(expr.into_iter().map(|expr| make_nnf(expr)).collect()), 304 CfgExpr::All(expr) => CfgExpr::All(expr.into_iter().map(make_nnf).collect()),
305 CfgExpr::Not(operand) => match *operand { 305 CfgExpr::Not(operand) => match *operand {
306 CfgExpr::Invalid | CfgExpr::Atom(_) => CfgExpr::Not(operand.clone()), // Original negated expr 306 CfgExpr::Invalid | CfgExpr::Atom(_) => CfgExpr::Not(operand.clone()), // Original negated expr
307 CfgExpr::Not(expr) => { 307 CfgExpr::Not(expr) => {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 9f6d7be48..97a78ca25 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -217,7 +217,7 @@ impl HirDisplay for Variant {
217 217
218impl HirDisplay for Type { 218impl HirDisplay for Type {
219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
220 self.ty.value.hir_fmt(f) 220 self.ty.hir_fmt(f)
221 } 221 }
222} 222}
223 223
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index e34be7e42..30b96d7e2 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -56,9 +56,9 @@ use hir_ty::{
56 primitive::UintTy, 56 primitive::UintTy,
57 to_assoc_type_id, 57 to_assoc_type_id,
58 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex, 59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
60 InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind, 60 DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar,
61 TyVariableKind, WhereClause, 61 Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause,
62}; 62};
63use itertools::Itertools; 63use itertools::Itertools;
64use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -213,7 +213,7 @@ impl Crate {
213 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), 213 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
214 _ => None 214 _ => None
215 } 215 }
216 }).flat_map(|t| t).next(); 216 }).flatten().next();
217 217
218 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") 218 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
219 } 219 }
@@ -851,13 +851,7 @@ impl Function {
851 .iter() 851 .iter()
852 .enumerate() 852 .enumerate()
853 .map(|(idx, type_ref)| { 853 .map(|(idx, type_ref)| {
854 let ty = Type { 854 let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
855 krate,
856 ty: InEnvironment {
857 value: ctx.lower_ty(type_ref),
858 environment: environment.clone(),
859 },
860 };
861 Param { func: self, ty, idx } 855 Param { func: self, ty, idx }
862 }) 856 })
863 .collect() 857 .collect()
@@ -1460,7 +1454,7 @@ impl TypeParam {
1460 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { 1454 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
1461 db.generic_predicates_for_param(self.id) 1455 db.generic_predicates_for_param(self.id)
1462 .into_iter() 1456 .into_iter()
1463 .filter_map(|pred| match &pred.value { 1457 .filter_map(|pred| match &pred.skip_binders().skip_binders() {
1464 hir_ty::WhereClause::Implemented(trait_ref) => { 1458 hir_ty::WhereClause::Implemented(trait_ref) => {
1465 Some(Trait::from(trait_ref.hir_trait_id())) 1459 Some(Trait::from(trait_ref.hir_trait_id()))
1466 } 1460 }
@@ -1540,8 +1534,8 @@ impl Impl {
1540 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1534 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1541 } 1535 }
1542 1536
1543 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { 1537 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
1544 let def_crates = match ty.value.def_crates(db, krate) { 1538 let def_crates = match ty.def_crates(db, krate) {
1545 Some(def_crates) => def_crates, 1539 Some(def_crates) => def_crates,
1546 None => return Vec::new(), 1540 None => return Vec::new(),
1547 }; 1541 };
@@ -1549,14 +1543,14 @@ impl Impl {
1549 let filter = |impl_def: &Impl| { 1543 let filter = |impl_def: &Impl| {
1550 let target_ty = impl_def.target_ty(db); 1544 let target_ty = impl_def.target_ty(db);
1551 let rref = target_ty.remove_ref(); 1545 let rref = target_ty.remove_ref();
1552 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) 1546 ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty))
1553 }; 1547 };
1554 1548
1555 let mut all = Vec::new(); 1549 let mut all = Vec::new();
1556 def_crates.iter().for_each(|&id| { 1550 def_crates.iter().for_each(|&id| {
1557 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) 1551 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1558 }); 1552 });
1559 let fp = TyFingerprint::for_impl(&ty.value); 1553 let fp = TyFingerprint::for_impl(&ty);
1560 for id in def_crates 1554 for id in def_crates
1561 .iter() 1555 .iter()
1562 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) 1556 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
@@ -1643,7 +1637,8 @@ impl Impl {
1643#[derive(Clone, PartialEq, Eq, Debug)] 1637#[derive(Clone, PartialEq, Eq, Debug)]
1644pub struct Type { 1638pub struct Type {
1645 krate: CrateId, 1639 krate: CrateId,
1646 ty: InEnvironment<Ty>, 1640 env: Arc<TraitEnvironment>,
1641 ty: Ty,
1647} 1642}
1648 1643
1649impl Type { 1644impl Type {
@@ -1663,14 +1658,14 @@ impl Type {
1663 ) -> Type { 1658 ) -> Type {
1664 let environment = 1659 let environment =
1665 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1660 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1666 Type { krate, ty: InEnvironment { value: ty, environment } } 1661 Type { krate, env: environment, ty }
1667 } 1662 }
1668 1663
1669 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { 1664 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1670 let resolver = lexical_env.resolver(db.upcast()); 1665 let resolver = lexical_env.resolver(db.upcast());
1671 let environment = 1666 let environment =
1672 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1667 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1673 Type { krate, ty: InEnvironment { value: ty, environment } } 1668 Type { krate, env: environment, ty }
1674 } 1669 }
1675 1670
1676 fn from_def( 1671 fn from_def(
@@ -1684,29 +1679,29 @@ impl Type {
1684 } 1679 }
1685 1680
1686 pub fn is_unit(&self) -> bool { 1681 pub fn is_unit(&self) -> bool {
1687 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) 1682 matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..))
1688 } 1683 }
1689 pub fn is_bool(&self) -> bool { 1684 pub fn is_bool(&self) -> bool {
1690 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) 1685 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1691 } 1686 }
1692 1687
1693 pub fn is_mutable_reference(&self) -> bool { 1688 pub fn is_mutable_reference(&self) -> bool {
1694 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) 1689 matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1695 } 1690 }
1696 1691
1697 pub fn is_usize(&self) -> bool { 1692 pub fn is_usize(&self) -> bool {
1698 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) 1693 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1699 } 1694 }
1700 1695
1701 pub fn remove_ref(&self) -> Option<Type> { 1696 pub fn remove_ref(&self) -> Option<Type> {
1702 match &self.ty.value.interned(&Interner) { 1697 match &self.ty.interned(&Interner) {
1703 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), 1698 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
1704 _ => None, 1699 _ => None,
1705 } 1700 }
1706 } 1701 }
1707 1702
1708 pub fn is_unknown(&self) -> bool { 1703 pub fn is_unknown(&self) -> bool {
1709 self.ty.value.is_unknown() 1704 self.ty.is_unknown()
1710 } 1705 }
1711 1706
1712 /// Checks that particular type `ty` implements `std::future::Future`. 1707 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1723,11 +1718,12 @@ impl Type {
1723 None => return false, 1718 None => return false,
1724 }; 1719 };
1725 1720
1726 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1721 let canonical_ty =
1722 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1727 method_resolution::implements_trait( 1723 method_resolution::implements_trait(
1728 &canonical_ty, 1724 &canonical_ty,
1729 db, 1725 db,
1730 self.ty.environment.clone(), 1726 self.env.clone(),
1731 krate, 1727 krate,
1732 std_future_trait, 1728 std_future_trait,
1733 ) 1729 )
@@ -1745,11 +1741,12 @@ impl Type {
1745 None => return false, 1741 None => return false,
1746 }; 1742 };
1747 1743
1748 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1744 let canonical_ty =
1745 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1749 method_resolution::implements_trait_unique( 1746 method_resolution::implements_trait_unique(
1750 &canonical_ty, 1747 &canonical_ty,
1751 db, 1748 db,
1752 self.ty.environment.clone(), 1749 self.env.clone(),
1753 krate, 1750 krate,
1754 fnonce_trait, 1751 fnonce_trait,
1755 ) 1752 )
@@ -1759,17 +1756,14 @@ impl Type {
1759 let trait_ref = hir_ty::TraitRef { 1756 let trait_ref = hir_ty::TraitRef {
1760 trait_id: hir_ty::to_chalk_trait_id(trait_.id), 1757 trait_id: hir_ty::to_chalk_trait_id(trait_.id),
1761 substitution: Substitution::build_for_def(db, trait_.id) 1758 substitution: Substitution::build_for_def(db, trait_.id)
1762 .push(self.ty.value.clone()) 1759 .push(self.ty.clone())
1763 .fill(args.iter().map(|t| t.ty.value.clone())) 1760 .fill(args.iter().map(|t| t.ty.clone()))
1764 .build(), 1761 .build(),
1765 }; 1762 };
1766 1763
1767 let goal = Canonical { 1764 let goal = Canonical {
1768 value: hir_ty::InEnvironment::new( 1765 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
1769 self.ty.environment.clone(), 1766 binders: CanonicalVarKinds::empty(&Interner),
1770 trait_ref.cast(&Interner),
1771 ),
1772 kinds: Arc::new([]),
1773 }; 1767 };
1774 1768
1775 db.trait_solve(self.krate, goal).is_some() 1769 db.trait_solve(self.krate, goal).is_some()
@@ -1783,12 +1777,12 @@ impl Type {
1783 alias: TypeAlias, 1777 alias: TypeAlias,
1784 ) -> Option<Type> { 1778 ) -> Option<Type> {
1785 let subst = Substitution::build_for_def(db, trait_.id) 1779 let subst = Substitution::build_for_def(db, trait_.id)
1786 .push(self.ty.value.clone()) 1780 .push(self.ty.clone())
1787 .fill(args.iter().map(|t| t.ty.value.clone())) 1781 .fill(args.iter().map(|t| t.ty.clone()))
1788 .build(); 1782 .build();
1789 let goal = Canonical { 1783 let goal = Canonical::new(
1790 value: InEnvironment::new( 1784 InEnvironment::new(
1791 self.ty.environment.clone(), 1785 self.env.env.clone(),
1792 AliasEq { 1786 AliasEq {
1793 alias: AliasTy::Projection(ProjectionTy { 1787 alias: AliasTy::Projection(ProjectionTy {
1794 associated_ty_id: to_assoc_type_id(alias.id), 1788 associated_ty_id: to_assoc_type_id(alias.id),
@@ -1799,8 +1793,8 @@ impl Type {
1799 } 1793 }
1800 .cast(&Interner), 1794 .cast(&Interner),
1801 ), 1795 ),
1802 kinds: Arc::new([TyVariableKind::General]), 1796 [TyVariableKind::General].iter().copied(),
1803 }; 1797 );
1804 1798
1805 match db.trait_solve(self.krate, goal)? { 1799 match db.trait_solve(self.krate, goal)? {
1806 Solution::Unique(SolutionVariables(subst)) => { 1800 Solution::Unique(SolutionVariables(subst)) => {
@@ -1820,22 +1814,22 @@ impl Type {
1820 } 1814 }
1821 1815
1822 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1816 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1823 let def = self.ty.value.callable_def(db); 1817 let def = self.ty.callable_def(db);
1824 1818
1825 let sig = self.ty.value.callable_sig(db)?; 1819 let sig = self.ty.callable_sig(db)?;
1826 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) 1820 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1827 } 1821 }
1828 1822
1829 pub fn is_closure(&self) -> bool { 1823 pub fn is_closure(&self) -> bool {
1830 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) 1824 matches!(&self.ty.interned(&Interner), TyKind::Closure { .. })
1831 } 1825 }
1832 1826
1833 pub fn is_fn(&self) -> bool { 1827 pub fn is_fn(&self) -> bool {
1834 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) 1828 matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1835 } 1829 }
1836 1830
1837 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1831 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1838 let adt_id = match self.ty.value.interned(&Interner) { 1832 let adt_id = match self.ty.interned(&Interner) {
1839 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1833 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1840 _ => return false, 1834 _ => return false,
1841 }; 1835 };
@@ -1848,11 +1842,11 @@ impl Type {
1848 } 1842 }
1849 1843
1850 pub fn is_raw_ptr(&self) -> bool { 1844 pub fn is_raw_ptr(&self) -> bool {
1851 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) 1845 matches!(&self.ty.interned(&Interner), TyKind::Raw(..))
1852 } 1846 }
1853 1847
1854 pub fn contains_unknown(&self) -> bool { 1848 pub fn contains_unknown(&self) -> bool {
1855 return go(&self.ty.value); 1849 return go(&self.ty);
1856 1850
1857 fn go(ty: &Ty) -> bool { 1851 fn go(ty: &Ty) -> bool {
1858 match ty.interned(&Interner) { 1852 match ty.interned(&Interner) {
@@ -1884,7 +1878,7 @@ impl Type {
1884 } 1878 }
1885 1879
1886 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1880 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1887 let (variant_id, substs) = match self.ty.value.interned(&Interner) { 1881 let (variant_id, substs) = match self.ty.interned(&Interner) {
1888 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1882 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1889 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1883 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1890 _ => return Vec::new(), 1884 _ => return Vec::new(),
@@ -1901,7 +1895,7 @@ impl Type {
1901 } 1895 }
1902 1896
1903 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1897 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1904 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { 1898 if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
1905 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1899 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1906 } else { 1900 } else {
1907 Vec::new() 1901 Vec::new()
@@ -1911,9 +1905,10 @@ impl Type {
1911 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1905 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1912 // There should be no inference vars in types passed here 1906 // There should be no inference vars in types passed here
1913 // FIXME check that? 1907 // FIXME check that?
1914 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1908 let canonical =
1915 let environment = self.ty.environment.clone(); 1909 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1916 let ty = InEnvironment { value: canonical, environment }; 1910 let environment = self.env.env.clone();
1911 let ty = InEnvironment { goal: canonical, environment };
1917 autoderef(db, Some(self.krate), ty) 1912 autoderef(db, Some(self.krate), ty)
1918 .map(|canonical| canonical.value) 1913 .map(|canonical| canonical.value)
1919 .map(move |ty| self.derived(ty)) 1914 .map(move |ty| self.derived(ty))
@@ -1927,10 +1922,10 @@ impl Type {
1927 krate: Crate, 1922 krate: Crate,
1928 mut callback: impl FnMut(AssocItem) -> Option<T>, 1923 mut callback: impl FnMut(AssocItem) -> Option<T>,
1929 ) -> Option<T> { 1924 ) -> Option<T> {
1930 for krate in self.ty.value.def_crates(db, krate.id)? { 1925 for krate in self.ty.def_crates(db, krate.id)? {
1931 let impls = db.inherent_impls_in_crate(krate); 1926 let impls = db.inherent_impls_in_crate(krate);
1932 1927
1933 for impl_def in impls.for_self_ty(&self.ty.value) { 1928 for impl_def in impls.for_self_ty(&self.ty) {
1934 for &item in db.impl_data(*impl_def).items.iter() { 1929 for &item in db.impl_data(*impl_def).items.iter() {
1935 if let Some(result) = callback(item.into()) { 1930 if let Some(result) = callback(item.into()) {
1936 return Some(result); 1931 return Some(result);
@@ -1943,7 +1938,6 @@ impl Type {
1943 1938
1944 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1939 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1945 self.ty 1940 self.ty
1946 .value
1947 .strip_references() 1941 .strip_references()
1948 .substs() 1942 .substs()
1949 .into_iter() 1943 .into_iter()
@@ -1962,9 +1956,10 @@ impl Type {
1962 // There should be no inference vars in types passed here 1956 // There should be no inference vars in types passed here
1963 // FIXME check that? 1957 // FIXME check that?
1964 // FIXME replace Unknown by bound vars here 1958 // FIXME replace Unknown by bound vars here
1965 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1959 let canonical =
1960 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1966 1961
1967 let env = self.ty.environment.clone(); 1962 let env = self.env.clone();
1968 let krate = krate.id; 1963 let krate = krate.id;
1969 1964
1970 method_resolution::iterate_method_candidates( 1965 method_resolution::iterate_method_candidates(
@@ -1993,9 +1988,10 @@ impl Type {
1993 // There should be no inference vars in types passed here 1988 // There should be no inference vars in types passed here
1994 // FIXME check that? 1989 // FIXME check that?
1995 // FIXME replace Unknown by bound vars here 1990 // FIXME replace Unknown by bound vars here
1996 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1991 let canonical =
1992 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1997 1993
1998 let env = self.ty.environment.clone(); 1994 let env = self.env.clone();
1999 let krate = krate.id; 1995 let krate = krate.id;
2000 1996
2001 method_resolution::iterate_method_candidates( 1997 method_resolution::iterate_method_candidates(
@@ -2011,18 +2007,18 @@ impl Type {
2011 } 2007 }
2012 2008
2013 pub fn as_adt(&self) -> Option<Adt> { 2009 pub fn as_adt(&self) -> Option<Adt> {
2014 let (adt, _subst) = self.ty.value.as_adt()?; 2010 let (adt, _subst) = self.ty.as_adt()?;
2015 Some(adt.into()) 2011 Some(adt.into())
2016 } 2012 }
2017 2013
2018 pub fn as_dyn_trait(&self) -> Option<Trait> { 2014 pub fn as_dyn_trait(&self) -> Option<Trait> {
2019 self.ty.value.dyn_trait().map(Into::into) 2015 self.ty.dyn_trait().map(Into::into)
2020 } 2016 }
2021 2017
2022 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2018 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2023 self.ty.value.impl_trait_bounds(db).map(|it| { 2019 self.ty.impl_trait_bounds(db).map(|it| {
2024 it.into_iter() 2020 it.into_iter()
2025 .filter_map(|pred| match pred { 2021 .filter_map(|pred| match pred.skip_binders() {
2026 hir_ty::WhereClause::Implemented(trait_ref) => { 2022 hir_ty::WhereClause::Implemented(trait_ref) => {
2027 Some(Trait::from(trait_ref.hir_trait_id())) 2023 Some(Trait::from(trait_ref.hir_trait_id()))
2028 } 2024 }
@@ -2033,14 +2029,11 @@ impl Type {
2033 } 2029 }
2034 2030
2035 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> { 2031 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
2036 self.ty.value.associated_type_parent_trait(db).map(Into::into) 2032 self.ty.associated_type_parent_trait(db).map(Into::into)
2037 } 2033 }
2038 2034
2039 fn derived(&self, ty: Ty) -> Type { 2035 fn derived(&self, ty: Ty) -> Type {
2040 Type { 2036 Type { krate: self.krate, env: self.env.clone(), ty }
2041 krate: self.krate,
2042 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
2043 }
2044 } 2037 }
2045 2038
2046 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { 2039 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
@@ -2061,14 +2054,17 @@ impl Type {
2061 fn walk_bounds( 2054 fn walk_bounds(
2062 db: &dyn HirDatabase, 2055 db: &dyn HirDatabase,
2063 type_: &Type, 2056 type_: &Type,
2064 bounds: &[WhereClause], 2057 bounds: &[QuantifiedWhereClause],
2065 cb: &mut impl FnMut(Type), 2058 cb: &mut impl FnMut(Type),
2066 ) { 2059 ) {
2067 for pred in bounds { 2060 for pred in bounds {
2068 match pred { 2061 match pred.skip_binders() {
2069 WhereClause::Implemented(trait_ref) => { 2062 WhereClause::Implemented(trait_ref) => {
2070 cb(type_.clone()); 2063 cb(type_.clone());
2071 walk_substs(db, type_, &trait_ref.substitution, cb); 2064 // skip the self type. it's likely the type we just got the bounds from
2065 for ty in trait_ref.substitution.iter().skip(1) {
2066 walk_type(db, &type_.derived(ty.clone()), cb);
2067 }
2072 } 2068 }
2073 _ => (), 2069 _ => (),
2074 } 2070 }
@@ -2076,7 +2072,7 @@ impl Type {
2076 } 2072 }
2077 2073
2078 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2074 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
2079 let ty = type_.ty.value.strip_references(); 2075 let ty = type_.ty.strip_references();
2080 match ty.interned(&Interner) { 2076 match ty.interned(&Interner) {
2081 TyKind::Adt(..) => { 2077 TyKind::Adt(..) => {
2082 cb(type_.derived(ty.clone())); 2078 cb(type_.derived(ty.clone()));
@@ -2104,7 +2100,12 @@ impl Type {
2104 } 2100 }
2105 } 2101 }
2106 TyKind::Dyn(bounds) => { 2102 TyKind::Dyn(bounds) => {
2107 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 2103 walk_bounds(
2104 db,
2105 &type_.derived(ty.clone()),
2106 bounds.bounds.skip_binders().interned(),
2107 cb,
2108 );
2108 } 2109 }
2109 2110
2110 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { 2111 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 2c10f46d8..52a2bce9b 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -638,7 +638,7 @@ fn collect_attrs(
638 owner: &dyn ast::AttrsOwner, 638 owner: &dyn ast::AttrsOwner,
639) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { 639) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> {
640 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) 640 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
641 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); 641 .map_or((None, None), |(attrs, docs)| (Some(attrs), Some(docs)));
642 642
643 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); 643 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
644 let attrs = outer_attrs 644 let attrs = outer_attrs
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 46a3c60cd..28b73c3a1 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -1467,12 +1467,13 @@ impl ModCollector<'_, '_> {
1467 }, 1467 },
1468 ) { 1468 ) {
1469 Ok(Ok(macro_call_id)) => { 1469 Ok(Ok(macro_call_id)) => {
1470 self.def_collector.unexpanded_macros.push(MacroDirective { 1470 // Legacy macros need to be expanded immediately, so that any macros they produce
1471 module_id: self.module_id, 1471 // are in scope.
1472 ast_id, 1472 self.def_collector.collect_macro_expansion(
1473 legacy: Some(macro_call_id), 1473 self.module_id,
1474 depth: self.macro_depth + 1, 1474 macro_call_id,
1475 }); 1475 self.macro_depth + 1,
1476 );
1476 1477
1477 return; 1478 return;
1478 } 1479 }
diff --git a/crates/hir_def/src/nameres/mod_resolution.rs b/crates/hir_def/src/nameres/mod_resolution.rs
index d5de9899c..d9cec0e27 100644
--- a/crates/hir_def/src/nameres/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/mod_resolution.rs
@@ -62,7 +62,7 @@ impl ModDir {
62 name: &Name, 62 name: &Name,
63 attr_path: Option<&SmolStr>, 63 attr_path: Option<&SmolStr>,
64 ) -> Result<(FileId, bool, ModDir), String> { 64 ) -> Result<(FileId, bool, ModDir), String> {
65 let file_id = file_id.original_file(db.upcast()); 65 let orig_file_id = file_id.original_file(db.upcast());
66 66
67 let mut candidate_files = Vec::new(); 67 let mut candidate_files = Vec::new();
68 match attr_path { 68 match attr_path {
@@ -70,13 +70,18 @@ impl ModDir {
70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner)) 70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
71 } 71 }
72 None => { 72 None => {
73 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name)); 73 if file_id.is_include_macro(db.upcast()) {
74 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name)); 74 candidate_files.push(format!("{}.rs", name));
75 candidate_files.push(format!("{}/mod.rs", name));
76 } else {
77 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
78 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
79 }
75 } 80 }
76 }; 81 };
77 82
78 for candidate in candidate_files.iter() { 83 for candidate in candidate_files.iter() {
79 let path = AnchoredPath { anchor: file_id, path: candidate.as_str() }; 84 let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() };
80 if let Some(file_id) = db.resolve_path(path) { 85 if let Some(file_id) = db.resolve_path(path) {
81 let is_mod_rs = candidate.ends_with("/mod.rs"); 86 let is_mod_rs = candidate.ends_with("/mod.rs");
82 87
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index d59d3c0db..6d3cb8d7a 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -713,6 +713,27 @@ b! { static = #[] ();}
713} 713}
714 714
715#[test] 715#[test]
716fn macros_defining_macros() {
717 check(
718 r#"
719macro_rules! item {
720 ($item:item) => { $item }
721}
722
723item! {
724 macro_rules! indirect_macro { () => { struct S {} } }
725}
726
727indirect_macro!();
728 "#,
729 expect![[r#"
730 crate
731 S: t
732 "#]],
733 );
734}
735
736#[test]
716fn resolves_proc_macros() { 737fn resolves_proc_macros() {
717 check( 738 check(
718 r" 739 r"
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 4a2d1c087..04ea9c5d7 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -472,7 +472,7 @@ impl Scope {
472 } 472 }
473 Scope::ExprScope(scope) => { 473 Scope::ExprScope(scope) => {
474 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) { 474 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {
475 f(name.clone(), ScopeDef::Label(label)) 475 f(name, ScopeDef::Label(label))
476 } 476 }
477 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { 477 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
478 f(e.name().clone(), ScopeDef::Local(e.pat())); 478 f(e.name().clone(), ScopeDef::Local(e.pat()));
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 8529b43b6..4d52904b9 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -43,7 +43,7 @@ macro_rules! register_builtin {
43 db: &dyn AstDatabase, 43 db: &dyn AstDatabase,
44 arg_id: EagerMacroId, 44 arg_id: EagerMacroId,
45 tt: &tt::Subtree, 45 tt: &tt::Subtree,
46 ) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 46 ) -> ExpandResult<Option<ExpandedEager>> {
47 let expander = match *self { 47 let expander = match *self {
48 $( EagerExpander::$e_kind => $e_expand, )* 48 $( EagerExpander::$e_kind => $e_expand, )*
49 }; 49 };
@@ -61,6 +61,20 @@ macro_rules! register_builtin {
61 }; 61 };
62} 62}
63 63
64#[derive(Debug)]
65pub struct ExpandedEager {
66 pub(crate) subtree: tt::Subtree,
67 pub(crate) fragment: FragmentKind,
68 /// The included file ID of the include macro.
69 pub(crate) included_file: Option<FileId>,
70}
71
72impl ExpandedEager {
73 fn new(subtree: tt::Subtree, fragment: FragmentKind) -> Self {
74 ExpandedEager { subtree, fragment, included_file: None }
75 }
76}
77
64pub fn find_builtin_macro( 78pub fn find_builtin_macro(
65 ident: &name::Name, 79 ident: &name::Name,
66 krate: CrateId, 80 krate: CrateId,
@@ -280,7 +294,7 @@ fn compile_error_expand(
280 _db: &dyn AstDatabase, 294 _db: &dyn AstDatabase,
281 _id: EagerMacroId, 295 _id: EagerMacroId,
282 tt: &tt::Subtree, 296 tt: &tt::Subtree,
283) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 297) -> ExpandResult<Option<ExpandedEager>> {
284 let err = match &*tt.token_trees { 298 let err = match &*tt.token_trees {
285 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => { 299 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => {
286 let text = it.text.as_str(); 300 let text = it.text.as_str();
@@ -294,14 +308,14 @@ fn compile_error_expand(
294 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()), 308 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
295 }; 309 };
296 310
297 ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) } 311 ExpandResult { value: Some(ExpandedEager::new(quote! {}, FragmentKind::Items)), err: Some(err) }
298} 312}
299 313
300fn concat_expand( 314fn concat_expand(
301 _db: &dyn AstDatabase, 315 _db: &dyn AstDatabase,
302 _arg_id: EagerMacroId, 316 _arg_id: EagerMacroId,
303 tt: &tt::Subtree, 317 tt: &tt::Subtree,
304) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 318) -> ExpandResult<Option<ExpandedEager>> {
305 let mut err = None; 319 let mut err = None;
306 let mut text = String::new(); 320 let mut text = String::new();
307 for (i, t) in tt.token_trees.iter().enumerate() { 321 for (i, t) in tt.token_trees.iter().enumerate() {
@@ -325,7 +339,7 @@ fn concat_expand(
325 } 339 }
326 } 340 }
327 } 341 }
328 ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err } 342 ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err }
329} 343}
330 344
331fn relative_file( 345fn relative_file(
@@ -361,21 +375,27 @@ fn include_expand(
361 db: &dyn AstDatabase, 375 db: &dyn AstDatabase,
362 arg_id: EagerMacroId, 376 arg_id: EagerMacroId,
363 tt: &tt::Subtree, 377 tt: &tt::Subtree,
364) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 378) -> ExpandResult<Option<ExpandedEager>> {
365 let res = (|| { 379 let res = (|| {
366 let path = parse_string(tt)?; 380 let path = parse_string(tt)?;
367 let file_id = relative_file(db, arg_id.into(), &path, false)?; 381 let file_id = relative_file(db, arg_id.into(), &path, false)?;
368 382
369 Ok(parse_to_token_tree(&db.file_text(file_id)) 383 let subtree = parse_to_token_tree(&db.file_text(file_id))
370 .ok_or_else(|| mbe::ExpandError::ConversionError)? 384 .ok_or_else(|| mbe::ExpandError::ConversionError)?
371 .0) 385 .0;
386 Ok((subtree, file_id))
372 })(); 387 })();
373 388
374 match res { 389 match res {
375 Ok(res) => { 390 Ok((subtree, file_id)) => {
376 // FIXME: 391 // FIXME:
377 // Handle include as expression 392 // Handle include as expression
378 ExpandResult::ok(Some((res, FragmentKind::Items))) 393
394 ExpandResult::ok(Some(ExpandedEager {
395 subtree,
396 fragment: FragmentKind::Items,
397 included_file: Some(file_id),
398 }))
379 } 399 }
380 Err(e) => ExpandResult::only_err(e), 400 Err(e) => ExpandResult::only_err(e),
381 } 401 }
@@ -385,7 +405,7 @@ fn include_bytes_expand(
385 _db: &dyn AstDatabase, 405 _db: &dyn AstDatabase,
386 _arg_id: EagerMacroId, 406 _arg_id: EagerMacroId,
387 tt: &tt::Subtree, 407 tt: &tt::Subtree,
388) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 408) -> ExpandResult<Option<ExpandedEager>> {
389 if let Err(e) = parse_string(tt) { 409 if let Err(e) = parse_string(tt) {
390 return ExpandResult::only_err(e); 410 return ExpandResult::only_err(e);
391 } 411 }
@@ -398,14 +418,14 @@ fn include_bytes_expand(
398 id: tt::TokenId::unspecified(), 418 id: tt::TokenId::unspecified(),
399 }))], 419 }))],
400 }; 420 };
401 ExpandResult::ok(Some((res, FragmentKind::Expr))) 421 ExpandResult::ok(Some(ExpandedEager::new(res, FragmentKind::Expr)))
402} 422}
403 423
404fn include_str_expand( 424fn include_str_expand(
405 db: &dyn AstDatabase, 425 db: &dyn AstDatabase,
406 arg_id: EagerMacroId, 426 arg_id: EagerMacroId,
407 tt: &tt::Subtree, 427 tt: &tt::Subtree,
408) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 428) -> ExpandResult<Option<ExpandedEager>> {
409 let path = match parse_string(tt) { 429 let path = match parse_string(tt) {
410 Ok(it) => it, 430 Ok(it) => it,
411 Err(e) => return ExpandResult::only_err(e), 431 Err(e) => return ExpandResult::only_err(e),
@@ -418,14 +438,14 @@ fn include_str_expand(
418 let file_id = match relative_file(db, arg_id.into(), &path, true) { 438 let file_id = match relative_file(db, arg_id.into(), &path, true) {
419 Ok(file_id) => file_id, 439 Ok(file_id) => file_id,
420 Err(_) => { 440 Err(_) => {
421 return ExpandResult::ok(Some((quote!(""), FragmentKind::Expr))); 441 return ExpandResult::ok(Some(ExpandedEager::new(quote!(""), FragmentKind::Expr)));
422 } 442 }
423 }; 443 };
424 444
425 let text = db.file_text(file_id); 445 let text = db.file_text(file_id);
426 let text = &*text; 446 let text = &*text;
427 447
428 ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr))) 448 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)))
429} 449}
430 450
431fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { 451fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
@@ -437,7 +457,7 @@ fn env_expand(
437 db: &dyn AstDatabase, 457 db: &dyn AstDatabase,
438 arg_id: EagerMacroId, 458 arg_id: EagerMacroId,
439 tt: &tt::Subtree, 459 tt: &tt::Subtree,
440) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 460) -> ExpandResult<Option<ExpandedEager>> {
441 let key = match parse_string(tt) { 461 let key = match parse_string(tt) {
442 Ok(it) => it, 462 Ok(it) => it,
443 Err(e) => return ExpandResult::only_err(e), 463 Err(e) => return ExpandResult::only_err(e),
@@ -461,14 +481,14 @@ fn env_expand(
461 }); 481 });
462 let expanded = quote! { #s }; 482 let expanded = quote! { #s };
463 483
464 ExpandResult { value: Some((expanded, FragmentKind::Expr)), err } 484 ExpandResult { value: Some(ExpandedEager::new(expanded, FragmentKind::Expr)), err }
465} 485}
466 486
467fn option_env_expand( 487fn option_env_expand(
468 db: &dyn AstDatabase, 488 db: &dyn AstDatabase,
469 arg_id: EagerMacroId, 489 arg_id: EagerMacroId,
470 tt: &tt::Subtree, 490 tt: &tt::Subtree,
471) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 491) -> ExpandResult<Option<ExpandedEager>> {
472 let key = match parse_string(tt) { 492 let key = match parse_string(tt) {
473 Ok(it) => it, 493 Ok(it) => it,
474 Err(e) => return ExpandResult::only_err(e), 494 Err(e) => return ExpandResult::only_err(e),
@@ -479,7 +499,7 @@ fn option_env_expand(
479 Some(s) => quote! { std::option::Some(#s) }, 499 Some(s) => quote! { std::option::Some(#s) },
480 }; 500 };
481 501
482 ExpandResult::ok(Some((expanded, FragmentKind::Expr))) 502 ExpandResult::ok(Some(ExpandedEager::new(expanded, FragmentKind::Expr)))
483} 503}
484 504
485#[cfg(test)] 505#[cfg(test)]
@@ -553,16 +573,18 @@ mod tests {
553 subtree: Arc::new(parsed_args.clone()), 573 subtree: Arc::new(parsed_args.clone()),
554 krate, 574 krate,
555 call: call_id, 575 call: call_id,
576 included_file: None,
556 } 577 }
557 }); 578 });
558 579
559 let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).value.unwrap(); 580 let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
560 let eager = EagerCallLoc { 581 let eager = EagerCallLoc {
561 def, 582 def,
562 fragment, 583 fragment: expanded.fragment,
563 subtree: Arc::new(subtree), 584 subtree: Arc::new(expanded.subtree),
564 krate, 585 krate,
565 call: call_id, 586 call: call_id,
587 included_file: expanded.included_file,
566 }; 588 };
567 589
568 let id: MacroCallId = db.intern_eager_expansion(eager).into(); 590 let id: MacroCallId = db.intern_eager_expansion(eager).into();
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 2748e25cf..fc73e435b 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -173,7 +173,7 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
173 }; 173 };
174 let loc = db.lookup_intern_macro(id); 174 let loc = db.lookup_intern_macro(id);
175 let arg = loc.kind.arg(db)?; 175 let arg = loc.kind.arg(db)?;
176 Some(arg.green().to_owned()) 176 Some(arg.green())
177} 177}
178 178
179fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { 179fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> {
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 04f374a29..9eedc8461 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -124,6 +124,7 @@ pub fn expand_eager_macro(
124 subtree: Arc::new(parsed_args.clone()), 124 subtree: Arc::new(parsed_args.clone()),
125 krate, 125 krate,
126 call: call_id, 126 call: call_id,
127 included_file: None,
127 } 128 }
128 }); 129 });
129 let arg_file_id: MacroCallId = arg_id.into(); 130 let arg_file_id: MacroCallId = arg_id.into();
@@ -143,9 +144,15 @@ pub fn expand_eager_macro(
143 if let MacroDefKind::BuiltInEager(eager, _) = def.kind { 144 if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
144 let res = eager.expand(db, arg_id, &subtree); 145 let res = eager.expand(db, arg_id, &subtree);
145 146
146 let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; 147 let expanded = diagnostic_sink.expand_result_option(res)?;
147 let eager = 148 let eager = EagerCallLoc {
148 EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id }; 149 def,
150 fragment: expanded.fragment,
151 subtree: Arc::new(expanded.subtree),
152 krate,
153 call: call_id,
154 included_file: expanded.included_file,
155 };
149 156
150 Ok(db.intern_eager_expansion(eager)) 157 Ok(db.intern_eager_expansion(eager))
151 } else { 158 } else {
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index f49fd4fda..b8045fda9 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -84,7 +84,11 @@ impl HirFileId {
84 } 84 }
85 MacroCallId::EagerMacro(id) => { 85 MacroCallId::EagerMacro(id) => {
86 let loc = db.lookup_intern_eager_expansion(id); 86 let loc = db.lookup_intern_eager_expansion(id);
87 loc.call.file_id 87 if let Some(included_file) = loc.included_file {
88 return included_file;
89 } else {
90 loc.call.file_id
91 }
88 } 92 }
89 }; 93 };
90 file_id.original_file(db) 94 file_id.original_file(db)
@@ -188,6 +192,21 @@ impl HirFileId {
188 } 192 }
189 } 193 }
190 } 194 }
195
196 /// Return whether this file is an include macro
197 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
198 match self.0 {
199 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
200 MacroCallId::EagerMacro(id) => {
201 let loc = db.lookup_intern_eager_expansion(id);
202 return loc.included_file.is_some();
203 }
204 _ => {}
205 },
206 _ => {}
207 }
208 false
209 }
191} 210}
192 211
193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 212#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -315,6 +334,8 @@ pub struct EagerCallLoc {
315 pub(crate) subtree: Arc<tt::Subtree>, 334 pub(crate) subtree: Arc<tt::Subtree>,
316 pub(crate) krate: CrateId, 335 pub(crate) krate: CrateId,
317 pub(crate) call: AstId<ast::MacroCall>, 336 pub(crate) call: AstId<ast::MacroCall>,
337 // The included file ID of the include macro.
338 pub(crate) included_file: Option<FileId>,
318} 339}
319 340
320/// ExpansionInfo mainly describes how to map text range between src and expanded macro 341/// ExpansionInfo mainly describes how to map text range between src and expanded macro
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 43de9edd6..0aeea48d5 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -48,9 +48,8 @@ impl Name {
48 48
49 /// Resolve a name from the text of token. 49 /// Resolve a name from the text of token.
50 fn resolve(raw_text: &str) -> Name { 50 fn resolve(raw_text: &str) -> Name {
51 let raw_start = "r#"; 51 if let Some(text) = raw_text.strip_prefix("r#") {
52 if raw_text.starts_with(raw_start) { 52 Name::new_text(SmolStr::new(text))
53 Name::new_text(SmolStr::new(&raw_text[raw_start.len()..]))
54 } else { 53 } else {
55 Name::new_text(raw_text.into()) 54 Name::new_text(raw_text.into())
56 } 55 }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 23ab042c1..dc5fc759a 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -16,8 +16,8 @@ use crate::{
16 to_assoc_type_id, to_chalk_trait_id, 16 to_assoc_type_id, to_chalk_trait_id,
17 traits::{InEnvironment, Solution}, 17 traits::{InEnvironment, Solution},
18 utils::generics, 18 utils::generics,
19 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution, 19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
20 TraitRef, Ty, TyKind, 20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 21};
22 22
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 23const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -27,9 +27,9 @@ pub fn autoderef<'a>(
27 krate: Option<CrateId>, 27 krate: Option<CrateId>,
28 ty: InEnvironment<Canonical<Ty>>, 28 ty: InEnvironment<Canonical<Ty>>,
29) -> impl Iterator<Item = Canonical<Ty>> + 'a { 29) -> impl Iterator<Item = Canonical<Ty>> + 'a {
30 let InEnvironment { value: ty, environment } = ty; 30 let InEnvironment { goal: ty, environment } = ty;
31 successors(Some(ty), move |ty| { 31 successors(Some(ty), move |ty| {
32 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) 32 deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
33 }) 33 })
34 .take(AUTODEREF_RECURSION_LIMIT) 34 .take(AUTODEREF_RECURSION_LIMIT)
35} 35}
@@ -39,8 +39,8 @@ pub(crate) fn deref(
39 krate: CrateId, 39 krate: CrateId,
40 ty: InEnvironment<&Canonical<Ty>>, 40 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 41) -> Option<Canonical<Ty>> {
42 if let Some(derefed) = ty.value.value.builtin_deref() { 42 if let Some(derefed) = ty.goal.value.builtin_deref() {
43 Some(Canonical { value: derefed, kinds: ty.value.kinds.clone() }) 43 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
44 } else { 44 } else {
45 deref_by_trait(db, krate, ty) 45 deref_by_trait(db, krate, ty)
46 } 46 }
@@ -67,15 +67,15 @@ fn deref_by_trait(
67 // FIXME make the Canonical / bound var handling nicer 67 // FIXME make the Canonical / bound var handling nicer
68 68
69 let parameters = 69 let parameters =
70 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
71 71
72 // Check that the type implements Deref at all 72 // Check that the type implements Deref at all
73 let trait_ref = 73 let trait_ref =
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; 74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
75 let implements_goal = Canonical { 75 let implements_goal = Canonical {
76 kinds: ty.value.kinds.clone(), 76 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 77 value: InEnvironment {
78 value: trait_ref.cast(&Interner), 78 goal: trait_ref.cast(&Interner),
79 environment: ty.environment.clone(), 79 environment: ty.environment.clone(),
80 }, 80 },
81 }; 81 };
@@ -89,18 +89,27 @@ fn deref_by_trait(
89 associated_ty_id: to_assoc_type_id(target), 89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters, 90 substitution: parameters,
91 }), 91 }),
92 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) 92 ty: TyKind::BoundVar(BoundVar::new(
93 .intern(&Interner), 93 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner),
95 ))
96 .intern(&Interner),
94 }; 97 };
95 98
96 let obligation = projection.cast(&Interner); 99 let obligation = projection.cast(&Interner);
97 100
98 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
99 102
100 let canonical = Canonical::new( 103 let canonical = Canonical {
101 in_env, 104 value: in_env,
102 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), 105 binders: CanonicalVarKinds::from_iter(
103 ); 106 &Interner,
107 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
109 chalk_ir::UniverseIndex::ROOT,
110 ))),
111 ),
112 };
104 113
105 let solution = db.trait_solve(krate, canonical)?; 114 let solution = db.trait_solve(krate, canonical)?;
106 115
@@ -121,21 +130,21 @@ fn deref_by_trait(
121 // assumptions will be broken. We would need to properly introduce 130 // assumptions will be broken. We would need to properly introduce
122 // new variables in that case 131 // new variables in that case
123 132
124 for i in 1..vars.0.kinds.len() { 133 for i in 1..vars.0.binders.len(&Interner) {
125 if vars.0.value[i - 1].interned(&Interner) 134 if vars.0.value[i - 1].interned(&Interner)
126 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
127 { 136 {
128 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
129 return None; 138 return None;
130 } 139 }
131 } 140 }
132 Some(Canonical { 141 Some(Canonical {
133 value: vars.0.value[vars.0.value.len() - 1].clone(), 142 value: vars.0.value[vars.0.value.len() - 1].clone(),
134 kinds: vars.0.kinds.clone(), 143 binders: vars.0.binders.clone(),
135 }) 144 })
136 } 145 }
137 Solution::Ambig(_) => { 146 Solution::Ambig(_) => {
138 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); 147 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
139 None 148 None
140 } 149 }
141 } 150 }
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 91a2e0b5b..58e4247c6 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -12,8 +12,8 @@ use la_arena::ArenaMap;
12use crate::{ 12use crate::{
13 method_resolution::{InherentImpls, TraitImpls}, 13 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 14 traits::chalk,
15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, ReturnTypeImplTraits, 15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig,
16 TraitRef, Ty, TyDefId, ValueTyDefId, WhereClause, 16 QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
17}; 17};
18use hir_expand::name::Name; 18use hir_expand::name::Name;
19 19
@@ -57,10 +57,13 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
57 57
58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
60 fn generic_predicates_for_param(&self, param_id: TypeParamId) -> Arc<[Binders<WhereClause>]>; 60 fn generic_predicates_for_param(
61 &self,
62 param_id: TypeParamId,
63 ) -> Arc<[Binders<QuantifiedWhereClause>]>;
61 64
62 #[salsa::invoke(crate::lower::generic_predicates_query)] 65 #[salsa::invoke(crate::lower::generic_predicates_query)]
63 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<WhereClause>]>; 66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<QuantifiedWhereClause>]>;
64 67
65 #[salsa::invoke(crate::lower::trait_environment_query)] 68 #[salsa::invoke(crate::lower::trait_environment_query)]
66 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; 69 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 981ba564d..6149067c7 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{borrow::Cow, fmt}; 3use std::fmt;
4 4
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
@@ -20,7 +20,7 @@ use crate::{
20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 23 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
24}; 24};
25 25
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -329,9 +329,9 @@ impl HirDisplay for Ty {
329 329
330 // FIXME: all this just to decide whether to use parentheses... 330 // FIXME: all this just to decide whether to use parentheses...
331 let datas; 331 let datas;
332 let predicates = match t.interned(&Interner) { 332 let predicates: Vec<_> = match t.interned(&Interner) {
333 TyKind::Dyn(predicates) if predicates.len() > 1 => { 333 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
334 Cow::Borrowed(predicates.as_ref()) 334 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
335 } 335 }
336 &TyKind::Alias(AliasTy::Opaque(OpaqueTy { 336 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
337 opaque_ty_id, 337 opaque_ty_id,
@@ -346,17 +346,21 @@ impl HirDisplay for Ty {
346 .as_ref() 346 .as_ref()
347 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 347 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
348 let bounds = data.subst(parameters); 348 let bounds = data.subst(parameters);
349 Cow::Owned(bounds.value) 349 bounds.value
350 } else { 350 } else {
351 Cow::Borrowed(&[][..]) 351 Vec::new()
352 } 352 }
353 } 353 }
354 _ => Cow::Borrowed(&[][..]), 354 _ => Vec::new(),
355 }; 355 };
356 356
357 if let [WhereClause::Implemented(trait_ref), _] = predicates.as_ref() { 357 if let Some(WhereClause::Implemented(trait_ref)) =
358 predicates.get(0).map(|b| b.skip_binders())
359 {
358 let trait_ = trait_ref.hir_trait_id(); 360 let trait_ = trait_ref.hir_trait_id();
359 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 361 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
362 && predicates.len() <= 2
363 {
360 return write!(f, "{}", ty_display); 364 return write!(f, "{}", ty_display);
361 } 365 }
362 } 366 }
@@ -577,19 +581,32 @@ impl HirDisplay for Ty {
577 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 581 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
578 } 582 }
579 TypeParamProvenance::ArgumentImplTrait => { 583 TypeParamProvenance::ArgumentImplTrait => {
580 let bounds = f.db.generic_predicates_for_param(id);
581 let substs = Substitution::type_params_for_generics(f.db, &generics); 584 let substs = Substitution::type_params_for_generics(f.db, &generics);
582 write_bounds_like_dyn_trait_with_prefix( 585 let bounds = f
583 "impl", 586 .db
584 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 587 .generic_predicates(id.parent)
585 f, 588 .into_iter()
586 )?; 589 .map(|pred| pred.clone().subst(&substs))
590 .filter(|wc| match &wc.skip_binders() {
591 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
592 WhereClause::AliasEq(AliasEq {
593 alias: AliasTy::Projection(proj),
594 ty: _,
595 }) => proj.self_type_parameter() == self,
596 _ => false,
597 })
598 .collect::<Vec<_>>();
599 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
587 } 600 }
588 } 601 }
589 } 602 }
590 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 603 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
591 TyKind::Dyn(predicates) => { 604 TyKind::Dyn(dyn_ty) => {
592 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 605 write_bounds_like_dyn_trait_with_prefix(
606 "dyn",
607 dyn_ty.bounds.skip_binders().interned(),
608 f,
609 )?;
593 } 610 }
594 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 611 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
595 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { 612 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
@@ -658,7 +675,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
658 675
659pub fn write_bounds_like_dyn_trait_with_prefix( 676pub fn write_bounds_like_dyn_trait_with_prefix(
660 prefix: &str, 677 prefix: &str,
661 predicates: &[WhereClause], 678 predicates: &[QuantifiedWhereClause],
662 f: &mut HirFormatter, 679 f: &mut HirFormatter,
663) -> Result<(), HirDisplayError> { 680) -> Result<(), HirDisplayError> {
664 write!(f, "{}", prefix)?; 681 write!(f, "{}", prefix)?;
@@ -671,7 +688,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
671} 688}
672 689
673fn write_bounds_like_dyn_trait( 690fn write_bounds_like_dyn_trait(
674 predicates: &[WhereClause], 691 predicates: &[QuantifiedWhereClause],
675 f: &mut HirFormatter, 692 f: &mut HirFormatter,
676) -> Result<(), HirDisplayError> { 693) -> Result<(), HirDisplayError> {
677 // Note: This code is written to produce nice results (i.e. 694 // Note: This code is written to produce nice results (i.e.
@@ -684,7 +701,7 @@ fn write_bounds_like_dyn_trait(
684 let mut angle_open = false; 701 let mut angle_open = false;
685 let mut is_fn_trait = false; 702 let mut is_fn_trait = false;
686 for p in predicates.iter() { 703 for p in predicates.iter() {
687 match p { 704 match p.skip_binders() {
688 WhereClause::Implemented(trait_ref) => { 705 WhereClause::Implemented(trait_ref) => {
689 let trait_ = trait_ref.hir_trait_id(); 706 let trait_ = trait_ref.hir_trait_id();
690 if !is_fn_trait { 707 if !is_fn_trait {
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index b9e434c78..8f9cf7480 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> {
331 fn resolve_obligations_as_possible(&mut self) { 331 fn resolve_obligations_as_possible(&mut self) {
332 let obligations = mem::replace(&mut self.obligations, Vec::new()); 332 let obligations = mem::replace(&mut self.obligations, Vec::new());
333 for obligation in obligations { 333 for obligation in obligations {
334 let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); 334 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
336 let solution = 336 let solution =
337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 07eb96573..9c62932b1 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -142,7 +142,7 @@ impl<'a> InferenceContext<'a> {
142 .build(); 142 .build();
143 let trait_ref = 143 let trait_ref =
144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; 144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
145 let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner)); 145 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
146 146
147 let canonicalizer = self.canonicalizer(); 147 let canonicalizer = self.canonicalizer();
148 let canonicalized = canonicalizer.canonicalize_obligation(goal); 148 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -170,8 +170,8 @@ impl<'a> InferenceContext<'a> {
170 self.db, 170 self.db,
171 self.resolver.krate(), 171 self.resolver.krate(),
172 InEnvironment { 172 InEnvironment {
173 value: canonicalized.value.clone(), 173 goal: canonicalized.value.clone(),
174 environment: self.trait_env.clone(), 174 environment: self.trait_env.env.clone(),
175 }, 175 },
176 ) { 176 ) {
177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 79bbc5dab..19249973c 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -11,6 +11,7 @@ use hir_def::{
11 AssocContainerId, FieldId, Lookup, 11 AssocContainerId, FieldId, Lookup,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::{name, Name};
14use stdx::always;
14use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
15 16
16use crate::{ 17use crate::{
@@ -89,12 +90,12 @@ impl<'a> InferenceContext<'a> {
89 let substs = 90 let substs =
90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 92
92 let trait_env = Arc::clone(&self.trait_env); 93 let trait_env = self.trait_env.env.clone();
93 let implements_fn_trait: DomainGoal = 94 let implements_fn_trait: DomainGoal =
94 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
95 .cast(&Interner); 96 .cast(&Interner);
96 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
97 value: implements_fn_trait.clone(), 98 goal: implements_fn_trait.clone(),
98 environment: trait_env, 99 environment: trait_env,
99 }); 100 });
100 if self.db.trait_solve(krate, goal.value).is_some() { 101 if self.db.trait_solve(krate, goal.value).is_some() {
@@ -298,8 +299,8 @@ impl<'a> InferenceContext<'a> {
298 self.db, 299 self.db,
299 self.resolver.krate(), 300 self.resolver.krate(),
300 InEnvironment { 301 InEnvironment {
301 value: canonicalized.value.clone(), 302 goal: canonicalized.value.clone(),
302 environment: self.trait_env.clone(), 303 environment: self.trait_env.env.clone(),
303 }, 304 },
304 ); 305 );
305 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs 306 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs
@@ -437,8 +438,8 @@ impl<'a> InferenceContext<'a> {
437 self.db, 438 self.db,
438 self.resolver.krate(), 439 self.resolver.krate(),
439 InEnvironment { 440 InEnvironment {
440 value: canonicalized.value.clone(), 441 goal: canonicalized.value.clone(),
441 environment: self.trait_env.clone(), 442 environment: self.trait_env.env.clone(),
442 }, 443 },
443 ) 444 )
444 .find_map(|derefed_ty| { 445 .find_map(|derefed_ty| {
@@ -513,10 +514,10 @@ impl<'a> InferenceContext<'a> {
513 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 514 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
514 if let Some(box_) = self.resolve_boxed_box() { 515 if let Some(box_) = self.resolve_boxed_box() {
515 let mut sb = 516 let mut sb =
516 Substitution::builder(generics(self.db.upcast(), box_.into()).len()); 517 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
517 sb = sb.push(inner_ty); 518 sb = sb.push(inner_ty);
518 match self.db.generic_defaults(box_.into()).as_ref() { 519 match self.db.generic_defaults(box_.into()).get(1) {
519 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { 520 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
520 sb = sb.push(alloc_ty.value.clone()); 521 sb = sb.push(alloc_ty.value.clone());
521 } 522 }
522 _ => (), 523 _ => (),
@@ -537,8 +538,8 @@ impl<'a> InferenceContext<'a> {
537 self.db, 538 self.db,
538 krate, 539 krate,
539 InEnvironment { 540 InEnvironment {
540 value: &canonicalized.value, 541 goal: &canonicalized.value,
541 environment: self.trait_env.clone(), 542 environment: self.trait_env.env.clone(),
542 }, 543 },
543 ) { 544 ) {
544 Some(derefed_ty) => { 545 Some(derefed_ty) => {
@@ -936,7 +937,9 @@ impl<'a> InferenceContext<'a> {
936 let def: CallableDefId = from_chalk(self.db, *fn_def); 937 let def: CallableDefId = from_chalk(self.db, *fn_def);
937 let generic_predicates = self.db.generic_predicates(def.into()); 938 let generic_predicates = self.db.generic_predicates(def.into());
938 for predicate in generic_predicates.iter() { 939 for predicate in generic_predicates.iter() {
939 let predicate = predicate.clone().subst(parameters); 940 let (predicate, binders) =
941 predicate.clone().subst(parameters).into_value_and_skipped_binders();
942 always!(binders == 0); // quantified where clauses not yet handled
940 self.obligations.push(predicate.cast(&Interner)); 943 self.obligations.push(predicate.cast(&Interner));
941 } 944 }
942 // add obligation for trait implementation, if this is a trait method 945 // add obligation for trait implementation, if this is a trait method
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index befa0d69b..474363709 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,9 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind, 16 lower::lower_to_chalk_mutability,
17 utils::{generics, variant_data},
18 Interner, Substitution, Ty, TyKind,
17}; 19};
18 20
19impl<'a> InferenceContext<'a> { 21impl<'a> InferenceContext<'a> {
@@ -38,7 +40,7 @@ impl<'a> InferenceContext<'a> {
38 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
39 let (pre, post) = match ellipsis { 41 let (pre, post) = match ellipsis {
40 Some(idx) => subpats.split_at(idx), 42 Some(idx) => subpats.split_at(idx),
41 None => (&subpats[..], &[][..]), 43 None => (subpats, &[][..]),
42 }; 44 };
43 let post_idx_offset = field_tys.iter().count() - post.len(); 45 let post_idx_offset = field_tys.iter().count() - post.len();
44 46
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
233 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 235 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
234 Pat::Box { inner } => match self.resolve_boxed_box() { 236 Pat::Box { inner } => match self.resolve_boxed_box() {
235 Some(box_adt) => { 237 Some(box_adt) => {
236 let inner_expected = match expected.as_adt() { 238 let (inner_ty, alloc_ty) = match expected.as_adt() {
237 Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), 239 Some((adt, subst)) if adt == box_adt => {
238 _ => self.result.standard_types.unknown.clone(), 240 (subst[0].clone(), subst.get(1).cloned())
241 }
242 _ => (self.result.standard_types.unknown.clone(), None),
239 }; 243 };
240 244
241 let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); 245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
242 Ty::adt_ty(box_adt, Substitution::single(inner_ty)) 246 let mut sb = Substitution::build_for_generics(&generics(
247 self.db.upcast(),
248 box_adt.into(),
249 ));
250 sb = sb.push(inner_ty);
251 if sb.remaining() == 1 {
252 sb = sb.push(match alloc_ty {
253 Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254 _ => match self.db.generic_defaults(box_adt.into()).get(1) {
255 Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256 alloc_ty.value.clone()
257 }
258 _ => self.table.new_type_var(),
259 },
260 });
261 }
262 Ty::adt_ty(box_adt, sb.build())
243 } 263 }
244 None => self.err_ty(), 264 None => self.err_ty(),
245 }, 265 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 1fc03c8f4..75250a369 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,13 +2,13 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind}; 5use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{DomainGoal, InferenceContext}; 8use super::{DomainGoal, InferenceContext};
9use crate::{ 9use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar, 10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer,
11 Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, 11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -76,8 +76,17 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
76 } 76 }
77 77
78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
79 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); 79 let kinds = self
80 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 80 .free_vars
81 .iter()
82 .map(|&(_, k)| chalk_ir::WithKind::new(VariableKind::Ty(k), UniverseIndex::ROOT));
83 Canonicalized {
84 value: Canonical {
85 value: result,
86 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
87 },
88 free_vars: self.free_vars,
89 }
81 } 90 }
82 91
83 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { 92 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> {
@@ -89,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
89 mut self, 98 mut self,
90 obligation: InEnvironment<DomainGoal>, 99 obligation: InEnvironment<DomainGoal>,
91 ) -> Canonicalized<InEnvironment<DomainGoal>> { 100 ) -> Canonicalized<InEnvironment<DomainGoal>> {
92 let result = match obligation.value { 101 let result = match obligation.goal {
93 DomainGoal::Holds(wc) => { 102 DomainGoal::Holds(wc) => {
94 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) 103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
95 } 104 }
96 }; 105 };
97 self.into_canonicalized(InEnvironment { 106 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
98 value: result,
99 environment: obligation.environment,
100 })
101 } 107 }
102} 108}
103 109
@@ -125,12 +131,19 @@ impl<T> Canonicalized<T> {
125 // the solution may contain new variables, which we need to convert to new inference vars 131 // the solution may contain new variables, which we need to convert to new inference vars
126 let new_vars = Substitution( 132 let new_vars = Substitution(
127 solution 133 solution
128 .kinds 134 .binders
129 .iter() 135 .iter(&Interner)
130 .map(|k| match k { 136 .map(|k| match k.kind {
131 TyVariableKind::General => ctx.table.new_type_var(), 137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
132 TyVariableKind::Integer => ctx.table.new_integer_var(), 138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
133 TyVariableKind::Float => ctx.table.new_float_var(), 139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
140 // HACK: Chalk can sometimes return new lifetime variables. We
141 // want to just skip them, but to not mess up the indices of
142 // other variables, we'll just create a new type variable in
143 // their place instead. This should not matter (we never see the
144 // actual *uses* of the lifetime variable).
145 VariableKind::Lifetime => ctx.table.new_type_var(),
146 _ => panic!("const variable in solution"),
134 }) 147 })
135 .collect(), 148 .collect(),
136 ); 149 );
@@ -147,8 +160,8 @@ impl<T> Canonicalized<T> {
147pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 160pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
148 let mut table = InferenceTable::new(); 161 let mut table = InferenceTable::new();
149 let vars = Substitution( 162 let vars = Substitution(
150 tys.kinds 163 tys.binders
151 .iter() 164 .iter(&Interner)
152 // we always use type vars here because we want everything to 165 // we always use type vars here because we want everything to
153 // fallback to Unknown in the end (kind of hacky, as below) 166 // fallback to Unknown in the end (kind of hacky, as below)
154 .map(|_| table.new_type_var()) 167 .map(|_| table.new_type_var())
@@ -170,7 +183,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
170 } 183 }
171 } 184 }
172 Some( 185 Some(
173 Substitution::builder(tys.kinds.len()) 186 Substitution::builder(tys.binders.len(&Interner))
174 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 187 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))
175 .build(), 188 .build(),
176 ) 189 )
@@ -310,9 +323,18 @@ impl InferenceTable {
310 323
311 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 324 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
312 325
313 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 326 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2))
314 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 327 if dyn1.bounds.skip_binders().interned().len()
315 if !self.unify_preds(pred1, pred2, depth + 1) { 328 == dyn2.bounds.skip_binders().interned().len() =>
329 {
330 for (pred1, pred2) in dyn1
331 .bounds
332 .skip_binders()
333 .interned()
334 .iter()
335 .zip(dyn2.bounds.skip_binders().interned().iter())
336 {
337 if !self.unify_preds(pred1.skip_binders(), pred2.skip_binders(), depth + 1) {
316 return false; 338 return false;
317 } 339 }
318 } 340 }
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index c46529879..0f49dd39b 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -61,6 +61,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
63 63
64pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
65
64pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 66pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
65 67
66#[derive(Clone, PartialEq, Eq, Debug, Hash)] 68#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -106,6 +108,10 @@ impl ProjectionTy {
106 } 108 }
107 } 109 }
108 110
111 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0]
113 }
114
109 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
110 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { 116 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
111 AssocContainerId::TraitId(it) => it, 117 AssocContainerId::TraitId(it) => it,
@@ -128,6 +134,12 @@ impl TypeWalk for ProjectionTy {
128 } 134 }
129} 135}
130 136
137#[derive(Clone, PartialEq, Eq, Debug, Hash)]
138pub struct DynTy {
139 /// The unknown self type.
140 pub bounds: Binders<QuantifiedWhereClauses>,
141}
142
131pub type FnSig = chalk_ir::FnSig<Interner>; 143pub type FnSig = chalk_ir::FnSig<Interner>;
132 144
133#[derive(Clone, PartialEq, Eq, Debug, Hash)] 145#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -279,7 +291,7 @@ pub enum TyKind {
279 /// represents the `Self` type inside the bounds. This is currently 291 /// represents the `Self` type inside the bounds. This is currently
280 /// implicit; Chalk has the `Binders` struct to make it explicit, but it 292 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
281 /// didn't seem worth the overhead yet. 293 /// didn't seem worth the overhead yet.
282 Dyn(Arc<[WhereClause]>), 294 Dyn(DynTy),
283 295
284 /// A placeholder for a type which could not be computed; this is propagated 296 /// A placeholder for a type which could not be computed; this is propagated
285 /// to avoid useless error messages. Doubles as a placeholder where type 297 /// to avoid useless error messages. Doubles as a placeholder where type
@@ -486,6 +498,13 @@ impl<T> Binders<T> {
486 Self { num_binders, value } 498 Self { num_binders, value }
487 } 499 }
488 500
501 pub fn wrap_empty(value: T) -> Self
502 where
503 T: TypeWalk,
504 {
505 Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) }
506 }
507
489 pub fn as_ref(&self) -> Binders<&T> { 508 pub fn as_ref(&self) -> Binders<&T> {
490 Binders { num_binders: self.num_binders, value: &self.value } 509 Binders { num_binders: self.num_binders, value: &self.value }
491 } 510 }
@@ -497,6 +516,14 @@ impl<T> Binders<T> {
497 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { 516 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
498 Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) 517 Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
499 } 518 }
519
520 pub fn skip_binders(&self) -> &T {
521 &self.value
522 }
523
524 pub fn into_value_and_skipped_binders(self) -> (T, usize) {
525 (self.value, self.num_binders)
526 }
500} 527}
501 528
502impl<T: Clone> Binders<&T> { 529impl<T: Clone> Binders<&T> {
@@ -610,6 +637,24 @@ impl TypeWalk for WhereClause {
610 } 637 }
611} 638}
612 639
640pub type QuantifiedWhereClause = Binders<WhereClause>;
641
642#[derive(Debug, Clone, PartialEq, Eq, Hash)]
643pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>);
644
645impl QuantifiedWhereClauses {
646 pub fn from_iter(
647 _interner: &Interner,
648 elements: impl IntoIterator<Item = QuantifiedWhereClause>,
649 ) -> Self {
650 QuantifiedWhereClauses(elements.into_iter().collect())
651 }
652
653 pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> {
654 &self.0
655 }
656}
657
613/// Basically a claim (currently not validated / checked) that the contained 658/// Basically a claim (currently not validated / checked) that the contained
614/// type / trait ref contains no inference variables; any inference variables it 659/// type / trait ref contains no inference variables; any inference variables it
615/// contained have been replaced by bound variables, and `kinds` tells us how 660/// contained have been replaced by bound variables, and `kinds` tells us how
@@ -619,12 +664,18 @@ impl TypeWalk for WhereClause {
619#[derive(Debug, Clone, PartialEq, Eq, Hash)] 664#[derive(Debug, Clone, PartialEq, Eq, Hash)]
620pub struct Canonical<T> { 665pub struct Canonical<T> {
621 pub value: T, 666 pub value: T,
622 pub kinds: Arc<[TyVariableKind]>, 667 pub binders: CanonicalVarKinds,
623} 668}
624 669
625impl<T> Canonical<T> { 670impl<T> Canonical<T> {
626 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { 671 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
627 Self { value, kinds: kinds.into_iter().collect() } 672 let kinds = kinds.into_iter().map(|tk| {
673 chalk_ir::CanonicalVarKind::new(
674 chalk_ir::VariableKind::Ty(tk),
675 chalk_ir::UniverseIndex::ROOT,
676 )
677 });
678 Self { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
628 } 679 }
629} 680}
630 681
@@ -806,12 +857,14 @@ impl Ty {
806 } 857 }
807 858
808 /// If this is a `dyn Trait` type, this returns the `Trait` part. 859 /// If this is a `dyn Trait` type, this returns the `Trait` part.
809 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 860 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
810 match self.interned(&Interner) { 861 match self.interned(&Interner) {
811 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 862 TyKind::Dyn(dyn_ty) => {
812 WhereClause::Implemented(trait_ref) => Some(trait_ref), 863 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
813 _ => None, 864 WhereClause::Implemented(trait_ref) => Some(trait_ref),
814 }), 865 _ => None,
866 })
867 }
815 _ => None, 868 _ => None,
816 } 869 }
817 } 870 }
@@ -888,7 +941,7 @@ impl Ty {
888 } 941 }
889 } 942 }
890 943
891 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<WhereClause>> { 944 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
892 match self.interned(&Interner) { 945 match self.interned(&Interner) {
893 TyKind::OpaqueType(opaque_ty_id, ..) => { 946 TyKind::OpaqueType(opaque_ty_id, ..) => {
894 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { 947 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
@@ -901,10 +954,13 @@ impl Ty {
901 // This is only used by type walking. 954 // This is only used by type walking.
902 // Parameters will be walked outside, and projection predicate is not used. 955 // Parameters will be walked outside, and projection predicate is not used.
903 // So just provide the Future trait. 956 // So just provide the Future trait.
904 let impl_bound = WhereClause::Implemented(TraitRef { 957 let impl_bound = Binders::new(
905 trait_id: to_chalk_trait_id(future_trait), 958 0,
906 substitution: Substitution::empty(), 959 WhereClause::Implemented(TraitRef {
907 }); 960 trait_id: to_chalk_trait_id(future_trait),
961 substitution: Substitution::empty(),
962 }),
963 );
908 Some(vec![impl_bound]) 964 Some(vec![impl_bound])
909 } else { 965 } else {
910 None 966 None
@@ -936,10 +992,19 @@ impl Ty {
936 let param_data = &generic_params.types[id.local_id]; 992 let param_data = &generic_params.types[id.local_id];
937 match param_data.provenance { 993 match param_data.provenance {
938 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { 994 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
995 let substs = Substitution::type_params(db, id.parent);
939 let predicates = db 996 let predicates = db
940 .generic_predicates_for_param(id) 997 .generic_predicates(id.parent)
941 .into_iter() 998 .into_iter()
942 .map(|pred| pred.value.clone()) 999 .map(|pred| pred.clone().subst(&substs))
1000 .filter(|wc| match &wc.skip_binders() {
1001 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
1002 WhereClause::AliasEq(AliasEq {
1003 alias: AliasTy::Projection(proj),
1004 ty: _,
1005 }) => proj.self_type_parameter() == self,
1006 _ => false,
1007 })
943 .collect_vec(); 1008 .collect_vec();
944 1009
945 Some(predicates) 1010 Some(predicates)
@@ -1081,8 +1146,8 @@ impl TypeWalk for Ty {
1081 t.walk(f); 1146 t.walk(f);
1082 } 1147 }
1083 } 1148 }
1084 TyKind::Dyn(predicates) => { 1149 TyKind::Dyn(dyn_ty) => {
1085 for p in predicates.iter() { 1150 for p in dyn_ty.bounds.value.interned().iter() {
1086 p.walk(f); 1151 p.walk(f);
1087 } 1152 }
1088 } 1153 }
@@ -1109,8 +1174,8 @@ impl TypeWalk for Ty {
1109 TyKind::Alias(AliasTy::Projection(p_ty)) => { 1174 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1110 p_ty.substitution.walk_mut_binders(f, binders); 1175 p_ty.substitution.walk_mut_binders(f, binders);
1111 } 1176 }
1112 TyKind::Dyn(predicates) => { 1177 TyKind::Dyn(dyn_ty) => {
1113 for p in make_mut_slice(predicates) { 1178 for p in make_mut_slice(&mut dyn_ty.bounds.value.0) {
1114 p.walk_mut_binders(f, binders.shifted_in()); 1179 p.walk_mut_binders(f, binders.shifted_in());
1115 } 1180 }
1116 } 1181 }
@@ -1160,7 +1225,7 @@ pub struct ReturnTypeImplTraits {
1160 1225
1161#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1226#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1162pub(crate) struct ReturnTypeImplTrait { 1227pub(crate) struct ReturnTypeImplTrait {
1163 pub(crate) bounds: Binders<Vec<WhereClause>>, 1228 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
1164} 1229}
1165 1230
1166pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 1231pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index cbbb535e5..f60cec649 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -33,9 +33,10 @@ use crate::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
34 variant_data, 34 variant_data,
35 }, 35 },
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, ImplTraitId, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
38 TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, WhereClause, 38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty,
39 TyKind, TypeWalk, WhereClause,
39}; 40};
40 41
41#[derive(Debug)] 42#[derive(Debug)]
@@ -188,10 +189,14 @@ impl<'a> TyLoweringContext<'a> {
188 TypeRef::DynTrait(bounds) => { 189 TypeRef::DynTrait(bounds) => {
189 let self_ty = 190 let self_ty =
190 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); 191 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
191 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 192 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
192 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() 193 QuantifiedWhereClauses::from_iter(
194 &Interner,
195 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
196 )
193 }); 197 });
194 TyKind::Dyn(predicates).intern(&Interner) 198 let bounds = Binders::new(1, bounds);
199 TyKind::Dyn(DynTy { bounds }).intern(&Interner)
195 } 200 }
196 TypeRef::ImplTrait(bounds) => { 201 TypeRef::ImplTrait(bounds) => {
197 match self.impl_trait_mode { 202 match self.impl_trait_mode {
@@ -373,7 +378,16 @@ impl<'a> TyLoweringContext<'a> {
373 // FIXME report error (ambiguous associated type) 378 // FIXME report error (ambiguous associated type)
374 TyKind::Unknown.intern(&Interner) 379 TyKind::Unknown.intern(&Interner)
375 } else { 380 } else {
376 TyKind::Dyn(Arc::new([WhereClause::Implemented(trait_ref)])).intern(&Interner) 381 let dyn_ty = DynTy {
382 bounds: Binders::new(
383 1,
384 QuantifiedWhereClauses::from_iter(
385 &Interner,
386 Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))),
387 ),
388 ),
389 };
390 TyKind::Dyn(dyn_ty).intern(&Interner)
377 }; 391 };
378 return (ty, None); 392 return (ty, None);
379 } 393 }
@@ -666,7 +680,8 @@ impl<'a> TyLoweringContext<'a> {
666 pub(crate) fn lower_where_predicate( 680 pub(crate) fn lower_where_predicate(
667 &'a self, 681 &'a self,
668 where_predicate: &'a WherePredicate, 682 where_predicate: &'a WherePredicate,
669 ) -> impl Iterator<Item = WhereClause> + 'a { 683 ignore_bindings: bool,
684 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
670 match where_predicate { 685 match where_predicate {
671 WherePredicate::ForLifetime { target, bound, .. } 686 WherePredicate::ForLifetime { target, bound, .. }
672 | WherePredicate::TypeBound { target, bound } => { 687 | WherePredicate::TypeBound { target, bound } => {
@@ -688,7 +703,9 @@ impl<'a> TyLoweringContext<'a> {
688 .intern(&Interner) 703 .intern(&Interner)
689 } 704 }
690 }; 705 };
691 self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter() 706 self.lower_type_bound(bound, self_ty, ignore_bindings)
707 .collect::<Vec<_>>()
708 .into_iter()
692 } 709 }
693 WherePredicate::Lifetime { .. } => vec![].into_iter(), 710 WherePredicate::Lifetime { .. } => vec![].into_iter(),
694 } 711 }
@@ -698,12 +715,13 @@ impl<'a> TyLoweringContext<'a> {
698 &'a self, 715 &'a self,
699 bound: &'a TypeBound, 716 bound: &'a TypeBound,
700 self_ty: Ty, 717 self_ty: Ty,
701 ) -> impl Iterator<Item = WhereClause> + 'a { 718 ignore_bindings: bool,
719 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
702 let mut bindings = None; 720 let mut bindings = None;
703 let trait_ref = match bound { 721 let trait_ref = match bound {
704 TypeBound::Path(path) => { 722 TypeBound::Path(path) => {
705 bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); 723 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
706 bindings.clone().map(WhereClause::Implemented) 724 bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b))
707 } 725 }
708 TypeBound::Lifetime(_) => None, 726 TypeBound::Lifetime(_) => None,
709 TypeBound::Error => None, 727 TypeBound::Error => None,
@@ -711,6 +729,7 @@ impl<'a> TyLoweringContext<'a> {
711 trait_ref.into_iter().chain( 729 trait_ref.into_iter().chain(
712 bindings 730 bindings
713 .into_iter() 731 .into_iter()
732 .filter(move |_| !ignore_bindings)
714 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)), 733 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
715 ) 734 )
716 } 735 }
@@ -719,7 +738,7 @@ impl<'a> TyLoweringContext<'a> {
719 &'a self, 738 &'a self,
720 bound: &'a TypeBound, 739 bound: &'a TypeBound,
721 trait_ref: TraitRef, 740 trait_ref: TraitRef,
722 ) -> impl Iterator<Item = WhereClause> + 'a { 741 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
723 let last_segment = match bound { 742 let last_segment = match bound {
724 TypeBound::Path(path) => path.segments().last(), 743 TypeBound::Path(path) => path.segments().last(),
725 TypeBound::Error | TypeBound::Lifetime(_) => None, 744 TypeBound::Error | TypeBound::Lifetime(_) => None,
@@ -735,7 +754,7 @@ impl<'a> TyLoweringContext<'a> {
735 &binding.name, 754 &binding.name,
736 ); 755 );
737 let (super_trait_ref, associated_ty) = match found { 756 let (super_trait_ref, associated_ty) = match found {
738 None => return SmallVec::<[WhereClause; 1]>::new(), 757 None => return SmallVec::<[QuantifiedWhereClause; 1]>::new(),
739 Some(t) => t, 758 Some(t) => t,
740 }; 759 };
741 let projection_ty = ProjectionTy { 760 let projection_ty = ProjectionTy {
@@ -749,12 +768,13 @@ impl<'a> TyLoweringContext<'a> {
749 let ty = self.lower_ty(type_ref); 768 let ty = self.lower_ty(type_ref);
750 let alias_eq = 769 let alias_eq =
751 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; 770 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
752 preds.push(WhereClause::AliasEq(alias_eq)); 771 preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq)));
753 } 772 }
754 for bound in &binding.bounds { 773 for bound in &binding.bounds {
755 preds.extend(self.lower_type_bound( 774 preds.extend(self.lower_type_bound(
756 bound, 775 bound,
757 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner), 776 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
777 false,
758 )); 778 ));
759 } 779 }
760 preds 780 preds
@@ -766,7 +786,7 @@ impl<'a> TyLoweringContext<'a> {
766 let self_ty = 786 let self_ty =
767 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); 787 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
768 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 788 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
769 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() 789 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
770 }); 790 });
771 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 791 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
772 } 792 }
@@ -805,7 +825,7 @@ pub fn associated_type_shorthand_candidates<R>(
805 let predicates = db.generic_predicates_for_param(param_id); 825 let predicates = db.generic_predicates_for_param(param_id);
806 let mut traits_: Vec<_> = predicates 826 let mut traits_: Vec<_> = predicates
807 .iter() 827 .iter()
808 .filter_map(|pred| match &pred.value { 828 .filter_map(|pred| match &pred.value.value {
809 WhereClause::Implemented(tr) => Some(tr.clone()), 829 WhereClause::Implemented(tr) => Some(tr.clone()),
810 _ => None, 830 _ => None,
811 }) 831 })
@@ -878,7 +898,7 @@ pub(crate) fn field_types_query(
878pub(crate) fn generic_predicates_for_param_query( 898pub(crate) fn generic_predicates_for_param_query(
879 db: &dyn HirDatabase, 899 db: &dyn HirDatabase,
880 param_id: TypeParamId, 900 param_id: TypeParamId,
881) -> Arc<[Binders<WhereClause>]> { 901) -> Arc<[Binders<QuantifiedWhereClause>]> {
882 let resolver = param_id.parent.resolver(db.upcast()); 902 let resolver = param_id.parent.resolver(db.upcast());
883 let ctx = 903 let ctx =
884 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 904 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
@@ -896,7 +916,9 @@ pub(crate) fn generic_predicates_for_param_query(
896 }, 916 },
897 WherePredicate::Lifetime { .. } => false, 917 WherePredicate::Lifetime { .. } => false,
898 }) 918 })
899 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) 919 .flat_map(|pred| {
920 ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
921 })
900 .collect() 922 .collect()
901} 923}
902 924
@@ -904,7 +926,7 @@ pub(crate) fn generic_predicates_for_param_recover(
904 _db: &dyn HirDatabase, 926 _db: &dyn HirDatabase,
905 _cycle: &[String], 927 _cycle: &[String],
906 _param_id: &TypeParamId, 928 _param_id: &TypeParamId,
907) -> Arc<[Binders<WhereClause>]> { 929) -> Arc<[Binders<QuantifiedWhereClause>]> {
908 Arc::new([]) 930 Arc::new([])
909} 931}
910 932
@@ -918,8 +940,8 @@ pub(crate) fn trait_environment_query(
918 let mut traits_in_scope = Vec::new(); 940 let mut traits_in_scope = Vec::new();
919 let mut clauses = Vec::new(); 941 let mut clauses = Vec::new();
920 for pred in resolver.where_predicates_in_scope() { 942 for pred in resolver.where_predicates_in_scope() {
921 for pred in ctx.lower_where_predicate(pred) { 943 for pred in ctx.lower_where_predicate(pred, false) {
922 if let WhereClause::Implemented(tr) = &pred { 944 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
923 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 945 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
924 } 946 }
925 let program_clause: chalk_ir::ProgramClause<Interner> = 947 let program_clause: chalk_ir::ProgramClause<Interner> =
@@ -946,8 +968,7 @@ pub(crate) fn trait_environment_query(
946 let substs = Substitution::type_params(db, trait_id); 968 let substs = Substitution::type_params(db, trait_id);
947 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 969 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
948 let pred = WhereClause::Implemented(trait_ref); 970 let pred = WhereClause::Implemented(trait_ref);
949 let program_clause: chalk_ir::ProgramClause<Interner> = 971 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner);
950 pred.clone().to_chalk(db).cast(&Interner);
951 clauses.push(program_clause.into_from_env_clause(&Interner)); 972 clauses.push(program_clause.into_from_env_clause(&Interner));
952 } 973 }
953 974
@@ -960,14 +981,16 @@ pub(crate) fn trait_environment_query(
960pub(crate) fn generic_predicates_query( 981pub(crate) fn generic_predicates_query(
961 db: &dyn HirDatabase, 982 db: &dyn HirDatabase,
962 def: GenericDefId, 983 def: GenericDefId,
963) -> Arc<[Binders<WhereClause>]> { 984) -> Arc<[Binders<QuantifiedWhereClause>]> {
964 let resolver = def.resolver(db.upcast()); 985 let resolver = def.resolver(db.upcast());
965 let ctx = 986 let ctx =
966 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 987 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
967 let generics = generics(db.upcast(), def); 988 let generics = generics(db.upcast(), def);
968 resolver 989 resolver
969 .where_predicates_in_scope() 990 .where_predicates_in_scope()
970 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) 991 .flat_map(|pred| {
992 ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
993 })
971 .collect() 994 .collect()
972} 995}
973 996
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index da6bc2a4a..8e986ddde 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,7 +6,7 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::{cast::Cast, Mutability}; 9use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
12 ImplId, Lookup, ModuleId, TraitId, 12 ImplId, Lookup, ModuleId, TraitId,
@@ -21,8 +21,9 @@ use crate::{
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id, 22 to_chalk_trait_id,
23 utils::all_super_traits, 23 utils::all_super_traits,
24 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind,
26 TypeWalk,
26}; 27};
27 28
28/// This is used as a key for indexing impls. 29/// This is used as a key for indexing impls.
@@ -375,7 +376,7 @@ fn iterate_method_candidates_impl(
375 // Also note that when we've got a receiver like &S, even if the method we 376 // Also note that when we've got a receiver like &S, even if the method we
376 // find in the end takes &self, we still do the autoderef step (just as 377 // find in the end takes &self, we still do the autoderef step (just as
377 // rustc does an autoderef and then autoref again). 378 // rustc does an autoderef and then autoref again).
378 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 379 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
379 380
380 // We have to be careful about the order we're looking at candidates 381 // We have to be careful about the order we're looking at candidates
381 // in here. Consider the case where we're resolving `x.clone()` 382 // in here. Consider the case where we're resolving `x.clone()`
@@ -443,7 +444,7 @@ fn iterate_method_candidates_with_autoref(
443 return true; 444 return true;
444 } 445 }
445 let refed = Canonical { 446 let refed = Canonical {
446 kinds: deref_chain[0].kinds.clone(), 447 binders: deref_chain[0].binders.clone(),
447 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 448 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner),
448 }; 449 };
449 if iterate_method_candidates_by_receiver( 450 if iterate_method_candidates_by_receiver(
@@ -459,7 +460,7 @@ fn iterate_method_candidates_with_autoref(
459 return true; 460 return true;
460 } 461 }
461 let ref_muted = Canonical { 462 let ref_muted = Canonical {
462 kinds: deref_chain[0].kinds.clone(), 463 binders: deref_chain[0].binders.clone(),
463 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 464 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner),
464 }; 465 };
465 if iterate_method_candidates_by_receiver( 466 if iterate_method_candidates_by_receiver(
@@ -621,7 +622,7 @@ pub fn resolve_indexing_op(
621 krate: CrateId, 622 krate: CrateId,
622 index_trait: TraitId, 623 index_trait: TraitId,
623) -> Option<Canonical<Ty>> { 624) -> Option<Canonical<Ty>> {
624 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 625 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
625 let deref_chain = autoderef_method_receiver(db, krate, ty); 626 let deref_chain = autoderef_method_receiver(db, krate, ty);
626 for ty in deref_chain { 627 for ty in deref_chain {
627 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); 628 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
@@ -677,19 +678,28 @@ pub(crate) fn inherent_impl_substs(
677 // we create a var for each type parameter of the impl; we need to keep in 678 // we create a var for each type parameter of the impl; we need to keep in
678 // mind here that `self_ty` might have vars of its own 679 // mind here that `self_ty` might have vars of its own
679 let vars = Substitution::build_for_def(db, impl_id) 680 let vars = Substitution::build_for_def(db, impl_id)
680 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) 681 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
681 .build(); 682 .build();
682 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 683 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
683 let mut kinds = self_ty.kinds.to_vec(); 684 let mut kinds = self_ty.binders.interned().to_vec();
684 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len())); 685 kinds.extend(
685 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; 686 iter::repeat(chalk_ir::WithKind::new(
687 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
688 UniverseIndex::ROOT,
689 ))
690 .take(vars.len()),
691 );
692 let tys = Canonical {
693 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
694 value: (self_ty_with_vars, self_ty.value.clone()),
695 };
686 let substs = super::infer::unify(&tys); 696 let substs = super::infer::unify(&tys);
687 // We only want the substs for the vars we added, not the ones from self_ty. 697 // We only want the substs for the vars we added, not the ones from self_ty.
688 // Also, if any of the vars we added are still in there, we replace them by 698 // Also, if any of the vars we added are still in there, we replace them by
689 // Unknown. I think this can only really happen if self_ty contained 699 // Unknown. I think this can only really happen if self_ty contained
690 // Unknown, and in that case we want the result to contain Unknown in those 700 // Unknown, and in that case we want the result to contain Unknown in those
691 // places again. 701 // places again.
692 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len())) 702 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner)))
693} 703}
694 704
695/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 705/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -768,15 +778,24 @@ fn generic_implements_goal(
768 trait_: TraitId, 778 trait_: TraitId,
769 self_ty: Canonical<Ty>, 779 self_ty: Canonical<Ty>,
770) -> Canonical<InEnvironment<super::DomainGoal>> { 780) -> Canonical<InEnvironment<super::DomainGoal>> {
771 let mut kinds = self_ty.kinds.to_vec(); 781 let mut kinds = self_ty.binders.interned().to_vec();
772 let substs = super::Substitution::build_for_def(db, trait_) 782 let substs = super::Substitution::build_for_def(db, trait_)
773 .push(self_ty.value) 783 .push(self_ty.value)
774 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 784 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
775 .build(); 785 .build();
776 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); 786 kinds.extend(
787 iter::repeat(chalk_ir::WithKind::new(
788 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
789 UniverseIndex::ROOT,
790 ))
791 .take(substs.len() - 1),
792 );
777 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; 793 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
778 let obligation = trait_ref.cast(&Interner); 794 let obligation = trait_ref.cast(&Interner);
779 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 795 Canonical {
796 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
797 value: InEnvironment::new(env.env.clone(), obligation),
798 }
780} 799}
781 800
782fn autoderef_method_receiver( 801fn autoderef_method_receiver(
@@ -789,9 +808,9 @@ fn autoderef_method_receiver(
789 if let Some(TyKind::Array(parameters)) = 808 if let Some(TyKind::Array(parameters)) =
790 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 809 deref_chain.last().map(|ty| ty.value.interned(&Interner))
791 { 810 {
792 let kinds = deref_chain.last().unwrap().kinds.clone(); 811 let kinds = deref_chain.last().unwrap().binders.clone();
793 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 812 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
794 deref_chain.push(Canonical { value: unsized_ty, kinds }) 813 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
795 } 814 }
796 deref_chain 815 deref_chain
797} 816}
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index 0a4141e69..ad283c1e0 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -369,3 +369,72 @@ fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
369 actual.push('\n'); 369 actual.push('\n');
370 expect.assert_eq(&actual); 370 expect.assert_eq(&actual);
371} 371}
372
373#[test]
374fn salsa_bug() {
375 let (mut db, pos) = TestDB::with_position(
376 "
377 //- /lib.rs
378 trait Index {
379 type Output;
380 }
381
382 type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
383
384 pub trait UnificationStoreBase: Index<Output = Key<Self>> {
385 type Key;
386
387 fn len(&self) -> usize;
388 }
389
390 pub trait UnificationStoreMut: UnificationStoreBase {
391 fn push(&mut self, value: Self::Key);
392 }
393
394 fn main() {
395 let x = 1;
396 x.push(1);$0
397 }
398 ",
399 );
400
401 let module = db.module_for_file(pos.file_id);
402 let crate_def_map = module.def_map(&db);
403 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
404 db.infer(def);
405 });
406
407 let new_text = "
408 //- /lib.rs
409 trait Index {
410 type Output;
411 }
412
413 type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
414
415 pub trait UnificationStoreBase: Index<Output = Key<Self>> {
416 type Key;
417
418 fn len(&self) -> usize;
419 }
420
421 pub trait UnificationStoreMut: UnificationStoreBase {
422 fn push(&mut self, value: Self::Key);
423 }
424
425 fn main() {
426
427 let x = 1;
428 x.push(1);
429 }
430 "
431 .to_string();
432
433 db.set_file_text(pos.file_id, Arc::new(new_text));
434
435 let module = db.module_for_file(pos.file_id);
436 let crate_def_map = module.def_map(&db);
437 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
438 db.infer(def);
439 });
440}
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index c1e605740..12951fb16 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -607,6 +607,29 @@ fn bar() -> u32 {0}
607} 607}
608 608
609#[test] 609#[test]
610fn infer_builtin_macros_include_child_mod() {
611 check_types(
612 r#"
613//- /main.rs
614#[rustc_builtin_macro]
615macro_rules! include {() => {}}
616
617include!("f/foo.rs");
618
619fn main() {
620 bar::bar();
621} //^ u32
622
623//- /f/foo.rs
624pub mod bar;
625
626//- /f/bar.rs
627pub fn bar() -> u32 {0}
628"#,
629 );
630}
631
632#[test]
610fn infer_builtin_macros_include_str() { 633fn infer_builtin_macros_include_str() {
611 check_types( 634 check_types(
612 r#" 635 r#"
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 5da19ba5f..85a28e76b 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -658,6 +658,28 @@ fn slice_tail_pattern() {
658fn box_pattern() { 658fn box_pattern() {
659 check_infer( 659 check_infer(
660 r#" 660 r#"
661 pub struct Global;
662 #[lang = "owned_box"]
663 pub struct Box<T, A = Global>(T);
664
665 fn foo(params: Box<i32>) {
666 match params {
667 box integer => {}
668 }
669 }
670 "#,
671 expect![[r#"
672 83..89 'params': Box<i32, Global>
673 101..155 '{ ... } }': ()
674 107..153 'match ... }': ()
675 113..119 'params': Box<i32, Global>
676 130..141 'box integer': Box<i32, Global>
677 134..141 'integer': i32
678 145..147 '{}': ()
679 "#]],
680 );
681 check_infer(
682 r#"
661 #[lang = "owned_box"] 683 #[lang = "owned_box"]
662 pub struct Box<T>(T); 684 pub struct Box<T>(T);
663 685
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 8f2bdffc0..37cd04c6f 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -2272,6 +2272,56 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
2272} 2272}
2273 2273
2274#[test] 2274#[test]
2275fn unselected_projection_in_trait_env_cycle_3() {
2276 // this is a cycle for rustc; we currently accept it
2277 check_types(
2278 r#"
2279//- /main.rs
2280trait Trait {
2281 type Item;
2282 type OtherItem;
2283}
2284
2285fn test<T>() where T: Trait<OtherItem = T::Item> {
2286 let x: T::Item = no_matter;
2287} //^ Trait::Item<T>
2288"#,
2289 );
2290}
2291
2292#[test]
2293fn unselected_projection_in_trait_env_no_cycle() {
2294 // this is not a cycle
2295 check_types(
2296 r#"
2297//- /main.rs
2298trait Index {
2299 type Output;
2300}
2301
2302type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
2303
2304pub trait UnificationStoreBase: Index<Output = Key<Self>> {
2305 type Key;
2306
2307 fn len(&self) -> usize;
2308}
2309
2310pub trait UnificationStoreMut: UnificationStoreBase {
2311 fn push(&mut self, value: Self::Key);
2312}
2313
2314fn test<T>(t: T) where T: UnificationStoreMut {
2315 let x;
2316 t.push(x);
2317 let y: Key<T>;
2318 (x, y);
2319} //^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
2320"#,
2321 );
2322}
2323
2324#[test]
2275fn inline_assoc_type_bounds_1() { 2325fn inline_assoc_type_bounds_1() {
2276 check_types( 2326 check_types(
2277 r#" 2327 r#"
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 7dadd1ffb..ccee0e5ad 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -1,6 +1,5 @@
1//! Trait solving using Chalk. 1//! Trait solving using Chalk.
2use std::env::var; 2use std::env::var;
3use std::sync::Arc;
4 3
5use base_db::CrateId; 4use base_db::CrateId;
6use chalk_ir::cast::Cast; 5use chalk_ir::cast::Cast;
@@ -44,7 +43,7 @@ pub struct TraitEnvironment {
44 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, 43 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord,
45 // but for now it's too annoying... 44 // but for now it's too annoying...
46 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, 45 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>,
47 pub(crate) env: chalk_ir::Environment<Interner>, 46 pub env: chalk_ir::Environment<Interner>,
48} 47}
49 48
50impl TraitEnvironment { 49impl TraitEnvironment {
@@ -74,13 +73,13 @@ impl Default for TraitEnvironment {
74/// Something (usually a goal), along with an environment. 73/// Something (usually a goal), along with an environment.
75#[derive(Clone, Debug, PartialEq, Eq, Hash)] 74#[derive(Clone, Debug, PartialEq, Eq, Hash)]
76pub struct InEnvironment<T> { 75pub struct InEnvironment<T> {
77 pub environment: Arc<TraitEnvironment>, 76 pub environment: chalk_ir::Environment<Interner>,
78 pub value: T, 77 pub goal: T,
79} 78}
80 79
81impl<T> InEnvironment<T> { 80impl<T> InEnvironment<T> {
82 pub fn new(environment: Arc<TraitEnvironment>, value: T) -> InEnvironment<T> { 81 pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
83 InEnvironment { environment, value } 82 InEnvironment { environment, goal: value }
84 } 83 }
85} 84}
86 85
@@ -126,18 +125,18 @@ pub(crate) fn trait_solve_query(
126 krate: CrateId, 125 krate: CrateId,
127 goal: Canonical<InEnvironment<DomainGoal>>, 126 goal: Canonical<InEnvironment<DomainGoal>>,
128) -> Option<Solution> { 127) -> Option<Solution> {
129 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { 128 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal {
130 DomainGoal::Holds(WhereClause::Implemented(it)) => { 129 DomainGoal::Holds(WhereClause::Implemented(it)) => {
131 db.trait_data(it.hir_trait_id()).name.to_string() 130 db.trait_data(it.hir_trait_id()).name.to_string()
132 } 131 }
133 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), 132 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
134 }); 133 });
135 log::info!("trait_solve_query({})", goal.value.value.display(db)); 134 log::info!("trait_solve_query({})", goal.value.goal.display(db));
136 135
137 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq { 136 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
138 alias: AliasTy::Projection(projection_ty), 137 alias: AliasTy::Projection(projection_ty),
139 .. 138 ..
140 })) = &goal.value.value 139 })) = &goal.value.goal
141 { 140 {
142 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 141 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
143 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 734679414..4019fdf17 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -238,7 +238,10 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
238 }); 238 });
239 let bound = OpaqueTyDatumBound { 239 let bound = OpaqueTyDatumBound {
240 bounds: make_binders( 240 bounds: make_binders(
241 vec![impl_bound.to_chalk(self.db), proj_bound.to_chalk(self.db)], 241 vec![
242 wrap_in_empty_binders(impl_bound).to_chalk(self.db),
243 wrap_in_empty_binders(proj_bound).to_chalk(self.db),
244 ],
242 1, 245 1,
243 ), 246 ),
244 where_clauses: make_binders(vec![], 0), 247 where_clauses: make_binders(vec![], 0),
@@ -395,9 +398,8 @@ pub(crate) fn associated_ty_data_query(
395 let bounds = type_alias_data 398 let bounds = type_alias_data
396 .bounds 399 .bounds
397 .iter() 400 .iter()
398 .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone())) 401 .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone(), false))
399 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty)) 402 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
400 .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
401 .collect(); 403 .collect();
402 404
403 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars); 405 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
@@ -720,3 +722,7 @@ impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
720 chalk_ir::ClosureId(id.as_intern_id()) 722 chalk_ir::ClosureId(id.as_intern_id())
721 } 723 }
722} 724}
725
726fn wrap_in_empty_binders<T: crate::TypeWalk>(value: T) -> crate::Binders<T> {
727 crate::Binders::wrap_empty(value)
728}
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 65feb82e5..aef6b8a15 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -7,15 +7,14 @@ use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeDa
7use chalk_solve::rust_ir; 7use chalk_solve::rust_ir;
8 8
9use base_db::salsa::InternKey; 9use base_db::salsa::InternKey;
10use hir_def::{AssocContainerId, GenericDefId, Lookup, TypeAliasId}; 10use hir_def::{GenericDefId, TypeAliasId};
11 11
12use crate::{ 12use crate::{
13 db::HirDatabase, 13 db::HirDatabase,
14 from_assoc_type_id,
15 primitive::UintTy, 14 primitive::UintTy,
16 traits::{Canonical, DomainGoal}, 15 traits::{Canonical, DomainGoal},
17 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution, 16 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy,
18 TraitRef, Ty, WhereClause, 17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
19}; 18};
20 19
21use super::interner::*; 20use super::interner::*;
@@ -95,10 +94,10 @@ impl ToChalk for Ty {
95 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner), 94 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner),
96 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), 95 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
97 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"), 96 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
98 TyKind::Dyn(predicates) => { 97 TyKind::Dyn(dyn_ty) => {
99 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 98 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
100 &Interner, 99 &Interner,
101 predicates.iter().cloned().map(|p| p.to_chalk(db)), 100 dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)),
102 ); 101 );
103 let bounded_ty = chalk_ir::DynTy { 102 let bounded_ty = chalk_ir::DynTy {
104 bounds: make_binders(where_clauses, 1), 103 bounds: make_binders(where_clauses, 1),
@@ -144,13 +143,17 @@ impl ToChalk for Ty {
144 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown, 143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
145 chalk_ir::TyKind::Dyn(where_clauses) => { 144 chalk_ir::TyKind::Dyn(where_clauses) => {
146 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 145 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
147 let predicates = where_clauses 146 let bounds = where_clauses
148 .bounds 147 .bounds
149 .skip_binders() 148 .skip_binders()
150 .iter(&Interner) 149 .iter(&Interner)
151 .map(|c| from_chalk(db, c.clone())) 150 .map(|c| from_chalk(db, c.clone()));
152 .collect(); 151 TyKind::Dyn(crate::DynTy {
153 TyKind::Dyn(predicates) 152 bounds: crate::Binders::new(
153 1,
154 crate::QuantifiedWhereClauses::from_iter(&Interner, bounds),
155 ),
156 })
154 } 157 }
155 158
156 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)), 159 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)),
@@ -305,33 +308,22 @@ impl ToChalk for TypeAliasAsValue {
305} 308}
306 309
307impl ToChalk for WhereClause { 310impl ToChalk for WhereClause {
308 type Chalk = chalk_ir::QuantifiedWhereClause<Interner>; 311 type Chalk = chalk_ir::WhereClause<Interner>;
309 312
310 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> { 313 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::WhereClause<Interner> {
311 match self { 314 match self {
312 WhereClause::Implemented(trait_ref) => { 315 WhereClause::Implemented(trait_ref) => {
313 let chalk_trait_ref = trait_ref.to_chalk(db); 316 chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db))
314 let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner);
315 make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0)
316 } 317 }
317 WhereClause::AliasEq(alias_eq) => make_binders( 318 WhereClause::AliasEq(alias_eq) => chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db)),
318 chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)),
319 0,
320 ),
321 } 319 }
322 } 320 }
323 321
324 fn from_chalk( 322 fn from_chalk(
325 db: &dyn HirDatabase, 323 db: &dyn HirDatabase,
326 where_clause: chalk_ir::QuantifiedWhereClause<Interner>, 324 where_clause: chalk_ir::WhereClause<Interner>,
327 ) -> WhereClause { 325 ) -> WhereClause {
328 // we don't produce any where clauses with binders and can't currently deal with them 326 match where_clause {
329 match where_clause
330 .skip_binders()
331 .clone()
332 .shifted_out(&Interner)
333 .expect("unexpected bound vars in where clause")
334 {
335 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)), 327 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)),
336 chalk_ir::WhereClause::AliasEq(alias_eq) => { 328 chalk_ir::WhereClause::AliasEq(alias_eq) => {
337 WhereClause::AliasEq(from_chalk(db, alias_eq)) 329 WhereClause::AliasEq(from_chalk(db, alias_eq))
@@ -447,35 +439,12 @@ where
447 type Chalk = chalk_ir::Canonical<T::Chalk>; 439 type Chalk = chalk_ir::Canonical<T::Chalk>;
448 440
449 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { 441 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
450 let kinds = self.kinds.iter().map(|&tk| {
451 chalk_ir::CanonicalVarKind::new(
452 chalk_ir::VariableKind::Ty(tk),
453 chalk_ir::UniverseIndex::ROOT,
454 )
455 });
456 let value = self.value.to_chalk(db); 442 let value = self.value.to_chalk(db);
457 chalk_ir::Canonical { 443 chalk_ir::Canonical { value, binders: self.binders }
458 value,
459 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
460 }
461 } 444 }
462 445
463 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { 446 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
464 let kinds = canonical 447 Canonical { binders: canonical.binders, value: from_chalk(db, canonical.value) }
465 .binders
466 .iter(&Interner)
467 .map(|k| match k.kind {
468 chalk_ir::VariableKind::Ty(tk) => tk,
469 // HACK: Chalk can sometimes return new lifetime variables. We
470 // want to just skip them, but to not mess up the indices of
471 // other variables, we'll just create a new type variable in
472 // their place instead. This should not matter (we never see the
473 // actual *uses* of the lifetime variable).
474 chalk_ir::VariableKind::Lifetime => chalk_ir::TyVariableKind::General,
475 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
476 })
477 .collect();
478 Canonical { kinds, value: from_chalk(db, canonical.value) }
479 } 448 }
480} 449}
481 450
@@ -486,10 +455,7 @@ where
486 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 455 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
487 456
488 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { 457 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
489 chalk_ir::InEnvironment { 458 chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
490 environment: self.environment.env.clone(),
491 goal: self.value.to_chalk(db),
492 }
493 } 459 }
494 460
495 fn from_chalk( 461 fn from_chalk(
@@ -500,6 +466,29 @@ where
500 } 466 }
501} 467}
502 468
469impl<T: ToChalk> ToChalk for crate::Binders<T>
470where
471 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
472{
473 type Chalk = chalk_ir::Binders<T::Chalk>;
474
475 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
476 chalk_ir::Binders::new(
477 chalk_ir::VariableKinds::from_iter(
478 &Interner,
479 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
480 .take(self.num_binders),
481 ),
482 self.value.to_chalk(db),
483 )
484 }
485
486 fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
487 let (v, b) = binders.into_value_and_skipped_binders();
488 crate::Binders::new(b.len(&Interner), from_chalk(db, v))
489 }
490}
491
503pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> 492pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
504where 493where
505 T: HasInterner<Interner = Interner>, 494 T: HasInterner<Interner = Interner>,
@@ -529,14 +518,15 @@ pub(super) fn convert_where_clauses(
529 518
530pub(super) fn generic_predicate_to_inline_bound( 519pub(super) fn generic_predicate_to_inline_bound(
531 db: &dyn HirDatabase, 520 db: &dyn HirDatabase,
532 pred: &WhereClause, 521 pred: &QuantifiedWhereClause,
533 self_ty: &Ty, 522 self_ty: &Ty,
534) -> Option<rust_ir::InlineBound<Interner>> { 523) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
535 // An InlineBound is like a GenericPredicate, except the self type is left out. 524 // An InlineBound is like a GenericPredicate, except the self type is left out.
536 // We don't have a special type for this, but Chalk does. 525 // We don't have a special type for this, but Chalk does.
537 match pred { 526 let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
527 match &pred.value {
538 WhereClause::Implemented(trait_ref) => { 528 WhereClause::Implemented(trait_ref) => {
539 if &trait_ref.substitution[0] != self_ty { 529 if trait_ref.self_type_parameter() != &self_ty_shifted_in {
540 // we can only convert predicates back to type bounds if they 530 // we can only convert predicates back to type bounds if they
541 // have the expected self type 531 // have the expected self type
542 return None; 532 return None;
@@ -546,19 +536,13 @@ pub(super) fn generic_predicate_to_inline_bound(
546 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 536 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
547 .collect(); 537 .collect();
548 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 538 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
549 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 539 Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
550 } 540 }
551 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 541 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
552 if &projection_ty.substitution[0] != self_ty { 542 if projection_ty.self_type_parameter() != &self_ty_shifted_in {
553 return None; 543 return None;
554 } 544 }
555 let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id) 545 let trait_ = projection_ty.trait_(db);
556 .lookup(db.upcast())
557 .container
558 {
559 AssocContainerId::TraitId(t) => t,
560 _ => panic!("associated type not in trait"),
561 };
562 let args_no_self = projection_ty.substitution[1..] 546 let args_no_self = projection_ty.substitution[1..]
563 .iter() 547 .iter()
564 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 548 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
@@ -569,7 +553,7 @@ pub(super) fn generic_predicate_to_inline_bound(
569 associated_ty_id: projection_ty.associated_ty_id, 553 associated_ty_id: projection_ty.associated_ty_id,
570 parameters: Vec::new(), // FIXME we don't support generic associated types yet 554 parameters: Vec::new(), // FIXME we don't support generic associated types yet
571 }; 555 };
572 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) 556 Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
573 } 557 }
574 _ => None, 558 _ => None,
575 } 559 }
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 1ec1ecd43..19874e42b 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -63,7 +63,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
63 db.generic_predicates_for_param(trait_self) 63 db.generic_predicates_for_param(trait_self)
64 .iter() 64 .iter()
65 .filter_map(|pred| { 65 .filter_map(|pred| {
66 pred.as_ref().filter_map(|pred| match pred { 66 pred.as_ref().filter_map(|pred| match pred.skip_binders() {
67 WhereClause::Implemented(tr) => Some(tr.clone()), 67 WhereClause::Implemented(tr) => Some(tr.clone()),
68 _ => None, 68 _ => None,
69 }) 69 })
diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs
index e187243cb..5201ce587 100644
--- a/crates/ide/src/extend_selection.rs
+++ b/crates/ide/src/extend_selection.rs
@@ -263,11 +263,10 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
263 ) -> Option<SyntaxToken> { 263 ) -> Option<SyntaxToken> {
264 node.siblings_with_tokens(dir) 264 node.siblings_with_tokens(dir)
265 .skip(1) 265 .skip(1)
266 .skip_while(|node| match node { 266 .find(|node| match node {
267 NodeOrToken::Node(_) => false, 267 NodeOrToken::Node(_) => true,
268 NodeOrToken::Token(it) => is_single_line_ws(it), 268 NodeOrToken::Token(it) => !is_single_line_ws(it),
269 }) 269 })
270 .next()
271 .and_then(|it| it.into_token()) 270 .and_then(|it| it.into_token())
272 .filter(|node| node.kind() == delimiter_kind) 271 .filter(|node| node.kind() == delimiter_kind)
273 } 272 }
diff --git a/crates/ide_assists/src/handlers/convert_comment_block.rs b/crates/ide_assists/src/handlers/convert_comment_block.rs
index cdc45fc42..9dc3ee28f 100644
--- a/crates/ide_assists/src/handlers/convert_comment_block.rs
+++ b/crates/ide_assists/src/handlers/convert_comment_block.rs
@@ -1,5 +1,4 @@
1use itertools::Itertools; 1use itertools::Itertools;
2use std::convert::identity;
3use syntax::{ 2use syntax::{
4 ast::{ 3 ast::{
5 self, 4 self,
@@ -140,7 +139,7 @@ fn relevant_line_comments(comment: &ast::Comment) -> Vec<Comment> {
140 .filter(|s| !skippable(s)) 139 .filter(|s| !skippable(s))
141 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix)) 140 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix))
142 .take_while(|opt_com| opt_com.is_some()) 141 .take_while(|opt_com| opt_com.is_some())
143 .filter_map(identity) 142 .flatten()
144 .skip(1); // skip the first element so we don't duplicate it in next_comments 143 .skip(1); // skip the first element so we don't duplicate it in next_comments
145 144
146 let next_comments = comment 145 let next_comments = comment
@@ -149,7 +148,7 @@ fn relevant_line_comments(comment: &ast::Comment) -> Vec<Comment> {
149 .filter(|s| !skippable(s)) 148 .filter(|s| !skippable(s))
150 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix)) 149 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix))
151 .take_while(|opt_com| opt_com.is_some()) 150 .take_while(|opt_com| opt_com.is_some())
152 .filter_map(identity); 151 .flatten();
153 152
154 let mut comments: Vec<_> = prev_comments.collect(); 153 let mut comments: Vec<_> = prev_comments.collect();
155 comments.reverse(); 154 comments.reverse();
diff --git a/crates/ide_assists/src/handlers/expand_glob_import.rs b/crates/ide_assists/src/handlers/expand_glob_import.rs
index 83aa11d52..98389e4f7 100644
--- a/crates/ide_assists/src/handlers/expand_glob_import.rs
+++ b/crates/ide_assists/src/handlers/expand_glob_import.rs
@@ -136,18 +136,13 @@ impl Refs {
136 .into_iter() 136 .into_iter()
137 .filter(|r| { 137 .filter(|r| {
138 if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def { 138 if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def {
139 if tr 139 if tr.items(ctx.db()).into_iter().any(|ai| {
140 .items(ctx.db()) 140 if let AssocItem::Function(f) = ai {
141 .into_iter() 141 Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx)
142 .find(|ai| { 142 } else {
143 if let AssocItem::Function(f) = *ai { 143 false
144 Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx) 144 }
145 } else { 145 }) {
146 false
147 }
148 })
149 .is_some()
150 {
151 return true; 146 return true;
152 } 147 }
153 } 148 }
diff --git a/crates/ide_assists/src/handlers/reorder_impl.rs b/crates/ide_assists/src/handlers/reorder_impl.rs
index edf4b0bfe..f976e73ad 100644
--- a/crates/ide_assists/src/handlers/reorder_impl.rs
+++ b/crates/ide_assists/src/handlers/reorder_impl.rs
@@ -95,7 +95,7 @@ fn compute_method_ranks(path: &ast::Path, ctx: &AssistContext) -> Option<FxHashM
95 _ => None, 95 _ => None,
96 }) 96 })
97 .enumerate() 97 .enumerate()
98 .map(|(idx, func)| ((func.name(ctx.db()).to_string(), idx))) 98 .map(|(idx, func)| (func.name(ctx.db()).to_string(), idx))
99 .collect(), 99 .collect(),
100 ) 100 )
101} 101}
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 628c1fb9b..5eeddf7a4 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -70,6 +70,16 @@ fn func<'lifetime>(foo: &'li$0) {}
70fn func<'lifetime>(foo: &'lifetime) {} 70fn func<'lifetime>(foo: &'lifetime) {}
71"#, 71"#,
72 ); 72 );
73 cov_mark::check!(completes_if_lifetime_without_idents);
74 check_edit(
75 "'lifetime",
76 r#"
77fn func<'lifetime>(foo: &'$0) {}
78"#,
79 r#"
80fn func<'lifetime>(foo: &'lifetime) {}
81"#,
82 );
73 } 83 }
74 84
75 #[test] 85 #[test]
@@ -192,6 +202,27 @@ fn foo<'footime, 'lifetime: 'a$0>() {}
192 } 202 }
193 203
194 #[test] 204 #[test]
205 fn check_label_edit() {
206 check_edit(
207 "'label",
208 r#"
209fn foo() {
210 'label: loop {
211 break '$0
212 }
213}
214"#,
215 r#"
216fn foo() {
217 'label: loop {
218 break 'label
219 }
220}
221"#,
222 );
223 }
224
225 #[test]
195 fn complete_label_in_loop() { 226 fn complete_label_in_loop() {
196 check( 227 check(
197 r#" 228 r#"
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 67e2d6f6c..32f81aec1 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -255,6 +255,10 @@ impl<'a> CompletionContext<'a> {
255 if kind == IDENT || kind == LIFETIME_IDENT || kind == UNDERSCORE || kind.is_keyword() { 255 if kind == IDENT || kind == LIFETIME_IDENT || kind == UNDERSCORE || kind.is_keyword() {
256 cov_mark::hit!(completes_if_prefix_is_keyword); 256 cov_mark::hit!(completes_if_prefix_is_keyword);
257 self.original_token.text_range() 257 self.original_token.text_range()
258 } else if kind == CHAR {
259 // assume we are completing a lifetime but the user has only typed the '
260 cov_mark::hit!(completes_if_lifetime_without_idents);
261 TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
258 } else { 262 } else {
259 TextRange::empty(self.position.offset) 263 TextRange::empty(self.position.offset)
260 } 264 }
@@ -471,7 +475,7 @@ impl<'a> CompletionContext<'a> {
471 self.lifetime_syntax = 475 self.lifetime_syntax =
472 find_node_at_offset(original_file, lifetime.syntax().text_range().start()); 476 find_node_at_offset(original_file, lifetime.syntax().text_range().start());
473 if let Some(parent) = lifetime.syntax().parent() { 477 if let Some(parent) = lifetime.syntax().parent() {
474 if parent.kind() == syntax::SyntaxKind::ERROR { 478 if parent.kind() == ERROR {
475 return; 479 return;
476 } 480 }
477 481
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs
index cf5ef07b7..d82564381 100644
--- a/crates/ide_completion/src/patterns.rs
+++ b/crates/ide_completion/src/patterns.rs
@@ -71,7 +71,7 @@ fn test_has_block_expr_parent() {
71} 71}
72 72
73pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { 73pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool {
74 element.ancestors().find(|it| it.kind() == IDENT_PAT).is_some() 74 element.ancestors().any(|it| it.kind() == IDENT_PAT)
75} 75}
76#[test] 76#[test]
77fn test_has_bind_pat_parent() { 77fn test_has_bind_pat_parent() {
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index 9e0cb91c3..37acf95f0 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -14,10 +14,12 @@ use syntax::{
14 AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, 14 AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
15}; 15};
16 16
17pub use hir::PrefixKind;
18
17#[derive(Clone, Copy, Debug, PartialEq, Eq)] 19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub struct InsertUseConfig { 20pub struct InsertUseConfig {
19 pub merge: Option<MergeBehavior>, 21 pub merge: Option<MergeBehavior>,
20 pub prefix_kind: hir::PrefixKind, 22 pub prefix_kind: PrefixKind,
21 pub group: bool, 23 pub group: bool,
22} 24}
23 25
diff --git a/crates/ide_ssr/src/parsing.rs b/crates/ide_ssr/src/parsing.rs
index 5ff25cb6d..5e757e701 100644
--- a/crates/ide_ssr/src/parsing.rs
+++ b/crates/ide_ssr/src/parsing.rs
@@ -67,7 +67,7 @@ impl ParsedRule {
67 ) -> Result<Vec<ParsedRule>, SsrError> { 67 ) -> Result<Vec<ParsedRule>, SsrError> {
68 let raw_pattern = pattern.as_rust_code(); 68 let raw_pattern = pattern.as_rust_code();
69 let raw_template = template.map(|t| t.as_rust_code()); 69 let raw_template = template.map(|t| t.as_rust_code());
70 let raw_template = raw_template.as_ref().map(|s| s.as_str()); 70 let raw_template = raw_template.as_deref();
71 let mut builder = RuleBuilder { 71 let mut builder = RuleBuilder {
72 placeholders_by_stand_in: pattern.placeholders_by_stand_in(), 72 placeholders_by_stand_in: pattern.placeholders_by_stand_in(),
73 rules: Vec::new(), 73 rules: Vec::new(),
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 1682b21b0..75d2f2eed 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -304,7 +304,7 @@ impl BindingsBuilder {
304 link_nodes: &'a Vec<LinkNode<Rc<BindingKind>>>, 304 link_nodes: &'a Vec<LinkNode<Rc<BindingKind>>>,
305 nodes: &mut Vec<&'a Rc<BindingKind>>, 305 nodes: &mut Vec<&'a Rc<BindingKind>>,
306 ) { 306 ) {
307 link_nodes.into_iter().for_each(|it| match it { 307 link_nodes.iter().for_each(|it| match it {
308 LinkNode::Node(it) => nodes.push(it), 308 LinkNode::Node(it) => nodes.push(it),
309 LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes), 309 LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes),
310 }); 310 });
@@ -713,10 +713,9 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
713 .map(|ident| Some(tt::Leaf::from(ident.clone()).into())) 713 .map(|ident| Some(tt::Leaf::from(ident.clone()).into()))
714 .map_err(|()| err!("expected ident")), 714 .map_err(|()| err!("expected ident")),
715 "tt" => input.expect_tt().map(Some).map_err(|()| err!()), 715 "tt" => input.expect_tt().map(Some).map_err(|()| err!()),
716 "lifetime" => input 716 "lifetime" => {
717 .expect_lifetime() 717 input.expect_lifetime().map(Some).map_err(|()| err!("expected lifetime"))
718 .map(|tt| Some(tt)) 718 }
719 .map_err(|()| err!("expected lifetime")),
720 "literal" => { 719 "literal" => {
721 let neg = input.eat_char('-'); 720 let neg = input.eat_char('-');
722 input 721 input
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index 33b85e23d..e74f8cf3f 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -356,6 +356,6 @@ impl<T> ExpandResult<T> {
356 356
357impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> { 357impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> {
358 fn from(result: Result<T, ExpandError>) -> Self { 358 fn from(result: Result<T, ExpandError>) -> Self {
359 result.map_or_else(|e| Self::only_err(e), |it| Self::ok(it)) 359 result.map_or_else(Self::only_err, Self::ok)
360 } 360 }
361} 361}
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index c88387653..61b2a4955 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -57,7 +57,7 @@ impl<'a> Iterator for OpDelimitedIter<'a> {
57 57
58 fn size_hint(&self) -> (usize, Option<usize>) { 58 fn size_hint(&self) -> (usize, Option<usize>) {
59 let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 }; 59 let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 };
60 let remain = len.checked_sub(self.idx).unwrap_or(0); 60 let remain = len.saturating_sub(self.idx);
61 (remain, Some(remain)) 61 (remain, Some(remain))
62 } 62 }
63} 63}
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index 8bba3d3d5..9d433b3b0 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -362,7 +362,7 @@ trait TokenConvertor {
362 if let Some((kind, closed)) = delim { 362 if let Some((kind, closed)) = delim {
363 let mut subtree = tt::Subtree::default(); 363 let mut subtree = tt::Subtree::default();
364 let (id, idx) = self.id_alloc().open_delim(range); 364 let (id, idx) = self.id_alloc().open_delim(range);
365 subtree.delimiter = Some(tt::Delimiter { kind, id }); 365 subtree.delimiter = Some(tt::Delimiter { id, kind });
366 366
367 while self.peek().map(|it| it.kind() != closed).unwrap_or(false) { 367 while self.peek().map(|it| it.kind() != closed).unwrap_or(false) {
368 self.collect_leaf(&mut subtree.token_trees); 368 self.collect_leaf(&mut subtree.token_trees);
diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs
index 2cce62781..8951f3813 100644
--- a/crates/mbe/src/tests/expand.rs
+++ b/crates/mbe/src/tests/expand.rs
@@ -1225,8 +1225,7 @@ macro_rules! m {
1225 ) 1225 )
1226 .expand_statements(r#"m!(C("0"))"#) 1226 .expand_statements(r#"m!(C("0"))"#)
1227 .descendants() 1227 .descendants()
1228 .find(|token| token.kind() == ERROR) 1228 .any(|token| token.kind() == ERROR));
1229 .is_some());
1230} 1229}
1231 1230
1232#[test] 1231#[test]
diff --git a/crates/project_model/src/build_data.rs b/crates/project_model/src/build_data.rs
index 728a258ea..f7050be4e 100644
--- a/crates/project_model/src/build_data.rs
+++ b/crates/project_model/src/build_data.rs
@@ -137,60 +137,53 @@ fn collect_from_workspace(
137 let stdout = BufReader::new(child_stdout); 137 let stdout = BufReader::new(child_stdout);
138 138
139 let mut res = BuildDataMap::default(); 139 let mut res = BuildDataMap::default();
140 for message in cargo_metadata::Message::parse_stream(stdout) { 140 for message in cargo_metadata::Message::parse_stream(stdout).flatten() {
141 if let Ok(message) = message { 141 match message {
142 match message { 142 Message::BuildScriptExecuted(BuildScript {
143 Message::BuildScriptExecuted(BuildScript { 143 package_id, out_dir, cfgs, env, ..
144 package_id, 144 }) => {
145 out_dir, 145 let cfgs = {
146 cfgs, 146 let mut acc = Vec::new();
147 env, 147 for cfg in cfgs {
148 .. 148 match cfg.parse::<CfgFlag>() {
149 }) => { 149 Ok(it) => acc.push(it),
150 let cfgs = { 150 Err(err) => {
151 let mut acc = Vec::new(); 151 anyhow::bail!("invalid cfg from cargo-metadata: {}", err)
152 for cfg in cfgs { 152 }
153 match cfg.parse::<CfgFlag>() { 153 };
154 Ok(it) => acc.push(it),
155 Err(err) => {
156 anyhow::bail!("invalid cfg from cargo-metadata: {}", err)
157 }
158 };
159 }
160 acc
161 };
162 let res = res.entry(package_id.repr.clone()).or_default();
163 // cargo_metadata crate returns default (empty) path for
164 // older cargos, which is not absolute, so work around that.
165 if !out_dir.as_str().is_empty() {
166 let out_dir = AbsPathBuf::assert(PathBuf::from(out_dir.into_os_string()));
167 res.out_dir = Some(out_dir);
168 res.cfgs = cfgs;
169 } 154 }
170 155 acc
171 res.envs = env; 156 };
157 let res = res.entry(package_id.repr.clone()).or_default();
158 // cargo_metadata crate returns default (empty) path for
159 // older cargos, which is not absolute, so work around that.
160 if !out_dir.as_str().is_empty() {
161 let out_dir = AbsPathBuf::assert(PathBuf::from(out_dir.into_os_string()));
162 res.out_dir = Some(out_dir);
163 res.cfgs = cfgs;
172 } 164 }
173 Message::CompilerArtifact(message) => { 165
174 progress(format!("metadata {}", message.target.name)); 166 res.envs = env;
175 167 }
176 if message.target.kind.contains(&"proc-macro".to_string()) { 168 Message::CompilerArtifact(message) => {
177 let package_id = message.package_id; 169 progress(format!("metadata {}", message.target.name));
178 // Skip rmeta file 170
179 if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name)) 171 if message.target.kind.contains(&"proc-macro".to_string()) {
180 { 172 let package_id = message.package_id;
181 let filename = AbsPathBuf::assert(PathBuf::from(&filename)); 173 // Skip rmeta file
182 let res = res.entry(package_id.repr.clone()).or_default(); 174 if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name)) {
183 res.proc_macro_dylib_path = Some(filename); 175 let filename = AbsPathBuf::assert(PathBuf::from(&filename));
184 } 176 let res = res.entry(package_id.repr.clone()).or_default();
177 res.proc_macro_dylib_path = Some(filename);
185 } 178 }
186 } 179 }
187 Message::CompilerMessage(message) => {
188 progress(message.target.name.clone());
189 }
190 Message::BuildFinished(_) => {}
191 Message::TextLine(_) => {}
192 _ => {}
193 } 180 }
181 Message::CompilerMessage(message) => {
182 progress(message.target.name.clone());
183 }
184 Message::BuildFinished(_) => {}
185 Message::TextLine(_) => {}
186 _ => {}
194 } 187 }
195 } 188 }
196 189
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index aa48c455c..7a5bcb8c7 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -33,7 +33,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
33 hover_provider: Some(HoverProviderCapability::Simple(true)), 33 hover_provider: Some(HoverProviderCapability::Simple(true)),
34 completion_provider: Some(CompletionOptions { 34 completion_provider: Some(CompletionOptions {
35 resolve_provider: completions_resolve_provider(client_caps), 35 resolve_provider: completions_resolve_provider(client_caps),
36 trigger_characters: Some(vec![":".to_string(), ".".to_string()]), 36 trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]),
37 all_commit_characters: None, 37 all_commit_characters: None,
38 completion_item: None, 38 completion_item: None,
39 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, 39 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 8f541976e..5c88c3a9b 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -10,10 +10,9 @@
10use std::{ffi::OsString, iter, path::PathBuf}; 10use std::{ffi::OsString, iter, path::PathBuf};
11 11
12use flycheck::FlycheckConfig; 12use flycheck::FlycheckConfig;
13use hir::PrefixKind;
14use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig}; 13use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig};
15use ide_db::helpers::{ 14use ide_db::helpers::{
16 insert_use::{InsertUseConfig, MergeBehavior}, 15 insert_use::{InsertUseConfig, MergeBehavior, PrefixKind},
17 SnippetCap, 16 SnippetCap,
18}; 17};
19use lsp_types::{ClientCapabilities, MarkupKind}; 18use lsp_types::{ClientCapabilities, MarkupKind};
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 984790d35..c63a0eaea 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -242,11 +242,8 @@ impl GlobalState {
242 } 242 }
243 BuildDataProgress::End(collector) => { 243 BuildDataProgress::End(collector) => {
244 self.fetch_build_data_completed(); 244 self.fetch_build_data_completed();
245 let workspaces = (*self.workspaces) 245 let workspaces =
246 .clone() 246 (*self.workspaces).clone().into_iter().map(Ok).collect();
247 .into_iter()
248 .map(|it| Ok(it))
249 .collect();
250 self.switch_workspaces(workspaces, Some(collector)); 247 self.switch_workspaces(workspaces, Some(collector));
251 (Some(Progress::End), None) 248 (Some(Progress::End), None)
252 } 249 }
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index aa8504c3d..76fdbcddd 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -237,7 +237,7 @@ impl GlobalState {
237 None => None, 237 None => None,
238 }; 238 };
239 239
240 if &*self.workspaces == &workspaces && self.workspace_build_data == workspace_build_data { 240 if *self.workspaces == workspaces && self.workspace_build_data == workspace_build_data {
241 return; 241 return;
242 } 242 }
243 243
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 1ddea9278..c1ca7ff9b 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1073,9 +1073,11 @@ pub(crate) fn rename_error(err: RenameError) -> crate::LspError {
1073mod tests { 1073mod tests {
1074 use std::sync::Arc; 1074 use std::sync::Arc;
1075 1075
1076 use hir::PrefixKind;
1077 use ide::Analysis; 1076 use ide::Analysis;
1078 use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap}; 1077 use ide_db::helpers::{
1078 insert_use::{InsertUseConfig, PrefixKind},
1079 SnippetCap,
1080 };
1079 1081
1080 use super::*; 1082 use super::*;
1081 1083
diff --git a/crates/rust-analyzer/tests/rust-analyzer/support.rs b/crates/rust-analyzer/tests/rust-analyzer/support.rs
index cd0c91481..95bf26f01 100644
--- a/crates/rust-analyzer/tests/rust-analyzer/support.rs
+++ b/crates/rust-analyzer/tests/rust-analyzer/support.rs
@@ -54,7 +54,7 @@ impl<'a> Project<'a> {
54 } 54 }
55 55
56 pub(crate) fn server(self) -> Server { 56 pub(crate) fn server(self) -> Server {
57 let tmp_dir = self.tmp_dir.unwrap_or_else(|| TestDir::new()); 57 let tmp_dir = self.tmp_dir.unwrap_or_else(TestDir::new);
58 static INIT: Once = Once::new(); 58 static INIT: Once = Once::new();
59 INIT.call_once(|| { 59 INIT.call_once(|| {
60 env_logger::builder().is_test(true).parse_env("RA_LOG").try_init().unwrap(); 60 env_logger::builder().is_test(true).parse_env("RA_LOG").try_init().unwrap();
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs
index 82ebf9037..a153a9e1c 100644
--- a/crates/syntax/src/algo.rs
+++ b/crates/syntax/src/algo.rs
@@ -567,7 +567,7 @@ impl<'a> SyntaxRewriter<'a> {
567 567
568fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { 568fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
569 match element { 569 match element {
570 NodeOrToken::Node(it) => NodeOrToken::Node(it.green().to_owned()), 570 NodeOrToken::Node(it) => NodeOrToken::Node(it.green()),
571 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()), 571 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()),
572 } 572 }
573} 573}
@@ -625,7 +625,7 @@ fn position_of_child(parent: &SyntaxNode, child: SyntaxElement) -> usize {
625 625
626fn to_green_element(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { 626fn to_green_element(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
627 match element { 627 match element {
628 NodeOrToken::Node(it) => it.green().to_owned().into(), 628 NodeOrToken::Node(it) => it.green().into(),
629 NodeOrToken::Token(it) => it.green().to_owned().into(), 629 NodeOrToken::Token(it) => it.green().to_owned().into(),
630 } 630 }
631} 631}
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 64fac13a7..347862b8a 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -333,8 +333,7 @@ impl ast::Use {
333 .and_then(ast::Whitespace::cast); 333 .and_then(ast::Whitespace::cast);
334 if let Some(next_ws) = next_ws { 334 if let Some(next_ws) = next_ws {
335 let ws_text = next_ws.syntax().text(); 335 let ws_text = next_ws.syntax().text();
336 if ws_text.starts_with('\n') { 336 if let Some(rest) = ws_text.strip_prefix('\n') {
337 let rest = &ws_text[1..];
338 if rest.is_empty() { 337 if rest.is_empty() {
339 res.delete(next_ws.syntax()) 338 res.delete(next_ws.syntax())
340 } else { 339 } else {
@@ -462,8 +461,7 @@ impl ast::MatchArmList {
462 let end = if let Some(comma) = start 461 let end = if let Some(comma) = start
463 .siblings_with_tokens(Direction::Next) 462 .siblings_with_tokens(Direction::Next)
464 .skip(1) 463 .skip(1)
465 .skip_while(|it| it.kind().is_trivia()) 464 .find(|it| !it.kind().is_trivia())
466 .next()
467 .filter(|it| it.kind() == T![,]) 465 .filter(|it| it.kind() == T![,])
468 { 466 {
469 comma 467 comma
@@ -597,7 +595,7 @@ impl IndentLevel {
597 pub fn from_node(node: &SyntaxNode) -> IndentLevel { 595 pub fn from_node(node: &SyntaxNode) -> IndentLevel {
598 match node.first_token() { 596 match node.first_token() {
599 Some(it) => Self::from_token(&it), 597 Some(it) => Self::from_token(&it),
600 None => return IndentLevel(0), 598 None => IndentLevel(0),
601 } 599 }
602 } 600 }
603 601
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index 636ce166d..6317d84ba 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -11,16 +11,16 @@ impl ast::AttrsOwner for ast::Expr {}
11 11
12impl ast::Expr { 12impl ast::Expr {
13 pub fn is_block_like(&self) -> bool { 13 pub fn is_block_like(&self) -> bool {
14 match self { 14 matches!(
15 self,
15 ast::Expr::IfExpr(_) 16 ast::Expr::IfExpr(_)
16 | ast::Expr::LoopExpr(_) 17 | ast::Expr::LoopExpr(_)
17 | ast::Expr::ForExpr(_) 18 | ast::Expr::ForExpr(_)
18 | ast::Expr::WhileExpr(_) 19 | ast::Expr::WhileExpr(_)
19 | ast::Expr::BlockExpr(_) 20 | ast::Expr::BlockExpr(_)
20 | ast::Expr::MatchExpr(_) 21 | ast::Expr::MatchExpr(_)
21 | ast::Expr::EffectExpr(_) => true, 22 | ast::Expr::EffectExpr(_)
22 _ => false, 23 )
23 }
24 } 24 }
25 25
26 pub fn name_ref(&self) -> Option<ast::NameRef> { 26 pub fn name_ref(&self) -> Option<ast::NameRef> {
@@ -151,20 +151,20 @@ pub enum BinOp {
151 151
152impl BinOp { 152impl BinOp {
153 pub fn is_assignment(self) -> bool { 153 pub fn is_assignment(self) -> bool {
154 match self { 154 matches!(
155 self,
155 BinOp::Assignment 156 BinOp::Assignment
156 | BinOp::AddAssign 157 | BinOp::AddAssign
157 | BinOp::DivAssign 158 | BinOp::DivAssign
158 | BinOp::MulAssign 159 | BinOp::MulAssign
159 | BinOp::RemAssign 160 | BinOp::RemAssign
160 | BinOp::ShrAssign 161 | BinOp::ShrAssign
161 | BinOp::ShlAssign 162 | BinOp::ShlAssign
162 | BinOp::SubAssign 163 | BinOp::SubAssign
163 | BinOp::BitOrAssign 164 | BinOp::BitOrAssign
164 | BinOp::BitAndAssign 165 | BinOp::BitAndAssign
165 | BinOp::BitXorAssign => true, 166 | BinOp::BitXorAssign
166 _ => false, 167 )
167 }
168 } 168 }
169} 169}
170 170
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 810c8d4c8..7049affd9 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -532,7 +532,7 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
532} 532}
533 533
534fn unroot(n: SyntaxNode) -> SyntaxNode { 534fn unroot(n: SyntaxNode) -> SyntaxNode {
535 SyntaxNode::new_root(n.green().to_owned()) 535 SyntaxNode::new_root(n.green())
536} 536}
537 537
538pub mod tokens { 538pub mod tokens {
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 42a7b9c2a..bdf907a21 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -58,10 +58,7 @@ impl From<ast::MacroDef> for Macro {
58 58
59impl AstNode for Macro { 59impl AstNode for Macro {
60 fn can_cast(kind: SyntaxKind) -> bool { 60 fn can_cast(kind: SyntaxKind) -> bool {
61 match kind { 61 matches!(kind, SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF)
62 SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF => true,
63 _ => false,
64 }
65 } 62 }
66 fn cast(syntax: SyntaxNode) -> Option<Self> { 63 fn cast(syntax: SyntaxNode) -> Option<Self> {
67 let res = match syntax.kind() { 64 let res = match syntax.kind() {
@@ -462,10 +459,8 @@ impl ast::FieldExpr {
462 pub fn field_access(&self) -> Option<FieldKind> { 459 pub fn field_access(&self) -> Option<FieldKind> {
463 if let Some(nr) = self.name_ref() { 460 if let Some(nr) = self.name_ref() {
464 Some(FieldKind::Name(nr)) 461 Some(FieldKind::Name(nr))
465 } else if let Some(tok) = self.index_token() {
466 Some(FieldKind::Index(tok))
467 } else { 462 } else {
468 None 463 self.index_token().map(FieldKind::Index)
469 } 464 }
470 } 465 }
471} 466}
@@ -482,16 +477,10 @@ impl ast::SlicePat {
482 let prefix = args 477 let prefix = args
483 .peeking_take_while(|p| match p { 478 .peeking_take_while(|p| match p {
484 ast::Pat::RestPat(_) => false, 479 ast::Pat::RestPat(_) => false,
485 ast::Pat::IdentPat(bp) => match bp.pat() { 480 ast::Pat::IdentPat(bp) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
486 Some(ast::Pat::RestPat(_)) => false,
487 _ => true,
488 },
489 ast::Pat::RefPat(rp) => match rp.pat() { 481 ast::Pat::RefPat(rp) => match rp.pat() {
490 Some(ast::Pat::RestPat(_)) => false, 482 Some(ast::Pat::RestPat(_)) => false,
491 Some(ast::Pat::IdentPat(bp)) => match bp.pat() { 483 Some(ast::Pat::IdentPat(bp)) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
492 Some(ast::Pat::RestPat(_)) => false,
493 _ => true,
494 },
495 _ => true, 484 _ => true,
496 }, 485 },
497 _ => true, 486 _ => true,
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 6c242d126..090282d28 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -494,9 +494,8 @@ pub trait HasFormatSpecifier: AstToken {
494 } 494 }
495 _ => { 495 _ => {
496 while let Some((_, Ok(next_char))) = chars.peek() { 496 while let Some((_, Ok(next_char))) = chars.peek() {
497 match next_char { 497 if next_char == &'{' {
498 '{' => break, 498 break;
499 _ => {}
500 } 499 }
501 chars.next(); 500 chars.next();
502 } 501 }
diff --git a/crates/syntax/src/fuzz.rs b/crates/syntax/src/fuzz.rs
index fbb97aa27..aa84239d2 100644
--- a/crates/syntax/src/fuzz.rs
+++ b/crates/syntax/src/fuzz.rs
@@ -43,7 +43,7 @@ impl CheckReparse {
43 TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap()); 43 TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap());
44 let edited_text = 44 let edited_text =
45 format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]); 45 format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]);
46 let edit = Indel { delete, insert }; 46 let edit = Indel { insert, delete };
47 Some(CheckReparse { text, edit, edited_text }) 47 Some(CheckReparse { text, edit, edited_text })
48 } 48 }
49 49
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs
index 3e216fb70..bbe802174 100644
--- a/crates/syntax/src/validation.rs
+++ b/crates/syntax/src/validation.rs
@@ -297,7 +297,7 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
297 } 297 }
298 }; 298 };
299 } 299 }
300 return None; 300 None
301 } 301 }
302 302
303 fn all_supers(path: &ast::Path) -> bool { 303 fn all_supers(path: &ast::Path) -> bool {
@@ -314,7 +314,7 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
314 return all_supers(subpath); 314 return all_supers(subpath);
315 } 315 }
316 316
317 return true; 317 true
318 } 318 }
319} 319}
320 320
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs
index 9d9a01e30..bed44d600 100644
--- a/crates/tt/src/lib.rs
+++ b/crates/tt/src/lib.rs
@@ -239,9 +239,8 @@ impl Subtree {
239 239
240 let mut res = String::new(); 240 let mut res = String::new();
241 res.push_str(delim.0); 241 res.push_str(delim.0);
242 let mut iter = self.token_trees.iter();
243 let mut last = None; 242 let mut last = None;
244 while let Some(child) = iter.next() { 243 for child in &self.token_trees {
245 let s = match child { 244 let s = match child {
246 TokenTree::Leaf(it) => { 245 TokenTree::Leaf(it) => {
247 let s = match it { 246 let s = match it {