aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/base_db/src/fixture.rs2
-rw-r--r--crates/hir/src/attrs.rs2
-rw-r--r--crates/hir/src/display.rs32
-rw-r--r--crates/hir/src/lib.rs28
-rw-r--r--crates/hir/src/semantics.rs2
-rw-r--r--crates/hir/src/source_analyzer.rs6
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/hir_def/src/body.rs26
-rw-r--r--crates/hir_def/src/body/diagnostics.rs6
-rw-r--r--crates/hir_def/src/body/lower.rs15
-rw-r--r--crates/hir_def/src/body/tests.rs12
-rw-r--r--crates/hir_def/src/data.rs37
-rw-r--r--crates/hir_def/src/diagnostics.rs2
-rw-r--r--crates/hir_def/src/lib.rs27
-rw-r--r--crates/hir_expand/src/eager.rs2
-rw-r--r--crates/hir_expand/src/hygiene.rs7
-rw-r--r--crates/hir_expand/src/lib.rs4
-rw-r--r--crates/hir_ty/src/autoderef.rs4
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs18
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs18
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs2
-rw-r--r--crates/hir_ty/src/display.rs4
-rw-r--r--crates/hir_ty/src/infer.rs8
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs37
-rw-r--r--crates/hir_ty/src/infer/pat.rs12
-rw-r--r--crates/hir_ty/src/infer/path.rs20
-rw-r--r--crates/hir_ty/src/infer/unify.rs16
-rw-r--r--crates/hir_ty/src/lib.rs94
-rw-r--r--crates/hir_ty/src/lower.rs46
-rw-r--r--crates/hir_ty/src/method_resolution.rs14
-rw-r--r--crates/hir_ty/src/traits.rs4
-rw-r--r--crates/hir_ty/src/traits/chalk.rs18
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs17
-rw-r--r--crates/ide/src/diagnostics/fixes.rs2
-rw-r--r--crates/ide/src/doc_links.rs4
-rw-r--r--crates/ide/src/goto_definition.rs2
-rw-r--r--crates/ide/src/hover.rs18
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs2
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs4
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs7
-rw-r--r--crates/ide_assists/src/handlers/move_bounds.rs36
-rw-r--r--crates/ide_completion/src/completions.rs2
-rw-r--r--crates/ide_completion/src/completions/pattern.rs4
-rw-r--r--crates/ide_completion/src/completions/postfix/format_like.rs2
-rw-r--r--crates/ide_completion/src/render.rs2
-rw-r--r--crates/ide_db/src/defs.rs2
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs2
-rw-r--r--crates/ide_db/src/search.rs34
-rw-r--r--crates/ide_ssr/src/lib.rs7
-rw-r--r--crates/ide_ssr/src/matching.rs2
-rw-r--r--crates/mbe/src/benchmark.rs21
-rw-r--r--crates/mbe/src/expander/matcher.rs14
-rw-r--r--crates/mbe/src/parser.rs2
-rw-r--r--crates/mbe/src/syntax_bridge.rs4
-rw-r--r--crates/mbe/src/tests.rs2
-rw-r--r--crates/proc_macro_api/src/process.rs2
-rw-r--r--crates/proc_macro_api/src/rpc.rs11
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs2
-rw-r--r--crates/rust-analyzer/src/handlers.rs2
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs2
-rw-r--r--crates/syntax/src/ast/edit.rs2
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs52
-rw-r--r--crates/syntax/src/ted.rs56
-rw-r--r--xtask/src/metrics.rs8
66 files changed, 480 insertions, 384 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index cad6866aa..8d4641355 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -197,7 +197,7 @@ impl ChangeFixture {
197 197
198 change.change_file(file_id, Some(Arc::new(text))); 198 change.change_file(file_id, Some(Arc::new(text)));
199 let path = VfsPath::new_virtual_path(meta.path); 199 let path = VfsPath::new_virtual_path(meta.path);
200 file_set.insert(file_id, path.into()); 200 file_set.insert(file_id, path);
201 files.push(file_id); 201 files.push(file_id);
202 file_id.0 += 1; 202 file_id.0 += 1;
203 } 203 }
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 505fc05e7..dab8da7bb 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -125,5 +125,5 @@ fn resolve_doc_path(
125 Some(Namespace::Macros) => return None, 125 Some(Namespace::Macros) => return None,
126 None => resolved.iter_items().find_map(|it| it.as_module_def_id())?, 126 None => resolved.iter_items().find_map(|it| it.as_module_def_id())?,
127 }; 127 };
128 Some(def.into()) 128 Some(def)
129} 129}
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 44cdcc296..9f6d7be48 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -12,8 +12,8 @@ use hir_ty::display::{
12use syntax::ast::{self, NameOwner}; 12use syntax::ast::{self, NameOwner};
13 13
14use crate::{ 14use crate::{
15 Const, ConstParam, Enum, Field, Function, HasVisibility, Module, Static, Struct, Substs, Trait, 15 Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam,
16 Type, TypeAlias, TypeParam, Union, Variant, 16 Module, Static, Struct, Substitution, Trait, Type, TypeAlias, TypeParam, Union, Variant,
17}; 17};
18 18
19impl HirDisplay for Function { 19impl HirDisplay for Function {
@@ -120,6 +120,16 @@ impl HirDisplay for Function {
120 } 120 }
121} 121}
122 122
123impl HirDisplay for Adt {
124 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
125 match self {
126 Adt::Struct(it) => it.hir_fmt(f),
127 Adt::Union(it) => it.hir_fmt(f),
128 Adt::Enum(it) => it.hir_fmt(f),
129 }
130 }
131}
132
123impl HirDisplay for Struct { 133impl HirDisplay for Struct {
124 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 134 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
125 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; 135 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
@@ -211,11 +221,21 @@ impl HirDisplay for Type {
211 } 221 }
212} 222}
213 223
224impl HirDisplay for GenericParam {
225 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
226 match self {
227 GenericParam::TypeParam(it) => it.hir_fmt(f),
228 GenericParam::LifetimeParam(it) => it.hir_fmt(f),
229 GenericParam::ConstParam(it) => it.hir_fmt(f),
230 }
231 }
232}
233
214impl HirDisplay for TypeParam { 234impl HirDisplay for TypeParam {
215 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 235 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
216 write!(f, "{}", self.name(f.db))?; 236 write!(f, "{}", self.name(f.db))?;
217 let bounds = f.db.generic_predicates_for_param(self.id); 237 let bounds = f.db.generic_predicates_for_param(self.id);
218 let substs = Substs::type_params(f.db, self.id.parent); 238 let substs = Substitution::type_params(f.db, self.id.parent);
219 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); 239 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
220 if !(predicates.is_empty() || f.omit_verbose_types()) { 240 if !(predicates.is_empty() || f.omit_verbose_types()) {
221 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; 241 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
@@ -224,6 +244,12 @@ impl HirDisplay for TypeParam {
224 } 244 }
225} 245}
226 246
247impl HirDisplay for LifetimeParam {
248 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
249 write!(f, "{}", self.name(f.db))
250 }
251}
252
227impl HirDisplay for ConstParam { 253impl HirDisplay for ConstParam {
228 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 254 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
229 write!(f, "const {}: ", self.name(f.db))?; 255 write!(f, "const {}: ", self.name(f.db))?;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 265a084f3..b41a36a78 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -57,8 +57,8 @@ use hir_ty::{
57 to_assoc_type_id, 57 to_assoc_type_id,
58 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
59 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 59 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
60 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, 60 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution,
61 TyDefId, TyKind, TyVariableKind, 61 Ty, TyDefId, TyKind, TyVariableKind,
62}; 62};
63use itertools::Itertools; 63use itertools::Itertools;
64use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -518,7 +518,7 @@ impl Field {
518 VariantDef::Union(it) => it.id.into(), 518 VariantDef::Union(it) => it.id.into(),
519 VariantDef::Variant(it) => it.parent.id.into(), 519 VariantDef::Variant(it) => it.parent.id.into(),
520 }; 520 };
521 let substs = Substs::type_params(db, generic_def_id); 521 let substs = Substitution::type_params(db, generic_def_id);
522 let ty = db.field_types(var_id)[self.id].clone().subst(&substs); 522 let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
523 Type::new(db, self.parent.module(db).id.krate(), var_id, ty) 523 Type::new(db, self.parent.module(db).id.krate(), var_id, ty)
524 } 524 }
@@ -1335,7 +1335,7 @@ impl Local {
1335 1335
1336 // FIXME: why is this an option? It shouldn't be? 1336 // FIXME: why is this an option? It shouldn't be?
1337 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1337 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1338 let body = db.body(self.parent.into()); 1338 let body = db.body(self.parent);
1339 match &body[self.pat_id] { 1339 match &body[self.pat_id] {
1340 Pat::Bind { name, .. } => Some(name.clone()), 1340 Pat::Bind { name, .. } => Some(name.clone()),
1341 _ => None, 1341 _ => None,
@@ -1347,7 +1347,7 @@ impl Local {
1347 } 1347 }
1348 1348
1349 pub fn is_mut(self, db: &dyn HirDatabase) -> bool { 1349 pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
1350 let body = db.body(self.parent.into()); 1350 let body = db.body(self.parent);
1351 matches!(&body[self.pat_id], Pat::Bind { mode: BindingAnnotation::Mutable, .. }) 1351 matches!(&body[self.pat_id], Pat::Bind { mode: BindingAnnotation::Mutable, .. })
1352 } 1352 }
1353 1353
@@ -1360,7 +1360,7 @@ impl Local {
1360 } 1360 }
1361 1361
1362 pub fn ty(self, db: &dyn HirDatabase) -> Type { 1362 pub fn ty(self, db: &dyn HirDatabase) -> Type {
1363 let def = DefWithBodyId::from(self.parent); 1363 let def = self.parent;
1364 let infer = db.infer(def); 1364 let infer = db.infer(def);
1365 let ty = infer[self.pat_id].clone(); 1365 let ty = infer[self.pat_id].clone();
1366 let krate = def.module(db.upcast()).krate(); 1366 let krate = def.module(db.upcast()).krate();
@@ -1368,7 +1368,7 @@ impl Local {
1368 } 1368 }
1369 1369
1370 pub fn source(self, db: &dyn HirDatabase) -> InFile<Either<ast::IdentPat, ast::SelfParam>> { 1370 pub fn source(self, db: &dyn HirDatabase) -> InFile<Either<ast::IdentPat, ast::SelfParam>> {
1371 let (_body, source_map) = db.body_with_source_map(self.parent.into()); 1371 let (_body, source_map) = db.body_with_source_map(self.parent);
1372 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 1372 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1373 let root = src.file_syntax(db.upcast()); 1373 let root = src.file_syntax(db.upcast());
1374 src.map(|ast| { 1374 src.map(|ast| {
@@ -1393,12 +1393,12 @@ impl Label {
1393 } 1393 }
1394 1394
1395 pub fn name(self, db: &dyn HirDatabase) -> Name { 1395 pub fn name(self, db: &dyn HirDatabase) -> Name {
1396 let body = db.body(self.parent.into()); 1396 let body = db.body(self.parent);
1397 body[self.label_id].name.clone() 1397 body[self.label_id].name.clone()
1398 } 1398 }
1399 1399
1400 pub fn source(self, db: &dyn HirDatabase) -> InFile<ast::Label> { 1400 pub fn source(self, db: &dyn HirDatabase) -> InFile<ast::Label> {
1401 let (_body, source_map) = db.body_with_source_map(self.parent.into()); 1401 let (_body, source_map) = db.body_with_source_map(self.parent);
1402 let src = source_map.label_syntax(self.label_id); 1402 let src = source_map.label_syntax(self.label_id);
1403 let root = src.file_syntax(db.upcast()); 1403 let root = src.file_syntax(db.upcast());
1404 src.map(|ast| ast.to_node(&root)) 1404 src.map(|ast| ast.to_node(&root))
@@ -1471,7 +1471,7 @@ impl TypeParam {
1471 let resolver = self.id.parent.resolver(db.upcast()); 1471 let resolver = self.id.parent.resolver(db.upcast());
1472 let krate = self.id.parent.module(db.upcast()).krate(); 1472 let krate = self.id.parent.module(db.upcast()).krate();
1473 let ty = params.get(local_idx)?.clone(); 1473 let ty = params.get(local_idx)?.clone();
1474 let subst = Substs::type_params(db, self.id.parent); 1474 let subst = Substitution::type_params(db, self.id.parent);
1475 let ty = ty.subst(&subst.prefix(local_idx)); 1475 let ty = ty.subst(&subst.prefix(local_idx));
1476 Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) 1476 Some(Type::new_with_resolver_inner(db, krate, &resolver, ty))
1477 } 1477 }
@@ -1674,7 +1674,7 @@ impl Type {
1674 krate: CrateId, 1674 krate: CrateId,
1675 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, 1675 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>,
1676 ) -> Type { 1676 ) -> Type {
1677 let substs = Substs::build_for_def(db, def).fill_with_unknown().build(); 1677 let substs = Substitution::build_for_def(db, def).fill_with_unknown().build();
1678 let ty = db.ty(def.into()).subst(&substs); 1678 let ty = db.ty(def.into()).subst(&substs);
1679 Type::new(db, krate, def, ty) 1679 Type::new(db, krate, def, ty)
1680 } 1680 }
@@ -1754,7 +1754,7 @@ impl Type {
1754 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { 1754 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1755 let trait_ref = hir_ty::TraitRef { 1755 let trait_ref = hir_ty::TraitRef {
1756 trait_: trait_.id, 1756 trait_: trait_.id,
1757 substs: Substs::build_for_def(db, trait_.id) 1757 substs: Substitution::build_for_def(db, trait_.id)
1758 .push(self.ty.value.clone()) 1758 .push(self.ty.value.clone())
1759 .fill(args.iter().map(|t| t.ty.value.clone())) 1759 .fill(args.iter().map(|t| t.ty.value.clone()))
1760 .build(), 1760 .build(),
@@ -1778,7 +1778,7 @@ impl Type {
1778 args: &[Type], 1778 args: &[Type],
1779 alias: TypeAlias, 1779 alias: TypeAlias,
1780 ) -> Option<Type> { 1780 ) -> Option<Type> {
1781 let subst = Substs::build_for_def(db, trait_.id) 1781 let subst = Substitution::build_for_def(db, trait_.id)
1782 .push(self.ty.value.clone()) 1782 .push(self.ty.value.clone())
1783 .fill(args.iter().map(|t| t.ty.value.clone())) 1783 .fill(args.iter().map(|t| t.ty.value.clone()))
1784 .build(); 1784 .build();
@@ -2045,7 +2045,7 @@ impl Type {
2045 fn walk_substs( 2045 fn walk_substs(
2046 db: &dyn HirDatabase, 2046 db: &dyn HirDatabase,
2047 type_: &Type, 2047 type_: &Type,
2048 substs: &Substs, 2048 substs: &Substitution,
2049 cb: &mut impl FnMut(Type), 2049 cb: &mut impl FnMut(Type),
2050 ) { 2050 ) {
2051 for ty in substs.iter() { 2051 for ty in substs.iter() {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index c7e0d0be3..e0eb2a66d 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -836,7 +836,7 @@ impl<'a> SemanticsScope<'a> {
836 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 836 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
837 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(id.into()), 837 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(id.into()),
838 resolver::ScopeDef::Local(pat_id) => { 838 resolver::ScopeDef::Local(pat_id) => {
839 let parent = resolver.body_owner().unwrap().into(); 839 let parent = resolver.body_owner().unwrap();
840 ScopeDef::Local(Local { parent, pat_id }) 840 ScopeDef::Local(Local { parent, pat_id })
841 } 841 }
842 }; 842 };
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 4d59293e9..37d162b32 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -20,7 +20,7 @@ use hir_def::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 21use hir_ty::{
22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, 22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23 InferenceResult, Substs, 23 InferenceResult, Substitution,
24}; 24};
25use syntax::{ 25use syntax::{
26 ast::{self, AstNode}, 26 ast::{self, AstNode},
@@ -329,7 +329,7 @@ impl SourceAnalyzer {
329 &self, 329 &self,
330 db: &dyn HirDatabase, 330 db: &dyn HirDatabase,
331 krate: CrateId, 331 krate: CrateId,
332 substs: &Substs, 332 substs: &Substitution,
333 variant: VariantId, 333 variant: VariantId,
334 missing_fields: Vec<LocalFieldId>, 334 missing_fields: Vec<LocalFieldId>,
335 ) -> Vec<(Field, Type)> { 335 ) -> Vec<(Field, Type)> {
@@ -484,7 +484,7 @@ fn resolve_hir_path_(
484 resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| { 484 resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| {
485 let res = match val { 485 let res = match val {
486 ValueNs::LocalBinding(pat_id) => { 486 ValueNs::LocalBinding(pat_id) => {
487 let var = Local { parent: body_owner?.into(), pat_id }; 487 let var = Local { parent: body_owner?, pat_id };
488 PathResolution::Local(var) 488 PathResolution::Local(var)
489 } 489 }
490 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), 490 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 7a6a41dc2..7ba53ee5c 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -333,7 +333,7 @@ impl Attrs {
333 if docs.is_empty() { 333 if docs.is_empty() {
334 None 334 None
335 } else { 335 } else {
336 Some(Documentation(docs.into())) 336 Some(Documentation(docs))
337 } 337 }
338 } 338 }
339} 339}
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 8bcc350ce..1080d9c2c 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -32,6 +32,7 @@ use crate::{
32 path::{ModPath, Path}, 32 path::{ModPath, Path},
33 src::HasSource, 33 src::HasSource,
34 AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId, 34 AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId,
35 UnresolvedMacro,
35}; 36};
36 37
37/// A subset of Expander that only deals with cfg attributes. We only need it to 38/// A subset of Expander that only deals with cfg attributes. We only need it to
@@ -101,10 +102,12 @@ impl Expander {
101 &mut self, 102 &mut self,
102 db: &dyn DefDatabase, 103 db: &dyn DefDatabase,
103 macro_call: ast::MacroCall, 104 macro_call: ast::MacroCall,
104 ) -> ExpandResult<Option<(Mark, T)>> { 105 ) -> Result<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> {
105 if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT { 106 if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT {
106 cov_mark::hit!(your_stack_belongs_to_me); 107 cov_mark::hit!(your_stack_belongs_to_me);
107 return ExpandResult::str_err("reached recursion limit during macro expansion".into()); 108 return Ok(ExpandResult::str_err(
109 "reached recursion limit during macro expansion".into(),
110 ));
108 } 111 }
109 112
110 let macro_call = InFile::new(self.current_file_id, &macro_call); 113 let macro_call = InFile::new(self.current_file_id, &macro_call);
@@ -116,14 +119,11 @@ impl Expander {
116 let call_id = 119 let call_id =
117 macro_call.as_call_id_with_errors(db, self.def_map.krate(), resolver, &mut |e| { 120 macro_call.as_call_id_with_errors(db, self.def_map.krate(), resolver, &mut |e| {
118 err.get_or_insert(e); 121 err.get_or_insert(e);
119 }); 122 })?;
120 let call_id = match call_id { 123 let call_id = match call_id {
121 Some(it) => it, 124 Ok(it) => it,
122 None => { 125 Err(_) => {
123 if err.is_none() { 126 return Ok(ExpandResult { value: None, err });
124 log::warn!("no error despite `as_call_id_with_errors` returning `None`");
125 }
126 return ExpandResult { value: None, err };
127 } 127 }
128 }; 128 };
129 129
@@ -141,9 +141,9 @@ impl Expander {
141 log::warn!("no error despite `parse_or_expand` failing"); 141 log::warn!("no error despite `parse_or_expand` failing");
142 } 142 }
143 143
144 return ExpandResult::only_err(err.unwrap_or_else(|| { 144 return Ok(ExpandResult::only_err(err.unwrap_or_else(|| {
145 mbe::ExpandError::Other("failed to parse macro invocation".into()) 145 mbe::ExpandError::Other("failed to parse macro invocation".into())
146 })); 146 })));
147 } 147 }
148 }; 148 };
149 149
@@ -151,7 +151,7 @@ impl Expander {
151 Some(it) => it, 151 Some(it) => it,
152 None => { 152 None => {
153 // This can happen without being an error, so only forward previous errors. 153 // This can happen without being an error, so only forward previous errors.
154 return ExpandResult { value: None, err }; 154 return Ok(ExpandResult { value: None, err });
155 } 155 }
156 }; 156 };
157 157
@@ -167,7 +167,7 @@ impl Expander {
167 self.current_file_id = file_id; 167 self.current_file_id = file_id;
168 self.ast_id_map = db.ast_id_map(file_id); 168 self.ast_id_map = db.ast_id_map(file_id);
169 169
170 ExpandResult { value: Some((mark, node)), err } 170 Ok(ExpandResult { value: Some((mark, node)), err })
171 } 171 }
172 172
173 pub(crate) fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) { 173 pub(crate) fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
diff --git a/crates/hir_def/src/body/diagnostics.rs b/crates/hir_def/src/body/diagnostics.rs
index 1de7d30e2..f6992c9a8 100644
--- a/crates/hir_def/src/body/diagnostics.rs
+++ b/crates/hir_def/src/body/diagnostics.rs
@@ -2,13 +2,14 @@
2 2
3use hir_expand::diagnostics::DiagnosticSink; 3use hir_expand::diagnostics::DiagnosticSink;
4 4
5use crate::diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}; 5use crate::diagnostics::{InactiveCode, MacroError, UnresolvedMacroCall, UnresolvedProcMacro};
6 6
7#[derive(Debug, Eq, PartialEq)] 7#[derive(Debug, Eq, PartialEq)]
8pub(crate) enum BodyDiagnostic { 8pub(crate) enum BodyDiagnostic {
9 InactiveCode(InactiveCode), 9 InactiveCode(InactiveCode),
10 MacroError(MacroError), 10 MacroError(MacroError),
11 UnresolvedProcMacro(UnresolvedProcMacro), 11 UnresolvedProcMacro(UnresolvedProcMacro),
12 UnresolvedMacroCall(UnresolvedMacroCall),
12} 13}
13 14
14impl BodyDiagnostic { 15impl BodyDiagnostic {
@@ -23,6 +24,9 @@ impl BodyDiagnostic {
23 BodyDiagnostic::UnresolvedProcMacro(diag) => { 24 BodyDiagnostic::UnresolvedProcMacro(diag) => {
24 sink.push(diag.clone()); 25 sink.push(diag.clone());
25 } 26 }
27 BodyDiagnostic::UnresolvedMacroCall(diag) => {
28 sink.push(diag.clone());
29 }
26 } 30 }
27 } 31 }
28} 32}
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 7052058f2..60b25db56 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -24,7 +24,7 @@ use crate::{
24 body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, 24 body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
25 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, 25 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
26 db::DefDatabase, 26 db::DefDatabase,
27 diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, 27 diagnostics::{InactiveCode, MacroError, UnresolvedMacroCall, UnresolvedProcMacro},
28 expr::{ 28 expr::{
29 dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Label, 29 dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Label,
30 LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, 30 LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField,
@@ -33,7 +33,7 @@ use crate::{
33 item_scope::BuiltinShadowMode, 33 item_scope::BuiltinShadowMode,
34 path::{GenericArgs, Path}, 34 path::{GenericArgs, Path},
35 type_ref::{Mutability, Rawness, TypeRef}, 35 type_ref::{Mutability, Rawness, TypeRef},
36 AdtId, BlockLoc, ModuleDefId, 36 AdtId, BlockLoc, ModuleDefId, UnresolvedMacro,
37}; 37};
38 38
39use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; 39use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource};
@@ -554,6 +554,17 @@ impl ExprCollector<'_> {
554 let macro_call = self.expander.to_source(AstPtr::new(&e)); 554 let macro_call = self.expander.to_source(AstPtr::new(&e));
555 let res = self.expander.enter_expand(self.db, e); 555 let res = self.expander.enter_expand(self.db, e);
556 556
557 let res = match res {
558 Ok(res) => res,
559 Err(UnresolvedMacro) => {
560 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall(
561 UnresolvedMacroCall { file: outer_file, node: syntax_ptr.cast().unwrap() },
562 ));
563 collector(self, None);
564 return;
565 }
566 };
567
557 match &res.err { 568 match &res.err {
558 Some(ExpandError::UnresolvedProcMacro) => { 569 Some(ExpandError::UnresolvedProcMacro) => {
559 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro( 570 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro(
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs
index 991a32b15..f8e6f70e8 100644
--- a/crates/hir_def/src/body/tests.rs
+++ b/crates/hir_def/src/body/tests.rs
@@ -175,6 +175,18 @@ fn f() {
175} 175}
176 176
177#[test] 177#[test]
178fn unresolved_macro_diag() {
179 check_diagnostics(
180 r#"
181fn f() {
182 m!();
183 //^^^^ unresolved macro call
184}
185 "#,
186 );
187}
188
189#[test]
178fn dollar_crate_in_builtin_macro() { 190fn dollar_crate_in_builtin_macro() {
179 check_diagnostics( 191 check_diagnostics(
180 r#" 192 r#"
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 74a2194e5..1a27f7bf2 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -267,23 +267,26 @@ fn collect_items(
267 let ast_id_map = db.ast_id_map(file_id); 267 let ast_id_map = db.ast_id_map(file_id);
268 let root = db.parse_or_expand(file_id).unwrap(); 268 let root = db.parse_or_expand(file_id).unwrap();
269 let call = ast_id_map.get(call.ast_id).to_node(&root); 269 let call = ast_id_map.get(call.ast_id).to_node(&root);
270 270 let res = expander.enter_expand(db, call);
271 if let Some((mark, mac)) = expander.enter_expand(db, call).value { 271
272 let src: InFile<ast::MacroItems> = expander.to_source(mac); 272 if let Ok(res) = res {
273 let item_tree = db.item_tree(src.file_id); 273 if let Some((mark, mac)) = res.value {
274 let iter = 274 let src: InFile<ast::MacroItems> = expander.to_source(mac);
275 item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); 275 let item_tree = db.item_tree(src.file_id);
276 items.extend(collect_items( 276 let iter =
277 db, 277 item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
278 module, 278 items.extend(collect_items(
279 expander, 279 db,
280 iter, 280 module,
281 src.file_id, 281 expander,
282 container, 282 iter,
283 limit - 1, 283 src.file_id,
284 )); 284 container,
285 285 limit - 1,
286 expander.exit(db, mark); 286 ));
287
288 expander.exit(db, mark);
289 }
287 } 290 }
288 } 291 }
289 } 292 }
diff --git a/crates/hir_def/src/diagnostics.rs b/crates/hir_def/src/diagnostics.rs
index 7188bb299..97abf8653 100644
--- a/crates/hir_def/src/diagnostics.rs
+++ b/crates/hir_def/src/diagnostics.rs
@@ -99,7 +99,7 @@ impl Diagnostic for UnresolvedImport {
99// 99//
100// This diagnostic is triggered if rust-analyzer is unable to resolve the path to a 100// This diagnostic is triggered if rust-analyzer is unable to resolve the path to a
101// macro in a macro invocation. 101// macro in a macro invocation.
102#[derive(Debug)] 102#[derive(Debug, Clone, Eq, PartialEq)]
103pub struct UnresolvedMacroCall { 103pub struct UnresolvedMacroCall {
104 pub file: HirFileId, 104 pub file: HirFileId,
105 pub node: AstPtr<ast::MacroCall>, 105 pub node: AstPtr<ast::MacroCall>,
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index c6655c5fb..6758411a0 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -58,7 +58,7 @@ use std::{
58use base_db::{impl_intern_key, salsa, CrateId}; 58use base_db::{impl_intern_key, salsa, CrateId};
59use hir_expand::{ 59use hir_expand::{
60 ast_id_map::FileAstId, 60 ast_id_map::FileAstId,
61 eager::{expand_eager_macro, ErrorEmitted}, 61 eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
62 hygiene::Hygiene, 62 hygiene::Hygiene,
63 AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 63 AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
64}; 64};
@@ -583,7 +583,7 @@ pub trait AsMacroCall {
583 krate: CrateId, 583 krate: CrateId,
584 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 584 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
585 ) -> Option<MacroCallId> { 585 ) -> Option<MacroCallId> {
586 self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()) 586 self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()).ok()?.ok()
587 } 587 }
588 588
589 fn as_call_id_with_errors( 589 fn as_call_id_with_errors(
@@ -592,7 +592,7 @@ pub trait AsMacroCall {
592 krate: CrateId, 592 krate: CrateId,
593 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 593 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
594 error_sink: &mut dyn FnMut(mbe::ExpandError), 594 error_sink: &mut dyn FnMut(mbe::ExpandError),
595 ) -> Option<MacroCallId>; 595 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro>;
596} 596}
597 597
598impl AsMacroCall for InFile<&ast::MacroCall> { 598impl AsMacroCall for InFile<&ast::MacroCall> {
@@ -601,25 +601,28 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
601 db: &dyn db::DefDatabase, 601 db: &dyn db::DefDatabase,
602 krate: CrateId, 602 krate: CrateId,
603 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 603 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
604 error_sink: &mut dyn FnMut(mbe::ExpandError), 604 mut error_sink: &mut dyn FnMut(mbe::ExpandError),
605 ) -> Option<MacroCallId> { 605 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
606 let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); 606 let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
607 let h = Hygiene::new(db.upcast(), self.file_id); 607 let h = Hygiene::new(db.upcast(), self.file_id);
608 let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h)); 608 let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h));
609 609
610 if path.is_none() { 610 let path = match error_sink
611 error_sink(mbe::ExpandError::Other("malformed macro invocation".into())); 611 .option(path, || mbe::ExpandError::Other("malformed macro invocation".into()))
612 } 612 {
613 Ok(path) => path,
614 Err(error) => {
615 return Ok(Err(error));
616 }
617 };
613 618
614 macro_call_as_call_id( 619 macro_call_as_call_id(
615 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path?), 620 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
616 db, 621 db,
617 krate, 622 krate,
618 resolver, 623 resolver,
619 error_sink, 624 error_sink,
620 ) 625 )
621 .ok()?
622 .ok()
623 } 626 }
624} 627}
625 628
@@ -636,7 +639,7 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
636 } 639 }
637} 640}
638 641
639struct UnresolvedMacro; 642pub struct UnresolvedMacro;
640 643
641fn macro_call_as_call_id( 644fn macro_call_as_call_id(
642 call: &AstIdWithPath<ast::MacroCall>, 645 call: &AstIdWithPath<ast::MacroCall>,
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index ae7b51a08..dc618a9ee 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -35,7 +35,7 @@ pub struct ErrorEmitted {
35 _private: (), 35 _private: (),
36} 36}
37 37
38trait ErrorSink { 38pub trait ErrorSink {
39 fn emit(&mut self, err: mbe::ExpandError); 39 fn emit(&mut self, err: mbe::ExpandError);
40 40
41 fn option<T>( 41 fn option<T>(
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index c8ea81210..87cad326d 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -23,7 +23,7 @@ pub struct Hygiene {
23 23
24impl Hygiene { 24impl Hygiene {
25 pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { 25 pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene {
26 Hygiene { frames: Some(HygieneFrames::new(db, file_id.clone())) } 26 Hygiene { frames: Some(HygieneFrames::new(db, file_id)) }
27 } 27 }
28 28
29 pub fn new_unhygienic() -> Hygiene { 29 pub fn new_unhygienic() -> Hygiene {
@@ -129,10 +129,7 @@ impl HygieneInfo {
129 mbe::Origin::Call => (&self.macro_arg.1, self.arg_start), 129 mbe::Origin::Call => (&self.macro_arg.1, self.arg_start),
130 mbe::Origin::Def => ( 130 mbe::Origin::Def => (
131 &self.macro_def.1, 131 &self.macro_def.1,
132 self.def_start 132 *self.def_start.as_ref().expect("`Origin::Def` used with non-`macro_rules!` macro"),
133 .as_ref()
134 .expect("`Origin::Def` used with non-`macro_rules!` macro")
135 .clone(),
136 ), 133 ),
137 }; 134 };
138 135
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index eee430af1..7532d00b8 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -475,7 +475,7 @@ fn original_range_opt(
475 let single = skip_trivia_token(node.value.first_token()?, Direction::Next)? 475 let single = skip_trivia_token(node.value.first_token()?, Direction::Next)?
476 == skip_trivia_token(node.value.last_token()?, Direction::Prev)?; 476 == skip_trivia_token(node.value.last_token()?, Direction::Prev)?;
477 477
478 Some(node.value.descendants().find_map(|it| { 478 node.value.descendants().find_map(|it| {
479 let first = skip_trivia_token(it.first_token()?, Direction::Next)?; 479 let first = skip_trivia_token(it.first_token()?, Direction::Next)?;
480 let first = ascend_call_token(db, &expansion, node.with_value(first))?; 480 let first = ascend_call_token(db, &expansion, node.with_value(first))?;
481 481
@@ -487,7 +487,7 @@ fn original_range_opt(
487 } 487 }
488 488
489 Some(first.with_value(first.value.text_range().cover(last.value.text_range()))) 489 Some(first.with_value(first.value.text_range().cover(last.value.text_range())))
490 })?) 490 })
491} 491}
492 492
493fn ascend_call_token( 493fn ascend_call_token(
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 56c6b92d4..bd2ff5d38 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -15,7 +15,7 @@ use crate::{
15 to_assoc_type_id, 15 to_assoc_type_id,
16 traits::{InEnvironment, Solution}, 16 traits::{InEnvironment, Solution},
17 utils::generics, 17 utils::generics,
18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind, 18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
19}; 19};
20 20
21const AUTODEREF_RECURSION_LIMIT: usize = 10; 21const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -65,7 +65,7 @@ fn deref_by_trait(
65 // FIXME make the Canonical / bound var handling nicer 65 // FIXME make the Canonical / bound var handling nicer
66 66
67 let parameters = 67 let parameters =
68 Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 68 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
69 69
70 // Check that the type implements Deref at all 70 // Check that the type implements Deref at all
71 let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() }; 71 let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() };
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 982ad5b9e..bfe239793 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -203,7 +203,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
203 let diagnostic = IncorrectCase { 203 let diagnostic = IncorrectCase {
204 file: fn_src.file_id, 204 file: fn_src.file_id,
205 ident_type: IdentType::Function, 205 ident_type: IdentType::Function,
206 ident: AstPtr::new(&ast_ptr).into(), 206 ident: AstPtr::new(&ast_ptr),
207 expected_case: replacement.expected_case, 207 expected_case: replacement.expected_case,
208 ident_text: replacement.current_name.to_string(), 208 ident_text: replacement.current_name.to_string(),
209 suggested_text: replacement.suggested_text, 209 suggested_text: replacement.suggested_text,
@@ -261,7 +261,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
261 let diagnostic = IncorrectCase { 261 let diagnostic = IncorrectCase {
262 file: fn_src.file_id, 262 file: fn_src.file_id,
263 ident_type: IdentType::Argument, 263 ident_type: IdentType::Argument,
264 ident: AstPtr::new(&ast_ptr).into(), 264 ident: AstPtr::new(&ast_ptr),
265 expected_case: param_to_rename.expected_case, 265 expected_case: param_to_rename.expected_case,
266 ident_text: param_to_rename.current_name.to_string(), 266 ident_text: param_to_rename.current_name.to_string(),
267 suggested_text: param_to_rename.suggested_text, 267 suggested_text: param_to_rename.suggested_text,
@@ -313,7 +313,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
313 let diagnostic = IncorrectCase { 313 let diagnostic = IncorrectCase {
314 file: source_ptr.file_id, 314 file: source_ptr.file_id,
315 ident_type: IdentType::Variable, 315 ident_type: IdentType::Variable,
316 ident: AstPtr::new(&name_ast).into(), 316 ident: AstPtr::new(&name_ast),
317 expected_case: replacement.expected_case, 317 expected_case: replacement.expected_case,
318 ident_text: replacement.current_name.to_string(), 318 ident_text: replacement.current_name.to_string(),
319 suggested_text: replacement.suggested_text, 319 suggested_text: replacement.suggested_text,
@@ -403,7 +403,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
403 let diagnostic = IncorrectCase { 403 let diagnostic = IncorrectCase {
404 file: struct_src.file_id, 404 file: struct_src.file_id,
405 ident_type: IdentType::Structure, 405 ident_type: IdentType::Structure,
406 ident: AstPtr::new(&ast_ptr).into(), 406 ident: AstPtr::new(&ast_ptr),
407 expected_case: replacement.expected_case, 407 expected_case: replacement.expected_case,
408 ident_text: replacement.current_name.to_string(), 408 ident_text: replacement.current_name.to_string(),
409 suggested_text: replacement.suggested_text, 409 suggested_text: replacement.suggested_text,
@@ -448,7 +448,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
448 let diagnostic = IncorrectCase { 448 let diagnostic = IncorrectCase {
449 file: struct_src.file_id, 449 file: struct_src.file_id,
450 ident_type: IdentType::Field, 450 ident_type: IdentType::Field,
451 ident: AstPtr::new(&ast_ptr).into(), 451 ident: AstPtr::new(&ast_ptr),
452 expected_case: field_to_rename.expected_case, 452 expected_case: field_to_rename.expected_case,
453 ident_text: field_to_rename.current_name.to_string(), 453 ident_text: field_to_rename.current_name.to_string(),
454 suggested_text: field_to_rename.suggested_text, 454 suggested_text: field_to_rename.suggested_text,
@@ -527,7 +527,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
527 let diagnostic = IncorrectCase { 527 let diagnostic = IncorrectCase {
528 file: enum_src.file_id, 528 file: enum_src.file_id,
529 ident_type: IdentType::Enum, 529 ident_type: IdentType::Enum,
530 ident: AstPtr::new(&ast_ptr).into(), 530 ident: AstPtr::new(&ast_ptr),
531 expected_case: replacement.expected_case, 531 expected_case: replacement.expected_case,
532 ident_text: replacement.current_name.to_string(), 532 ident_text: replacement.current_name.to_string(),
533 suggested_text: replacement.suggested_text, 533 suggested_text: replacement.suggested_text,
@@ -572,7 +572,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
572 let diagnostic = IncorrectCase { 572 let diagnostic = IncorrectCase {
573 file: enum_src.file_id, 573 file: enum_src.file_id,
574 ident_type: IdentType::Variant, 574 ident_type: IdentType::Variant,
575 ident: AstPtr::new(&ast_ptr).into(), 575 ident: AstPtr::new(&ast_ptr),
576 expected_case: variant_to_rename.expected_case, 576 expected_case: variant_to_rename.expected_case,
577 ident_text: variant_to_rename.current_name.to_string(), 577 ident_text: variant_to_rename.current_name.to_string(),
578 suggested_text: variant_to_rename.suggested_text, 578 suggested_text: variant_to_rename.suggested_text,
@@ -617,7 +617,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
617 let diagnostic = IncorrectCase { 617 let diagnostic = IncorrectCase {
618 file: const_src.file_id, 618 file: const_src.file_id,
619 ident_type: IdentType::Constant, 619 ident_type: IdentType::Constant,
620 ident: AstPtr::new(&ast_ptr).into(), 620 ident: AstPtr::new(&ast_ptr),
621 expected_case: replacement.expected_case, 621 expected_case: replacement.expected_case,
622 ident_text: replacement.current_name.to_string(), 622 ident_text: replacement.current_name.to_string(),
623 suggested_text: replacement.suggested_text, 623 suggested_text: replacement.suggested_text,
@@ -665,7 +665,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
665 let diagnostic = IncorrectCase { 665 let diagnostic = IncorrectCase {
666 file: static_src.file_id, 666 file: static_src.file_id,
667 ident_type: IdentType::StaticVariable, 667 ident_type: IdentType::StaticVariable,
668 ident: AstPtr::new(&ast_ptr).into(), 668 ident: AstPtr::new(&ast_ptr),
669 expected_case: replacement.expected_case, 669 expected_case: replacement.expected_case,
670 ident_text: replacement.current_name.to_string(), 670 ident_text: replacement.current_name.to_string(),
671 suggested_text: replacement.suggested_text, 671 suggested_text: replacement.suggested_text,
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index b2bfd68d4..71b2cade0 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -44,7 +44,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
44 pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) { 44 pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
45 self.check_for_filter_map_next(db); 45 self.check_for_filter_map_next(db);
46 46
47 let body = db.body(self.owner.into()); 47 let body = db.body(self.owner);
48 48
49 for (id, expr) in body.exprs.iter() { 49 for (id, expr) in body.exprs.iter() {
50 if let Some((variant_def, missed_fields, true)) = 50 if let Some((variant_def, missed_fields, true)) =
@@ -98,7 +98,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
98 missed_fields: Vec<LocalFieldId>, 98 missed_fields: Vec<LocalFieldId>,
99 ) { 99 ) {
100 // XXX: only look at source_map if we do have missing fields 100 // XXX: only look at source_map if we do have missing fields
101 let (_, source_map) = db.body_with_source_map(self.owner.into()); 101 let (_, source_map) = db.body_with_source_map(self.owner);
102 102
103 if let Ok(source_ptr) = source_map.expr_syntax(id) { 103 if let Ok(source_ptr) = source_map.expr_syntax(id) {
104 let root = source_ptr.file_syntax(db.upcast()); 104 let root = source_ptr.file_syntax(db.upcast());
@@ -128,7 +128,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
128 missed_fields: Vec<LocalFieldId>, 128 missed_fields: Vec<LocalFieldId>,
129 ) { 129 ) {
130 // XXX: only look at source_map if we do have missing fields 130 // XXX: only look at source_map if we do have missing fields
131 let (_, source_map) = db.body_with_source_map(self.owner.into()); 131 let (_, source_map) = db.body_with_source_map(self.owner);
132 132
133 if let Ok(source_ptr) = source_map.pat_syntax(id) { 133 if let Ok(source_ptr) = source_map.pat_syntax(id) {
134 if let Some(expr) = source_ptr.value.as_ref().left() { 134 if let Some(expr) = source_ptr.value.as_ref().left() {
@@ -175,7 +175,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
175 }; 175 };
176 176
177 // Search function body for instances of .filter_map(..).next() 177 // Search function body for instances of .filter_map(..).next()
178 let body = db.body(self.owner.into()); 178 let body = db.body(self.owner);
179 let mut prev = None; 179 let mut prev = None;
180 for (id, expr) in body.exprs.iter() { 180 for (id, expr) in body.exprs.iter() {
181 if let Expr::MethodCall { receiver, .. } = expr { 181 if let Expr::MethodCall { receiver, .. } = expr {
@@ -192,7 +192,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
192 if function_id == *next_function_id { 192 if function_id == *next_function_id {
193 if let Some(filter_map_id) = prev { 193 if let Some(filter_map_id) = prev {
194 if *receiver == filter_map_id { 194 if *receiver == filter_map_id {
195 let (_, source_map) = db.body_with_source_map(self.owner.into()); 195 let (_, source_map) = db.body_with_source_map(self.owner);
196 if let Ok(next_source_ptr) = source_map.expr_syntax(id) { 196 if let Ok(next_source_ptr) = source_map.expr_syntax(id) {
197 self.sink.push(ReplaceFilterMapNextWithFindMap { 197 self.sink.push(ReplaceFilterMapNextWithFindMap {
198 file: next_source_ptr.file_id, 198 file: next_source_ptr.file_id,
@@ -262,7 +262,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
262 let mut arg_count = args.len(); 262 let mut arg_count = args.len();
263 263
264 if arg_count != param_count { 264 if arg_count != param_count {
265 let (_, source_map) = db.body_with_source_map(self.owner.into()); 265 let (_, source_map) = db.body_with_source_map(self.owner);
266 if let Ok(source_ptr) = source_map.expr_syntax(call_id) { 266 if let Ok(source_ptr) = source_map.expr_syntax(call_id) {
267 if is_method_call { 267 if is_method_call {
268 param_count -= 1; 268 param_count -= 1;
@@ -287,7 +287,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
287 infer: Arc<InferenceResult>, 287 infer: Arc<InferenceResult>,
288 ) { 288 ) {
289 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = 289 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
290 db.body_with_source_map(self.owner.into()); 290 db.body_with_source_map(self.owner);
291 291
292 let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() { 292 let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() {
293 return; 293 return;
@@ -393,7 +393,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
393 }; 393 };
394 394
395 if params.len() > 0 && params[0] == mismatch.actual { 395 if params.len() > 0 && params[0] == mismatch.actual {
396 let (_, source_map) = db.body_with_source_map(self.owner.into()); 396 let (_, source_map) = db.body_with_source_map(self.owner);
397 397
398 if let Ok(source_ptr) = source_map.expr_syntax(id) { 398 if let Ok(source_ptr) = source_map.expr_syntax(id) {
399 self.sink.push(MissingOkOrSomeInTailExpr { 399 self.sink.push(MissingOkOrSomeInTailExpr {
@@ -425,7 +425,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
425 return; 425 return;
426 } 426 }
427 427
428 let (_, source_map) = db.body_with_source_map(self.owner.into()); 428 let (_, source_map) = db.body_with_source_map(self.owner);
429 429
430 if let Ok(source_ptr) = source_map.expr_syntax(possible_tail_id) { 430 if let Ok(source_ptr) = source_map.expr_syntax(possible_tail_id) {
431 self.sink 431 self.sink
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 44a7e5506..1f49a4909 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -29,7 +29,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
29 } 29 }
30 30
31 pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) { 31 pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
32 let def = self.owner.into(); 32 let def = self.owner;
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 34 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe,
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index c572bb114..7ce0f864c 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -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, AliasTy, CallableDefId, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
22 CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy, 22 CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
23 ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind, 23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
24}; 24};
25 25
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -562,7 +562,7 @@ impl HirDisplay for Ty {
562 } 562 }
563 TypeParamProvenance::ArgumentImplTrait => { 563 TypeParamProvenance::ArgumentImplTrait => {
564 let bounds = f.db.generic_predicates_for_param(id); 564 let bounds = f.db.generic_predicates_for_param(id);
565 let substs = Substs::type_params_for_generics(f.db, &generics); 565 let substs = Substitution::type_params_for_generics(f.db, &generics);
566 write_bounds_like_dyn_trait_with_prefix( 566 write_bounds_like_dyn_trait_with_prefix(
567 "impl", 567 "impl",
568 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 568 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 9c385b845..2610c9279 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -38,7 +38,7 @@ use syntax::SmolStr;
38 38
39use super::{ 39use super::{
40 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 40 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
@@ -390,7 +390,7 @@ impl<'a> InferenceContext<'a> {
390 _ => panic!("resolve_associated_type called with non-associated type"), 390 _ => panic!("resolve_associated_type called with non-associated type"),
391 }; 391 };
392 let ty = self.table.new_type_var(); 392 let ty = self.table.new_type_var();
393 let substs = Substs::build_for_def(self.db, res_assoc_ty) 393 let substs = Substitution::build_for_def(self.db, res_assoc_ty)
394 .push(inner_ty) 394 .push(inner_ty)
395 .fill(params.iter().cloned()) 395 .fill(params.iter().cloned())
396 .build(); 396 .build();
@@ -469,7 +469,7 @@ impl<'a> InferenceContext<'a> {
469 } 469 }
470 TypeNs::SelfType(impl_id) => { 470 TypeNs::SelfType(impl_id) => {
471 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 471 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
472 let substs = Substs::type_params_for_generics(self.db, &generics); 472 let substs = Substitution::type_params_for_generics(self.db, &generics);
473 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 473 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
474 match unresolved { 474 match unresolved {
475 None => { 475 None => {
@@ -496,7 +496,7 @@ impl<'a> InferenceContext<'a> {
496 } 496 }
497 } 497 }
498 TypeNs::TypeAliasId(it) => { 498 TypeNs::TypeAliasId(it) => {
499 let substs = Substs::build_for_def(self.db, it) 499 let substs = Substitution::build_for_def(self.db, it)
500 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 500 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
501 .build(); 501 .build();
502 let ty = self.db.ty(it.into()).subst(&substs); 502 let ty = self.db.ty(it.into()).subst(&substs);
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 137419264..b1f98c507 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +7,9 @@
7use chalk_ir::{Mutability, TyVariableKind}; 7use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind}; 10use crate::{
11 autoderef, traits::Solution, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
12};
11 13
12use super::{InEnvironment, InferenceContext}; 14use super::{InEnvironment, InferenceContext};
13 15
@@ -134,7 +136,7 @@ impl<'a> InferenceContext<'a> {
134 return None; 136 return None;
135 } 137 }
136 138
137 let substs = Substs::build_for_generics(&generic_params) 139 let substs = Substitution::build_for_generics(&generic_params)
138 .push(from_ty.clone()) 140 .push(from_ty.clone())
139 .push(to_ty.clone()) 141 .push(to_ty.clone())
140 .build(); 142 .build();
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index f40dec17f..0be8c5a90 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -21,8 +21,8 @@ use crate::{
21 to_assoc_type_id, 21 to_assoc_type_id,
22 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 22 traits::{chalk::from_chalk, FnTrait, InEnvironment},
23 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs, 24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
25 TraitRef, Ty, TyKind, 25 Substitution, TraitRef, Ty, TyKind,
26}; 26};
27 27
28use super::{ 28use super::{
@@ -77,7 +77,7 @@ impl<'a> InferenceContext<'a> {
77 return None; 77 return None;
78 } 78 }
79 79
80 let mut param_builder = Substs::builder(num_args); 80 let mut param_builder = Substitution::builder(num_args);
81 let mut arg_tys = vec![]; 81 let mut arg_tys = vec![];
82 for _ in 0..num_args { 82 for _ in 0..num_args {
83 let arg = self.table.new_type_var(); 83 let arg = self.table.new_type_var();
@@ -87,7 +87,7 @@ impl<'a> InferenceContext<'a> {
87 let parameters = param_builder.build(); 87 let parameters = param_builder.build();
88 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 88 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner);
89 let substs = 89 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 91
92 let trait_env = Arc::clone(&self.trait_env); 92 let trait_env = Arc::clone(&self.trait_env);
93 let implements_fn_trait = 93 let implements_fn_trait =
@@ -181,7 +181,7 @@ impl<'a> InferenceContext<'a> {
181 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
183 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 183 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
184 TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner) 184 TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner)
185 } 185 }
186 Expr::Loop { body, label } => { 186 Expr::Loop { body, label } => {
187 self.breakables.push(BreakableContext { 187 self.breakables.push(BreakableContext {
@@ -262,12 +262,12 @@ impl<'a> InferenceContext<'a> {
262 let sig_ty = TyKind::Function(FnPointer { 262 let sig_ty = TyKind::Function(FnPointer {
263 num_args: sig_tys.len() - 1, 263 num_args: sig_tys.len() - 1,
264 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 264 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
265 substs: Substs(sig_tys.clone().into()), 265 substs: Substitution(sig_tys.clone().into()),
266 }) 266 })
267 .intern(&Interner); 267 .intern(&Interner);
268 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 268 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
269 let closure_ty = 269 let closure_ty =
270 TyKind::Closure(closure_id, Substs::single(sig_ty)).intern(&Interner); 270 TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner);
271 271
272 // Eagerly try to relate the closure type with the expected 272 // Eagerly try to relate the closure type with the expected
273 // type, otherwise we often won't have enough information to 273 // type, otherwise we often won't have enough information to
@@ -402,7 +402,7 @@ impl<'a> InferenceContext<'a> {
402 402
403 self.unify(&ty, &expected.ty); 403 self.unify(&ty, &expected.ty);
404 404
405 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); 405 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty);
406 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 406 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
407 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 407 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
408 for field in fields.iter() { 408 for field in fields.iter() {
@@ -511,7 +511,8 @@ impl<'a> InferenceContext<'a> {
511 Expr::Box { expr } => { 511 Expr::Box { expr } => {
512 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 512 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
513 if let Some(box_) = self.resolve_boxed_box() { 513 if let Some(box_) = self.resolve_boxed_box() {
514 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); 514 let mut sb =
515 Substitution::builder(generics(self.db.upcast(), box_.into()).len());
515 sb = sb.push(inner_ty); 516 sb = sb.push(inner_ty);
516 match self.db.generic_defaults(box_.into()).as_ref() { 517 match self.db.generic_defaults(box_.into()).as_ref() {
517 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { 518 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
@@ -610,31 +611,31 @@ impl<'a> InferenceContext<'a> {
610 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 611 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
611 match (range_type, lhs_ty, rhs_ty) { 612 match (range_type, lhs_ty, rhs_ty) {
612 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 613 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
613 Some(adt) => Ty::adt_ty(adt, Substs::empty()), 614 Some(adt) => Ty::adt_ty(adt, Substitution::empty()),
614 None => self.err_ty(), 615 None => self.err_ty(),
615 }, 616 },
616 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 617 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
617 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 618 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)),
618 None => self.err_ty(), 619 None => self.err_ty(),
619 }, 620 },
620 (RangeOp::Inclusive, None, Some(ty)) => { 621 (RangeOp::Inclusive, None, Some(ty)) => {
621 match self.resolve_range_to_inclusive() { 622 match self.resolve_range_to_inclusive() {
622 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 623 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)),
623 None => self.err_ty(), 624 None => self.err_ty(),
624 } 625 }
625 } 626 }
626 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 627 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
627 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 628 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)),
628 None => self.err_ty(), 629 None => self.err_ty(),
629 }, 630 },
630 (RangeOp::Inclusive, Some(_), Some(ty)) => { 631 (RangeOp::Inclusive, Some(_), Some(ty)) => {
631 match self.resolve_range_inclusive() { 632 match self.resolve_range_inclusive() {
632 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 633 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)),
633 None => self.err_ty(), 634 None => self.err_ty(),
634 } 635 }
635 } 636 }
636 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 637 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
637 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 638 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)),
638 None => self.err_ty(), 639 None => self.err_ty(),
639 }, 640 },
640 (RangeOp::Inclusive, _, None) => self.err_ty(), 641 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -681,7 +682,7 @@ impl<'a> InferenceContext<'a> {
681 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 682 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
682 } 683 }
683 684
684 TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner) 685 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner)
685 } 686 }
686 Expr::Array(array) => { 687 Expr::Array(array) => {
687 let elem_ty = match expected.ty.interned(&Interner) { 688 let elem_ty = match expected.ty.interned(&Interner) {
@@ -887,7 +888,7 @@ impl<'a> InferenceContext<'a> {
887 def_generics: Option<Generics>, 888 def_generics: Option<Generics>,
888 generic_args: Option<&GenericArgs>, 889 generic_args: Option<&GenericArgs>,
889 receiver_ty: &Ty, 890 receiver_ty: &Ty,
890 ) -> Substs { 891 ) -> Substitution {
891 let (parent_params, self_params, type_params, impl_trait_params) = 892 let (parent_params, self_params, type_params, impl_trait_params) =
892 def_generics.as_ref().map_or((0, 0, 0, 0), |g| g.provenance_split()); 893 def_generics.as_ref().map_or((0, 0, 0, 0), |g| g.provenance_split());
893 assert_eq!(self_params, 0); // method shouldn't have another Self param 894 assert_eq!(self_params, 0); // method shouldn't have another Self param
@@ -926,7 +927,7 @@ impl<'a> InferenceContext<'a> {
926 substs.push(self.err_ty()); 927 substs.push(self.err_ty());
927 } 928 }
928 assert_eq!(substs.len(), total_len); 929 assert_eq!(substs.len(), total_len);
929 Substs(substs.into()) 930 Substitution(substs.into())
930 } 931 }
931 932
932 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 933 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 9e8ca18ef..befa0d69b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -12,7 +12,9 @@ use hir_def::{
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substs, Ty, TyKind}; 15use crate::{
16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind,
17};
16 18
17impl<'a> InferenceContext<'a> { 19impl<'a> InferenceContext<'a> {
18 fn infer_tuple_struct_pat( 20 fn infer_tuple_struct_pat(
@@ -31,7 +33,7 @@ impl<'a> InferenceContext<'a> {
31 } 33 }
32 self.unify(&ty, expected); 34 self.unify(&ty, expected);
33 35
34 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); 36 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty);
35 37
36 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 38 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
37 let (pre, post) = match ellipsis { 39 let (pre, post) = match ellipsis {
@@ -70,7 +72,7 @@ impl<'a> InferenceContext<'a> {
70 72
71 self.unify(&ty, expected); 73 self.unify(&ty, expected);
72 74
73 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); 75 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty);
74 76
75 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 77 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
76 for subpat in subpats { 78 for subpat in subpats {
@@ -138,7 +140,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 140 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 141 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 142
141 TyKind::Tuple(inner_tys.len(), Substs(inner_tys.into())).intern(&Interner) 143 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner)
142 } 144 }
143 Pat::Or(ref pats) => { 145 Pat::Or(ref pats) => {
144 if let Some((first_pat, rest)) = pats.split_first() { 146 if let Some((first_pat, rest)) = pats.split_first() {
@@ -237,7 +239,7 @@ impl<'a> InferenceContext<'a> {
237 }; 239 };
238 240
239 let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); 241 let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm);
240 Ty::adt_ty(box_adt, Substs::single(inner_ty)) 242 Ty::adt_ty(box_adt, Substitution::single(inner_ty))
241 } 243 }
242 None => self.err_ty(), 244 None => self.err_ty(),
243 }, 245 },
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index af108fb6c..ea01d6238 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -9,7 +9,7 @@ use hir_def::{
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{method_resolution, Interner, Substs, Ty, TyKind, ValueTyDefId}; 12use crate::{method_resolution, Interner, Substitution, Ty, TyKind, ValueTyDefId};
13 13
14use super::{ExprOrPatId, InferenceContext, TraitRef}; 14use super::{ExprOrPatId, InferenceContext, TraitRef};
15 15
@@ -79,7 +79,7 @@ impl<'a> InferenceContext<'a> {
79 } 79 }
80 ValueNs::ImplSelf(impl_id) => { 80 ValueNs::ImplSelf(impl_id) => {
81 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 81 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
82 let substs = Substs::type_params_for_generics(self.db, &generics); 82 let substs = Substitution::type_params_for_generics(self.db, &generics);
83 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 83 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
84 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 84 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
85 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 85 let ty = self.db.value_ty(struct_id.into()).subst(&substs);
@@ -94,10 +94,10 @@ impl<'a> InferenceContext<'a> {
94 94
95 let ty = self.db.value_ty(typable); 95 let ty = self.db.value_ty(typable);
96 // self_subst is just for the parent 96 // self_subst is just for the parent
97 let parent_substs = self_subst.unwrap_or_else(Substs::empty); 97 let parent_substs = self_subst.unwrap_or_else(Substitution::empty);
98 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 98 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
99 let substs = ctx.substs_from_path(path, typable, true); 99 let substs = ctx.substs_from_path(path, typable, true);
100 let full_substs = Substs::builder(substs.len()) 100 let full_substs = Substitution::builder(substs.len())
101 .use_parent_substs(&parent_substs) 101 .use_parent_substs(&parent_substs)
102 .fill(substs.0[parent_substs.len()..].iter().cloned()) 102 .fill(substs.0[parent_substs.len()..].iter().cloned())
103 .build(); 103 .build();
@@ -111,7 +111,7 @@ impl<'a> InferenceContext<'a> {
111 path: &Path, 111 path: &Path,
112 remaining_index: usize, 112 remaining_index: usize,
113 id: ExprOrPatId, 113 id: ExprOrPatId,
114 ) -> Option<(ValueNs, Option<Substs>)> { 114 ) -> Option<(ValueNs, Option<Substitution>)> {
115 assert!(remaining_index < path.segments().len()); 115 assert!(remaining_index < path.segments().len());
116 // there may be more intermediate segments between the resolved one and 116 // there may be more intermediate segments between the resolved one and
117 // the end. Only the last segment needs to be resolved to a value; from 117 // the end. Only the last segment needs to be resolved to a value; from
@@ -164,7 +164,7 @@ impl<'a> InferenceContext<'a> {
164 trait_ref: TraitRef, 164 trait_ref: TraitRef,
165 segment: PathSegment<'_>, 165 segment: PathSegment<'_>,
166 id: ExprOrPatId, 166 id: ExprOrPatId,
167 ) -> Option<(ValueNs, Option<Substs>)> { 167 ) -> Option<(ValueNs, Option<Substitution>)> {
168 let trait_ = trait_ref.trait_; 168 let trait_ = trait_ref.trait_;
169 let item = 169 let item =
170 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| { 170 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
@@ -208,7 +208,7 @@ impl<'a> InferenceContext<'a> {
208 ty: Ty, 208 ty: Ty,
209 name: &Name, 209 name: &Name,
210 id: ExprOrPatId, 210 id: ExprOrPatId,
211 ) -> Option<(ValueNs, Option<Substs>)> { 211 ) -> Option<(ValueNs, Option<Substitution>)> {
212 if let TyKind::Unknown = ty.interned(&Interner) { 212 if let TyKind::Unknown = ty.interned(&Interner) {
213 return None; 213 return None;
214 } 214 }
@@ -241,7 +241,7 @@ impl<'a> InferenceContext<'a> {
241 }; 241 };
242 let substs = match container { 242 let substs = match container {
243 AssocContainerId::ImplId(impl_id) => { 243 AssocContainerId::ImplId(impl_id) => {
244 let impl_substs = Substs::build_for_def(self.db, impl_id) 244 let impl_substs = Substitution::build_for_def(self.db, impl_id)
245 .fill(iter::repeat_with(|| self.table.new_type_var())) 245 .fill(iter::repeat_with(|| self.table.new_type_var()))
246 .build(); 246 .build();
247 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 247 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs);
@@ -250,7 +250,7 @@ impl<'a> InferenceContext<'a> {
250 } 250 }
251 AssocContainerId::TraitId(trait_) => { 251 AssocContainerId::TraitId(trait_) => {
252 // we're picking this method 252 // we're picking this method
253 let trait_substs = Substs::build_for_def(self.db, trait_) 253 let trait_substs = Substitution::build_for_def(self.db, trait_)
254 .push(ty.clone()) 254 .push(ty.clone())
255 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 255 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
256 .build(); 256 .build();
@@ -274,7 +274,7 @@ impl<'a> InferenceContext<'a> {
274 ty: &Ty, 274 ty: &Ty,
275 name: &Name, 275 name: &Name,
276 id: ExprOrPatId, 276 id: ExprOrPatId,
277 ) -> Option<(ValueNs, Option<Substs>)> { 277 ) -> Option<(ValueNs, Option<Substitution>)> {
278 let (enum_id, subst) = match ty.as_adt() { 278 let (enum_id, subst) = match ty.as_adt() {
279 Some((AdtId::EnumId(e), subst)) => (e, subst), 279 Some((AdtId::EnumId(e), subst)) => (e, subst),
280 _ => return None, 280 _ => return None,
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 7795f446f..b2d4f67b3 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -8,7 +8,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
8use super::{InferenceContext, Obligation}; 8use super::{InferenceContext, Obligation};
9use crate::{ 9use crate::{
10 BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar, 10 BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar,
11 Interner, Scalar, Substs, Ty, TyKind, TypeWalk, 11 Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -123,10 +123,10 @@ impl<T> Canonicalized<T> {
123 pub(super) fn apply_solution( 123 pub(super) fn apply_solution(
124 &self, 124 &self,
125 ctx: &mut InferenceContext<'_>, 125 ctx: &mut InferenceContext<'_>,
126 solution: Canonical<Substs>, 126 solution: Canonical<Substitution>,
127 ) { 127 ) {
128 // the solution may contain new variables, which we need to convert to new inference vars 128 // the solution may contain new variables, which we need to convert to new inference vars
129 let new_vars = Substs( 129 let new_vars = Substitution(
130 solution 130 solution
131 .kinds 131 .kinds
132 .iter() 132 .iter()
@@ -147,9 +147,9 @@ impl<T> Canonicalized<T> {
147 } 147 }
148} 148}
149 149
150pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { 150pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
151 let mut table = InferenceTable::new(); 151 let mut table = InferenceTable::new();
152 let vars = Substs( 152 let vars = Substitution(
153 tys.kinds 153 tys.kinds
154 .iter() 154 .iter()
155 // we always use type vars here because we want everything to 155 // we always use type vars here because we want everything to
@@ -173,7 +173,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
173 } 173 }
174 } 174 }
175 Some( 175 Some(
176 Substs::builder(tys.kinds.len()) 176 Substitution::builder(tys.kinds.len())
177 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 177 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))
178 .build(), 178 .build(),
179 ) 179 )
@@ -264,8 +264,8 @@ impl InferenceTable {
264 264
265 pub(crate) fn unify_substs( 265 pub(crate) fn unify_substs(
266 &mut self, 266 &mut self,
267 substs1: &Substs, 267 substs1: &Substitution,
268 substs2: &Substs, 268 substs2: &Substitution,
269 depth: usize, 269 depth: usize,
270 ) -> bool { 270 ) -> bool {
271 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 271 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth))
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 850385280..52b498ff7 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -67,7 +67,7 @@ pub enum Lifetime {
67#[derive(Clone, PartialEq, Eq, Debug, Hash)] 67#[derive(Clone, PartialEq, Eq, Debug, Hash)]
68pub struct OpaqueTy { 68pub struct OpaqueTy {
69 pub opaque_ty_id: OpaqueTyId, 69 pub opaque_ty_id: OpaqueTyId,
70 pub substitution: Substs, 70 pub substitution: Substitution,
71} 71}
72 72
73/// A "projection" type corresponds to an (unnormalized) 73/// A "projection" type corresponds to an (unnormalized)
@@ -76,7 +76,7 @@ pub struct OpaqueTy {
76#[derive(Clone, PartialEq, Eq, Debug, Hash)] 76#[derive(Clone, PartialEq, Eq, Debug, Hash)]
77pub struct ProjectionTy { 77pub struct ProjectionTy {
78 pub associated_ty_id: AssocTypeId, 78 pub associated_ty_id: AssocTypeId,
79 pub substitution: Substs, 79 pub substitution: Substitution,
80} 80}
81 81
82impl ProjectionTy { 82impl ProjectionTy {
@@ -112,7 +112,7 @@ pub type FnSig = chalk_ir::FnSig<Interner>;
112pub struct FnPointer { 112pub struct FnPointer {
113 pub num_args: usize, 113 pub num_args: usize,
114 pub sig: FnSig, 114 pub sig: FnSig,
115 pub substs: Substs, 115 pub substs: Substitution,
116} 116}
117 117
118#[derive(Clone, PartialEq, Eq, Debug, Hash)] 118#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -137,19 +137,19 @@ pub enum AliasTy {
137#[derive(Clone, PartialEq, Eq, Debug, Hash)] 137#[derive(Clone, PartialEq, Eq, Debug, Hash)]
138pub enum TyKind { 138pub enum TyKind {
139 /// Structures, enumerations and unions. 139 /// Structures, enumerations and unions.
140 Adt(AdtId<Interner>, Substs), 140 Adt(AdtId<Interner>, Substitution),
141 141
142 /// Represents an associated item like `Iterator::Item`. This is used 142 /// Represents an associated item like `Iterator::Item`. This is used
143 /// when we have tried to normalize a projection like `T::Item` but 143 /// when we have tried to normalize a projection like `T::Item` but
144 /// couldn't find a better representation. In that case, we generate 144 /// couldn't find a better representation. In that case, we generate
145 /// an **application type** like `(Iterator::Item)<T>`. 145 /// an **application type** like `(Iterator::Item)<T>`.
146 AssociatedType(AssocTypeId, Substs), 146 AssociatedType(AssocTypeId, Substitution),
147 147
148 /// a scalar type like `bool` or `u32` 148 /// a scalar type like `bool` or `u32`
149 Scalar(Scalar), 149 Scalar(Scalar),
150 150
151 /// A tuple type. For example, `(i32, bool)`. 151 /// A tuple type. For example, `(i32, bool)`.
152 Tuple(usize, Substs), 152 Tuple(usize, Substitution),
153 153
154 /// An array with the given length. Written as `[T; n]`. 154 /// An array with the given length. Written as `[T; n]`.
155 Array(Ty), 155 Array(Ty),
@@ -169,7 +169,7 @@ pub enum TyKind {
169 /// analogous to the `AssociatedType` type constructor. 169 /// analogous to the `AssociatedType` type constructor.
170 /// It is also used as the type of async block, with one type parameter 170 /// It is also used as the type of async block, with one type parameter
171 /// representing the Future::Output type. 171 /// representing the Future::Output type.
172 OpaqueType(OpaqueTyId, Substs), 172 OpaqueType(OpaqueTyId, Substitution),
173 173
174 /// The anonymous type of a function declaration/definition. Each 174 /// The anonymous type of a function declaration/definition. Each
175 /// function has a unique type, which is output (for a function 175 /// function has a unique type, which is output (for a function
@@ -183,7 +183,7 @@ pub enum TyKind {
183 /// fn foo() -> i32 { 1 } 183 /// fn foo() -> i32 { 1 }
184 /// let bar = foo; // bar: fn() -> i32 {foo} 184 /// let bar = foo; // bar: fn() -> i32 {foo}
185 /// ``` 185 /// ```
186 FnDef(FnDefId, Substs), 186 FnDef(FnDefId, Substitution),
187 187
188 /// The pointee of a string slice. Written as `str`. 188 /// The pointee of a string slice. Written as `str`.
189 Str, 189 Str,
@@ -195,7 +195,7 @@ pub enum TyKind {
195 /// 195 ///
196 /// The closure signature is stored in a `FnPtr` type in the first type 196 /// The closure signature is stored in a `FnPtr` type in the first type
197 /// parameter. 197 /// parameter.
198 Closure(ClosureId, Substs), 198 Closure(ClosureId, Substitution),
199 199
200 /// Represents a foreign type declared in external blocks. 200 /// Represents a foreign type declared in external blocks.
201 ForeignType(ForeignDefId), 201 ForeignType(ForeignDefId),
@@ -273,9 +273,9 @@ impl Ty {
273 273
274/// A list of substitutions for generic parameters. 274/// A list of substitutions for generic parameters.
275#[derive(Clone, PartialEq, Eq, Debug, Hash)] 275#[derive(Clone, PartialEq, Eq, Debug, Hash)]
276pub struct Substs(SmallVec<[Ty; 2]>); 276pub struct Substitution(SmallVec<[Ty; 2]>);
277 277
278impl TypeWalk for Substs { 278impl TypeWalk for Substitution {
279 fn walk(&self, f: &mut impl FnMut(&Ty)) { 279 fn walk(&self, f: &mut impl FnMut(&Ty)) {
280 for t in self.0.iter() { 280 for t in self.0.iter() {
281 t.walk(f); 281 t.walk(f);
@@ -293,29 +293,29 @@ impl TypeWalk for Substs {
293 } 293 }
294} 294}
295 295
296impl Substs { 296impl Substitution {
297 pub fn interned(&self, _: &Interner) -> &[Ty] { 297 pub fn interned(&self, _: &Interner) -> &[Ty] {
298 &self.0 298 &self.0
299 } 299 }
300 300
301 pub fn empty() -> Substs { 301 pub fn empty() -> Substitution {
302 Substs(SmallVec::new()) 302 Substitution(SmallVec::new())
303 } 303 }
304 304
305 pub fn single(ty: Ty) -> Substs { 305 pub fn single(ty: Ty) -> Substitution {
306 Substs({ 306 Substitution({
307 let mut v = SmallVec::new(); 307 let mut v = SmallVec::new();
308 v.push(ty); 308 v.push(ty);
309 v 309 v
310 }) 310 })
311 } 311 }
312 312
313 pub fn prefix(&self, n: usize) -> Substs { 313 pub fn prefix(&self, n: usize) -> Substitution {
314 Substs(self.0[..std::cmp::min(self.0.len(), n)].into()) 314 Substitution(self.0[..std::cmp::min(self.0.len(), n)].into())
315 } 315 }
316 316
317 pub fn suffix(&self, n: usize) -> Substs { 317 pub fn suffix(&self, n: usize) -> Substitution {
318 Substs(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into()) 318 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
319 } 319 }
320 320
321 pub fn as_single(&self) -> &Ty { 321 pub fn as_single(&self) -> &Ty {
@@ -326,15 +326,15 @@ impl Substs {
326 } 326 }
327 327
328 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self { 328 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
329 Substs(elements.into_iter().collect()) 329 Substitution(elements.into_iter().collect())
330 } 330 }
331 331
332 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 332 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
333 pub(crate) fn type_params_for_generics( 333 pub(crate) fn type_params_for_generics(
334 db: &dyn HirDatabase, 334 db: &dyn HirDatabase,
335 generic_params: &Generics, 335 generic_params: &Generics,
336 ) -> Substs { 336 ) -> Substitution {
337 Substs( 337 Substitution(
338 generic_params 338 generic_params
339 .iter() 339 .iter()
340 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)) 340 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner))
@@ -343,14 +343,14 @@ impl Substs {
343 } 343 }
344 344
345 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 345 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
346 pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { 346 pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
347 let params = generics(db.upcast(), def.into()); 347 let params = generics(db.upcast(), def.into());
348 Substs::type_params_for_generics(db, &params) 348 Substitution::type_params_for_generics(db, &params)
349 } 349 }
350 350
351 /// Return Substs that replace each parameter by a bound variable. 351 /// Return Substs that replace each parameter by a bound variable.
352 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substs { 352 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution {
353 Substs( 353 Substitution(
354 generic_params 354 generic_params
355 .iter() 355 .iter()
356 .enumerate() 356 .enumerate()
@@ -363,11 +363,11 @@ impl Substs {
363 let def = def.into(); 363 let def = def.into();
364 let params = generics(db.upcast(), def); 364 let params = generics(db.upcast(), def);
365 let param_count = params.len(); 365 let param_count = params.len();
366 Substs::builder(param_count) 366 Substitution::builder(param_count)
367 } 367 }
368 368
369 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder { 369 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder {
370 Substs::builder(generic_params.len()) 370 Substitution::builder(generic_params.len())
371 } 371 }
372 372
373 fn builder(param_count: usize) -> SubstsBuilder { 373 fn builder(param_count: usize) -> SubstsBuilder {
@@ -387,9 +387,9 @@ pub struct SubstsBuilder {
387} 387}
388 388
389impl SubstsBuilder { 389impl SubstsBuilder {
390 pub fn build(self) -> Substs { 390 pub fn build(self) -> Substitution {
391 assert_eq!(self.vec.len(), self.param_count); 391 assert_eq!(self.vec.len(), self.param_count);
392 Substs(self.vec.into()) 392 Substitution(self.vec.into())
393 } 393 }
394 394
395 pub fn push(mut self, ty: Ty) -> Self { 395 pub fn push(mut self, ty: Ty) -> Self {
@@ -418,7 +418,7 @@ impl SubstsBuilder {
418 self 418 self
419 } 419 }
420 420
421 pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self { 421 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
422 assert!(self.vec.is_empty()); 422 assert!(self.vec.is_empty());
423 assert!(parent_substs.len() <= self.param_count); 423 assert!(parent_substs.len() <= self.param_count);
424 self.vec.extend(parent_substs.iter().cloned()); 424 self.vec.extend(parent_substs.iter().cloned());
@@ -426,7 +426,7 @@ impl SubstsBuilder {
426 } 426 }
427} 427}
428 428
429impl Deref for Substs { 429impl Deref for Substitution {
430 type Target = [Ty]; 430 type Target = [Ty];
431 431
432 fn deref(&self) -> &[Ty] { 432 fn deref(&self) -> &[Ty] {
@@ -466,13 +466,13 @@ impl<T: Clone> Binders<&T> {
466 466
467impl<T: TypeWalk> Binders<T> { 467impl<T: TypeWalk> Binders<T> {
468 /// Substitutes all variables. 468 /// Substitutes all variables.
469 pub fn subst(self, subst: &Substs) -> T { 469 pub fn subst(self, subst: &Substitution) -> T {
470 assert_eq!(subst.len(), self.num_binders); 470 assert_eq!(subst.len(), self.num_binders);
471 self.value.subst_bound_vars(subst) 471 self.value.subst_bound_vars(subst)
472 } 472 }
473 473
474 /// Substitutes just a prefix of the variables (shifting the rest). 474 /// Substitutes just a prefix of the variables (shifting the rest).
475 pub fn subst_prefix(self, subst: &Substs) -> Binders<T> { 475 pub fn subst_prefix(self, subst: &Substitution) -> Binders<T> {
476 assert!(subst.len() < self.num_binders); 476 assert!(subst.len() < self.num_binders);
477 Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst)) 477 Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
478 } 478 }
@@ -498,7 +498,7 @@ impl<T: TypeWalk> TypeWalk for Binders<T> {
498pub struct TraitRef { 498pub struct TraitRef {
499 /// FIXME name? 499 /// FIXME name?
500 pub trait_: TraitId, 500 pub trait_: TraitId,
501 pub substs: Substs, 501 pub substs: Substitution,
502} 502}
503 503
504impl TraitRef { 504impl TraitRef {
@@ -618,7 +618,7 @@ impl CallableSig {
618 } 618 }
619 } 619 }
620 620
621 pub fn from_substs(substs: &Substs) -> CallableSig { 621 pub fn from_substs(substs: &Substitution) -> CallableSig {
622 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false } 622 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false }
623 } 623 }
624 624
@@ -651,10 +651,10 @@ impl TypeWalk for CallableSig {
651 651
652impl Ty { 652impl Ty {
653 pub fn unit() -> Self { 653 pub fn unit() -> Self {
654 TyKind::Tuple(0, Substs::empty()).intern(&Interner) 654 TyKind::Tuple(0, Substitution::empty()).intern(&Interner)
655 } 655 }
656 656
657 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { 657 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
658 TyKind::Adt(AdtId(adt), substs).intern(&Interner) 658 TyKind::Adt(AdtId(adt), substs).intern(&Interner)
659 } 659 }
660 660
@@ -662,7 +662,7 @@ impl Ty {
662 TyKind::Function(FnPointer { 662 TyKind::Function(FnPointer {
663 num_args: sig.params().len(), 663 num_args: sig.params().len(),
664 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, 664 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
665 substs: Substs::from_iter(&Interner, sig.params_and_return.iter().cloned()), 665 substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()),
666 }) 666 })
667 .intern(&Interner) 667 .intern(&Interner)
668 } 668 }
@@ -709,14 +709,14 @@ impl Ty {
709 t 709 t
710 } 710 }
711 711
712 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { 712 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
713 match self.interned(&Interner) { 713 match self.interned(&Interner) {
714 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), 714 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
715 _ => None, 715 _ => None,
716 } 716 }
717 } 717 }
718 718
719 pub fn as_tuple(&self) -> Option<&Substs> { 719 pub fn as_tuple(&self) -> Option<&Substitution> {
720 match self.interned(&Interner) { 720 match self.interned(&Interner) {
721 TyKind::Tuple(_, substs) => Some(substs), 721 TyKind::Tuple(_, substs) => Some(substs),
722 _ => None, 722 _ => None,
@@ -828,7 +828,7 @@ impl Ty {
828 828
829 /// Returns the type parameters of this type if it has some (i.e. is an ADT 829 /// Returns the type parameters of this type if it has some (i.e. is an ADT
830 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 830 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
831 pub fn substs(&self) -> Option<&Substs> { 831 pub fn substs(&self) -> Option<&Substitution> {
832 match self.interned(&Interner) { 832 match self.interned(&Interner) {
833 TyKind::Adt(_, substs) 833 TyKind::Adt(_, substs)
834 | TyKind::FnDef(_, substs) 834 | TyKind::FnDef(_, substs)
@@ -841,7 +841,7 @@ impl Ty {
841 } 841 }
842 } 842 }
843 843
844 fn substs_mut(&mut self) -> Option<&mut Substs> { 844 fn substs_mut(&mut self) -> Option<&mut Substitution> {
845 match self.interned_mut() { 845 match self.interned_mut() {
846 TyKind::Adt(_, substs) 846 TyKind::Adt(_, substs)
847 | TyKind::FnDef(_, substs) 847 | TyKind::FnDef(_, substs)
@@ -869,7 +869,7 @@ impl Ty {
869 // So just provide the Future trait. 869 // So just provide the Future trait.
870 let impl_bound = GenericPredicate::Implemented(TraitRef { 870 let impl_bound = GenericPredicate::Implemented(TraitRef {
871 trait_: future_trait, 871 trait_: future_trait,
872 substs: Substs::empty(), 872 substs: Substitution::empty(),
873 }); 873 });
874 Some(vec![impl_bound]) 874 Some(vec![impl_bound])
875 } else { 875 } else {
@@ -992,7 +992,7 @@ pub trait TypeWalk {
992 } 992 }
993 993
994 /// Substitutes `TyKind::Bound` vars with the given substitution. 994 /// Substitutes `TyKind::Bound` vars with the given substitution.
995 fn subst_bound_vars(self, substs: &Substs) -> Self 995 fn subst_bound_vars(self, substs: &Substitution) -> Self
996 where 996 where
997 Self: Sized, 997 Self: Sized,
998 { 998 {
@@ -1000,7 +1000,7 @@ pub trait TypeWalk {
1000 } 1000 }
1001 1001
1002 /// Substitutes `TyKind::Bound` vars with the given substitution. 1002 /// Substitutes `TyKind::Bound` vars with the given substitution.
1003 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self 1003 fn subst_bound_vars_at_depth(mut self, substs: &Substitution, depth: DebruijnIndex) -> Self
1004 where 1004 where
1005 Self: Sized, 1005 Self: Sized,
1006 { 1006 {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 6ab757bfc..462882b2b 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -35,7 +35,7 @@ use crate::{
35 }, 35 },
36 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, 36 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
38 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 38 ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
39}; 39};
40 40
41#[derive(Debug)] 41#[derive(Debug)]
@@ -151,7 +151,7 @@ impl<'a> TyLoweringContext<'a> {
151 TypeRef::Never => TyKind::Never.intern(&Interner), 151 TypeRef::Never => TyKind::Never.intern(&Interner),
152 TypeRef::Tuple(inner) => { 152 TypeRef::Tuple(inner) => {
153 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr)); 153 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
154 TyKind::Tuple(inner_tys.len(), Substs::from_iter(&Interner, inner_tys)) 154 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
155 .intern(&Interner) 155 .intern(&Interner)
156 } 156 }
157 TypeRef::Path(path) => { 157 TypeRef::Path(path) => {
@@ -177,7 +177,7 @@ impl<'a> TyLoweringContext<'a> {
177 } 177 }
178 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), 178 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
179 TypeRef::Fn(params, is_varargs) => { 179 TypeRef::Fn(params, is_varargs) => {
180 let substs = Substs(params.iter().map(|tr| self.lower_ty(tr)).collect()); 180 let substs = Substitution(params.iter().map(|tr| self.lower_ty(tr)).collect());
181 TyKind::Function(FnPointer { 181 TyKind::Function(FnPointer {
182 num_args: substs.len() - 1, 182 num_args: substs.len() - 1,
183 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 183 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
@@ -228,7 +228,7 @@ impl<'a> TyLoweringContext<'a> {
228 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx); 228 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
229 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 229 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
230 let generics = generics(self.db.upcast(), func.into()); 230 let generics = generics(self.db.upcast(), func.into());
231 let parameters = Substs::bound_vars(&generics, self.in_binders); 231 let parameters = Substitution::bound_vars(&generics, self.in_binders);
232 TyKind::Alias(AliasTy::Opaque(OpaqueTy { 232 TyKind::Alias(AliasTy::Opaque(OpaqueTy {
233 opaque_ty_id, 233 opaque_ty_id,
234 substitution: parameters, 234 substitution: parameters,
@@ -398,10 +398,10 @@ impl<'a> TyLoweringContext<'a> {
398 let generics = generics(self.db.upcast(), impl_id.into()); 398 let generics = generics(self.db.upcast(), impl_id.into());
399 let substs = match self.type_param_mode { 399 let substs = match self.type_param_mode {
400 TypeParamLoweringMode::Placeholder => { 400 TypeParamLoweringMode::Placeholder => {
401 Substs::type_params_for_generics(self.db, &generics) 401 Substitution::type_params_for_generics(self.db, &generics)
402 } 402 }
403 TypeParamLoweringMode::Variable => { 403 TypeParamLoweringMode::Variable => {
404 Substs::bound_vars(&generics, self.in_binders) 404 Substitution::bound_vars(&generics, self.in_binders)
405 } 405 }
406 }; 406 };
407 self.db.impl_self_ty(impl_id).subst(&substs) 407 self.db.impl_self_ty(impl_id).subst(&substs)
@@ -410,10 +410,10 @@ impl<'a> TyLoweringContext<'a> {
410 let generics = generics(self.db.upcast(), adt.into()); 410 let generics = generics(self.db.upcast(), adt.into());
411 let substs = match self.type_param_mode { 411 let substs = match self.type_param_mode {
412 TypeParamLoweringMode::Placeholder => { 412 TypeParamLoweringMode::Placeholder => {
413 Substs::type_params_for_generics(self.db, &generics) 413 Substitution::type_params_for_generics(self.db, &generics)
414 } 414 }
415 TypeParamLoweringMode::Variable => { 415 TypeParamLoweringMode::Variable => {
416 Substs::bound_vars(&generics, self.in_binders) 416 Substitution::bound_vars(&generics, self.in_binders)
417 } 417 }
418 }; 418 };
419 self.db.ty(adt.into()).subst(&substs) 419 self.db.ty(adt.into()).subst(&substs)
@@ -464,7 +464,7 @@ impl<'a> TyLoweringContext<'a> {
464 TypeParamLoweringMode::Placeholder => { 464 TypeParamLoweringMode::Placeholder => {
465 // if we're lowering to placeholders, we have to put 465 // if we're lowering to placeholders, we have to put
466 // them in now 466 // them in now
467 let s = Substs::type_params( 467 let s = Substitution::type_params(
468 self.db, 468 self.db,
469 self.resolver.generic_def().expect( 469 self.resolver.generic_def().expect(
470 "there should be generics if there's a generic param", 470 "there should be generics if there's a generic param",
@@ -522,7 +522,7 @@ impl<'a> TyLoweringContext<'a> {
522 // special-case enum variants 522 // special-case enum variants
523 resolved: ValueTyDefId, 523 resolved: ValueTyDefId,
524 infer_args: bool, 524 infer_args: bool,
525 ) -> Substs { 525 ) -> Substitution {
526 let last = path.segments().last().expect("path should have at least one segment"); 526 let last = path.segments().last().expect("path should have at least one segment");
527 let (segment, generic_def) = match resolved { 527 let (segment, generic_def) = match resolved {
528 ValueTyDefId::FunctionId(it) => (last, Some(it.into())), 528 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
@@ -553,7 +553,7 @@ impl<'a> TyLoweringContext<'a> {
553 segment: PathSegment<'_>, 553 segment: PathSegment<'_>,
554 def_generic: Option<GenericDefId>, 554 def_generic: Option<GenericDefId>,
555 infer_args: bool, 555 infer_args: bool,
556 ) -> Substs { 556 ) -> Substitution {
557 let mut substs = Vec::new(); 557 let mut substs = Vec::new();
558 let def_generics = def_generic.map(|def| generics(self.db.upcast(), def)); 558 let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
559 559
@@ -601,7 +601,7 @@ impl<'a> TyLoweringContext<'a> {
601 601
602 for default_ty in defaults.iter().skip(substs.len()) { 602 for default_ty in defaults.iter().skip(substs.len()) {
603 // each default can depend on the previous parameters 603 // each default can depend on the previous parameters
604 let substs_so_far = Substs(substs.clone().into()); 604 let substs_so_far = Substitution(substs.clone().into());
605 substs.push(default_ty.clone().subst(&substs_so_far)); 605 substs.push(default_ty.clone().subst(&substs_so_far));
606 } 606 }
607 } 607 }
@@ -614,7 +614,7 @@ impl<'a> TyLoweringContext<'a> {
614 } 614 }
615 assert_eq!(substs.len(), total_len); 615 assert_eq!(substs.len(), total_len);
616 616
617 Substs(substs.into()) 617 Substitution(substs.into())
618 } 618 }
619 619
620 fn lower_trait_ref_from_path( 620 fn lower_trait_ref_from_path(
@@ -656,7 +656,11 @@ impl<'a> TyLoweringContext<'a> {
656 self.lower_trait_ref_from_path(path, explicit_self_ty) 656 self.lower_trait_ref_from_path(path, explicit_self_ty)
657 } 657 }
658 658
659 fn trait_ref_substs_from_path(&self, segment: PathSegment<'_>, resolved: TraitId) -> Substs { 659 fn trait_ref_substs_from_path(
660 &self,
661 segment: PathSegment<'_>,
662 resolved: TraitId,
663 ) -> Substitution {
660 self.substs_from_path_segment(segment, Some(resolved.into()), false) 664 self.substs_from_path_segment(segment, Some(resolved.into()), false)
661 } 665 }
662 666
@@ -817,7 +821,7 @@ pub fn associated_type_shorthand_candidates<R>(
817 { 821 {
818 let trait_ref = TraitRef { 822 let trait_ref = TraitRef {
819 trait_: trait_id, 823 trait_: trait_id,
820 substs: Substs::bound_vars(&generics, DebruijnIndex::INNERMOST), 824 substs: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
821 }; 825 };
822 traits_.push(trait_ref); 826 traits_.push(trait_ref);
823 } 827 }
@@ -945,7 +949,7 @@ pub(crate) fn trait_environment_query(
945 // function default implementations (and hypothetical code 949 // function default implementations (and hypothetical code
946 // inside consts or type aliases) 950 // inside consts or type aliases)
947 cov_mark::hit!(trait_self_implements_self); 951 cov_mark::hit!(trait_self_implements_self);
948 let substs = Substs::type_params(db, trait_id); 952 let substs = Substitution::type_params(db, trait_id);
949 let trait_ref = TraitRef { trait_: trait_id, substs }; 953 let trait_ref = TraitRef { trait_: trait_id, substs };
950 let pred = GenericPredicate::Implemented(trait_ref); 954 let pred = GenericPredicate::Implemented(trait_ref);
951 let program_clause: chalk_ir::ProgramClause<Interner> = 955 let program_clause: chalk_ir::ProgramClause<Interner> =
@@ -1033,7 +1037,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1033/// function body. 1037/// function body.
1034fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1038fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1035 let generics = generics(db.upcast(), def.into()); 1039 let generics = generics(db.upcast(), def.into());
1036 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1040 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1037 Binders::new( 1041 Binders::new(
1038 substs.len(), 1042 substs.len(),
1039 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), 1043 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
@@ -1078,7 +1082,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1078 return type_for_adt(db, def.into()); 1082 return type_for_adt(db, def.into());
1079 } 1083 }
1080 let generics = generics(db.upcast(), def.into()); 1084 let generics = generics(db.upcast(), def.into());
1081 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1085 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1082 Binders::new( 1086 Binders::new(
1083 substs.len(), 1087 substs.len(),
1084 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), 1088 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
@@ -1105,7 +1109,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1105 return type_for_adt(db, def.parent.into()); 1109 return type_for_adt(db, def.parent.into());
1106 } 1110 }
1107 let generics = generics(db.upcast(), def.parent.into()); 1111 let generics = generics(db.upcast(), def.parent.into());
1108 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1112 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1109 Binders::new( 1113 Binders::new(
1110 substs.len(), 1114 substs.len(),
1111 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), 1115 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
@@ -1114,7 +1118,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1114 1118
1115fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1119fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1116 let generics = generics(db.upcast(), adt.into()); 1120 let generics = generics(db.upcast(), adt.into());
1117 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1121 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1118 Binders::new(substs.len(), Ty::adt_ty(adt, substs)) 1122 Binders::new(substs.len(), Ty::adt_ty(adt, substs))
1119} 1123}
1120 1124
@@ -1126,7 +1130,7 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1126 if db.type_alias_data(t).is_extern { 1130 if db.type_alias_data(t).is_extern {
1127 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) 1131 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
1128 } else { 1132 } else {
1129 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1133 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1130 let type_ref = &db.type_alias_data(t).type_ref; 1134 let type_ref = &db.type_alias_data(t).type_ref;
1131 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1135 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
1132 Binders::new(substs.len(), inner) 1136 Binders::new(substs.len(), inner)
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index be72c4a1c..943d3339b 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -21,7 +21,7 @@ use crate::{
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 utils::all_super_traits, 22 utils::all_super_traits,
23 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 23 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
24 Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 24 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
25}; 25};
26 26
27/// This is used as a key for indexing impls. 27/// This is used as a key for indexing impls.
@@ -672,10 +672,10 @@ pub(crate) fn inherent_impl_substs(
672 db: &dyn HirDatabase, 672 db: &dyn HirDatabase,
673 impl_id: ImplId, 673 impl_id: ImplId,
674 self_ty: &Canonical<Ty>, 674 self_ty: &Canonical<Ty>,
675) -> Option<Substs> { 675) -> Option<Substitution> {
676 // we create a var for each type parameter of the impl; we need to keep in 676 // we create a var for each type parameter of the impl; we need to keep in
677 // mind here that `self_ty` might have vars of its own 677 // mind here that `self_ty` might have vars of its own
678 let vars = Substs::build_for_def(db, impl_id) 678 let vars = Substitution::build_for_def(db, impl_id)
679 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) 679 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len())
680 .build(); 680 .build();
681 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 681 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
@@ -693,7 +693,7 @@ pub(crate) fn inherent_impl_substs(
693 693
694/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 694/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
695/// num_vars_to_keep) by `TyKind::Unknown`. 695/// num_vars_to_keep) by `TyKind::Unknown`.
696fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { 696fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
697 s.fold_binders( 697 s.fold_binders(
698 &mut |ty, binders| { 698 &mut |ty, binders| {
699 if let TyKind::BoundVar(bound) = ty.interned(&Interner) { 699 if let TyKind::BoundVar(bound) = ty.interned(&Interner) {
@@ -716,13 +716,13 @@ fn transform_receiver_ty(
716 self_ty: &Canonical<Ty>, 716 self_ty: &Canonical<Ty>,
717) -> Option<Ty> { 717) -> Option<Ty> {
718 let substs = match function_id.lookup(db.upcast()).container { 718 let substs = match function_id.lookup(db.upcast()).container {
719 AssocContainerId::TraitId(_) => Substs::build_for_def(db, function_id) 719 AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id)
720 .push(self_ty.value.clone()) 720 .push(self_ty.value.clone())
721 .fill_with_unknown() 721 .fill_with_unknown()
722 .build(), 722 .build(),
723 AssocContainerId::ImplId(impl_id) => { 723 AssocContainerId::ImplId(impl_id) => {
724 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 724 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
725 Substs::build_for_def(db, function_id) 725 Substitution::build_for_def(db, function_id)
726 .use_parent_substs(&impl_substs) 726 .use_parent_substs(&impl_substs)
727 .fill_with_unknown() 727 .fill_with_unknown()
728 .build() 728 .build()
@@ -768,7 +768,7 @@ fn generic_implements_goal(
768 self_ty: Canonical<Ty>, 768 self_ty: Canonical<Ty>,
769) -> Canonical<InEnvironment<super::Obligation>> { 769) -> Canonical<InEnvironment<super::Obligation>> {
770 let mut kinds = self_ty.kinds.to_vec(); 770 let mut kinds = self_ty.kinds.to_vec();
771 let substs = super::Substs::build_for_def(db, trait_) 771 let substs = super::Substitution::build_for_def(db, trait_)
772 .push(self_ty.value) 772 .push(self_ty.value)
773 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 773 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
774 .build(); 774 .build();
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index a6a63c673..40eb1034e 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -8,7 +8,7 @@ use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver};
8use hir_def::{lang_item::LangItemTarget, TraitId}; 8use hir_def::{lang_item::LangItemTarget, TraitId};
9use stdx::panic_context; 9use stdx::panic_context;
10 10
11use crate::{db::HirDatabase, DebruijnIndex, Substs}; 11use crate::{db::HirDatabase, DebruijnIndex, Substitution};
12 12
13use super::{ 13use super::{
14 Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk, 14 Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk,
@@ -252,7 +252,7 @@ fn solution_from_chalk(
252} 252}
253 253
254#[derive(Clone, Debug, PartialEq, Eq)] 254#[derive(Clone, Debug, PartialEq, Eq)]
255pub struct SolutionVariables(pub Canonical<Substs>); 255pub struct SolutionVariables(pub Canonical<Substitution>);
256 256
257#[derive(Clone, Debug, PartialEq, Eq)] 257#[derive(Clone, Debug, PartialEq, Eq)]
258/// A (possible) solution for a proposed goal. 258/// A (possible) solution for a proposed goal.
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 4bd8ba303..bef6e7e9c 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -22,7 +22,7 @@ use crate::{
22 to_assoc_type_id, 22 to_assoc_type_id,
23 utils::generics, 23 utils::generics,
24 BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate, 24 BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
25 ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TyKind, 25 ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
26}; 26};
27use mapping::{ 27use mapping::{
28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, 28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -221,7 +221,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
221 let impl_bound = GenericPredicate::Implemented(TraitRef { 221 let impl_bound = GenericPredicate::Implemented(TraitRef {
222 trait_: future_trait, 222 trait_: future_trait,
223 // Self type as the first parameter. 223 // Self type as the first parameter.
224 substs: Substs::single( 224 substs: Substitution::single(
225 TyKind::BoundVar(BoundVar { 225 TyKind::BoundVar(BoundVar {
226 debruijn: DebruijnIndex::INNERMOST, 226 debruijn: DebruijnIndex::INNERMOST,
227 index: 0, 227 index: 0,
@@ -236,7 +236,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
236 projection_ty: ProjectionTy { 236 projection_ty: ProjectionTy {
237 associated_ty_id: to_assoc_type_id(future_output), 237 associated_ty_id: to_assoc_type_id(future_output),
238 // Self type as the first parameter. 238 // Self type as the first parameter.
239 substitution: Substs::single( 239 substitution: Substitution::single(
240 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) 240 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
241 .intern(&Interner), 241 .intern(&Interner),
242 ), 242 ),
@@ -313,7 +313,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
313 _closure_id: chalk_ir::ClosureId<Interner>, 313 _closure_id: chalk_ir::ClosureId<Interner>,
314 _substs: &chalk_ir::Substitution<Interner>, 314 _substs: &chalk_ir::Substitution<Interner>,
315 ) -> chalk_ir::Substitution<Interner> { 315 ) -> chalk_ir::Substitution<Interner> {
316 Substs::empty().to_chalk(self.db) 316 Substitution::empty().to_chalk(self.db)
317 } 317 }
318 318
319 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { 319 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
@@ -392,7 +392,7 @@ pub(crate) fn associated_ty_data_query(
392 // Lower bounds -- we could/should maybe move this to a separate query in `lower` 392 // Lower bounds -- we could/should maybe move this to a separate query in `lower`
393 let type_alias_data = db.type_alias_data(type_alias); 393 let type_alias_data = db.type_alias_data(type_alias);
394 let generic_params = generics(db.upcast(), type_alias.into()); 394 let generic_params = generics(db.upcast(), type_alias.into());
395 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 395 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
396 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); 396 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
397 let ctx = crate::TyLoweringContext::new(db, &resolver) 397 let ctx = crate::TyLoweringContext::new(db, &resolver)
398 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); 398 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
@@ -427,7 +427,7 @@ pub(crate) fn trait_datum_query(
427 let trait_data = db.trait_data(trait_); 427 let trait_data = db.trait_data(trait_);
428 debug!("trait {:?} = {:?}", trait_id, trait_data.name); 428 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
429 let generic_params = generics(db.upcast(), trait_.into()); 429 let generic_params = generics(db.upcast(), trait_.into());
430 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 430 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
431 let flags = rust_ir::TraitFlags { 431 let flags = rust_ir::TraitFlags {
432 auto: trait_data.is_auto, 432 auto: trait_data.is_auto,
433 upstream: trait_.lookup(db.upcast()).container.krate() != krate, 433 upstream: trait_.lookup(db.upcast()).container.krate() != krate,
@@ -496,7 +496,7 @@ pub(crate) fn struct_datum_query(
496 let upstream = adt_id.module(db.upcast()).krate() != krate; 496 let upstream = adt_id.module(db.upcast()).krate() != krate;
497 let where_clauses = { 497 let where_clauses = {
498 let generic_params = generics(db.upcast(), adt_id.into()); 498 let generic_params = generics(db.upcast(), adt_id.into());
499 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 499 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
500 convert_where_clauses(db, adt_id.into(), &bound_vars) 500 convert_where_clauses(db, adt_id.into(), &bound_vars)
501 }; 501 };
502 let flags = rust_ir::AdtFlags { 502 let flags = rust_ir::AdtFlags {
@@ -545,7 +545,7 @@ fn impl_def_datum(
545 let impl_data = db.impl_data(impl_id); 545 let impl_data = db.impl_data(impl_id);
546 546
547 let generic_params = generics(db.upcast(), impl_id.into()); 547 let generic_params = generics(db.upcast(), impl_id.into());
548 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 548 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
549 let trait_ = trait_ref.trait_; 549 let trait_ = trait_ref.trait_;
550 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { 550 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
551 rust_ir::ImplType::Local 551 rust_ir::ImplType::Local
@@ -635,7 +635,7 @@ pub(crate) fn fn_def_datum_query(
635 let callable_def: CallableDefId = from_chalk(db, fn_def_id); 635 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
636 let generic_params = generics(db.upcast(), callable_def.into()); 636 let generic_params = generics(db.upcast(), callable_def.into());
637 let sig = db.callable_item_signature(callable_def); 637 let sig = db.callable_item_signature(callable_def);
638 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 638 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
639 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); 639 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
640 let bound = rust_ir::FnDefDatumBound { 640 let bound = rust_ir::FnDefDatumBound {
641 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway 641 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 6a8b6752e..d969527dc 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -15,7 +15,7 @@ use crate::{
15 primitive::UintTy, 15 primitive::UintTy,
16 traits::{Canonical, Obligation}, 16 traits::{Canonical, Obligation},
17 AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, 17 AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy,
18 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty, 18 ProjectionPredicate, ProjectionTy, Scalar, Substitution, TraitRef, Ty,
19}; 19};
20 20
21use super::interner::*; 21use super::interner::*;
@@ -52,7 +52,7 @@ impl ToChalk for Ty {
52 52
53 TyKind::Tuple(cardinality, substs) => { 53 TyKind::Tuple(cardinality, substs) => {
54 let substitution = substs.to_chalk(db); 54 let substitution = substs.to_chalk(db);
55 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) 55 chalk_ir::TyKind::Tuple(cardinality, substitution).intern(&Interner)
56 } 56 }
57 TyKind::Raw(mutability, ty) => { 57 TyKind::Raw(mutability, ty) => {
58 let ty = ty.to_chalk(db); 58 let ty = ty.to_chalk(db);
@@ -134,7 +134,7 @@ impl ToChalk for Ty {
134 .. 134 ..
135 }) => { 135 }) => {
136 assert_eq!(num_binders, 0); 136 assert_eq!(num_binders, 0);
137 let substs: Substs = from_chalk( 137 let substs: Substitution = from_chalk(
138 db, 138 db,
139 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 139 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
140 ); 140 );
@@ -213,14 +213,17 @@ fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
213 chalk_ir::TyKind::Array(arg, const_).intern(&Interner) 213 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
214} 214}
215 215
216impl ToChalk for Substs { 216impl ToChalk for Substitution {
217 type Chalk = chalk_ir::Substitution<Interner>; 217 type Chalk = chalk_ir::Substitution<Interner>;
218 218
219 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 219 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
220 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) 220 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
221 } 221 }
222 222
223 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { 223 fn from_chalk(
224 db: &dyn HirDatabase,
225 parameters: chalk_ir::Substitution<Interner>,
226 ) -> Substitution {
224 let tys = parameters 227 let tys = parameters
225 .iter(&Interner) 228 .iter(&Interner)
226 .map(|p| match p.ty(&Interner) { 229 .map(|p| match p.ty(&Interner) {
@@ -228,7 +231,7 @@ impl ToChalk for Substs {
228 None => unimplemented!(), 231 None => unimplemented!(),
229 }) 232 })
230 .collect(); 233 .collect();
231 Substs(tys) 234 Substitution(tys)
232 } 235 }
233} 236}
234 237
@@ -489,7 +492,7 @@ where
489pub(super) fn convert_where_clauses( 492pub(super) fn convert_where_clauses(
490 db: &dyn HirDatabase, 493 db: &dyn HirDatabase,
491 def: GenericDefId, 494 def: GenericDefId,
492 substs: &Substs, 495 substs: &Substitution,
493) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { 496) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
494 let generic_predicates = db.generic_predicates(def); 497 let generic_predicates = db.generic_predicates(def);
495 let mut result = Vec::with_capacity(generic_predicates.len()); 498 let mut result = Vec::with_capacity(generic_predicates.len());
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs
index cbfc66ab3..2f840909c 100644
--- a/crates/ide/src/diagnostics/fixes.rs
+++ b/crates/ide/src/diagnostics/fixes.rs
@@ -180,7 +180,7 @@ fn missing_record_expr_field_fix(
180 let def_id = sema.resolve_variant(record_lit)?; 180 let def_id = sema.resolve_variant(record_lit)?;
181 let module; 181 let module;
182 let def_file_id; 182 let def_file_id;
183 let record_fields = match VariantDef::from(def_id) { 183 let record_fields = match def_id {
184 VariantDef::Struct(s) => { 184 VariantDef::Struct(s) => {
185 module = s.module(sema.db); 185 module = s.module(sema.db);
186 let source = s.source(sema.db)?; 186 let source = s.source(sema.db)?;
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 461e11060..5ea9fc4fb 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -93,7 +93,7 @@ pub(crate) fn remove_links(markdown: &str) -> String {
93 93
94 let mut cb = |_: BrokenLink| { 94 let mut cb = |_: BrokenLink| {
95 let empty = InlineStr::try_from("").unwrap(); 95 let empty = InlineStr::try_from("").unwrap();
96 Some((CowStr::Inlined(empty.clone()), CowStr::Inlined(empty))) 96 Some((CowStr::Inlined(empty), CowStr::Inlined(empty)))
97 }; 97 };
98 let doc = Parser::new_with_broken_link_callback(markdown, opts, Some(&mut cb)); 98 let doc = Parser::new_with_broken_link_callback(markdown, opts, Some(&mut cb));
99 let doc = doc.filter_map(move |evt| match evt { 99 let doc = doc.filter_map(move |evt| match evt {
@@ -147,7 +147,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
147 _ => return None, 147 _ => return None,
148 }; 148 };
149 149
150 let ns = ItemInNs::from(target_def.clone()); 150 let ns = ItemInNs::from(target_def);
151 151
152 let module = definition.module(db)?; 152 let module = definition.module(db)?;
153 let krate = module.krate(); 153 let krate = module.krate();
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 6986477a5..b71f4917c 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -102,7 +102,7 @@ fn extract_positioned_link_from_comment(
102 None => comment_range.end(), 102 None => comment_range.end(),
103 } 103 }
104 })?; 104 })?;
105 Some((def_link.to_string(), ns.clone())) 105 Some((def_link.to_string(), *ns))
106} 106}
107 107
108fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { 108fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 8d45b4875..325014622 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -1,6 +1,6 @@
1use either::Either; 1use either::Either;
2use hir::{ 2use hir::{
3 Adt, AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, Module, 3 AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, Module,
4 ModuleDef, Semantics, 4 ModuleDef, Semantics,
5}; 5};
6use ide_db::{ 6use ide_db::{
@@ -339,9 +339,7 @@ fn hover_for_definition(
339 Definition::ModuleDef(it) => match it { 339 Definition::ModuleDef(it) => match it {
340 ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path), 340 ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path),
341 ModuleDef::Function(it) => from_hir_fmt(db, it, mod_path), 341 ModuleDef::Function(it) => from_hir_fmt(db, it, mod_path),
342 ModuleDef::Adt(Adt::Struct(it)) => from_hir_fmt(db, it, mod_path), 342 ModuleDef::Adt(it) => from_hir_fmt(db, it, mod_path),
343 ModuleDef::Adt(Adt::Union(it)) => from_hir_fmt(db, it, mod_path),
344 ModuleDef::Adt(Adt::Enum(it)) => from_hir_fmt(db, it, mod_path),
345 ModuleDef::Variant(it) => from_hir_fmt(db, it, mod_path), 343 ModuleDef::Variant(it) => from_hir_fmt(db, it, mod_path),
346 ModuleDef::Const(it) => from_hir_fmt(db, it, mod_path), 344 ModuleDef::Const(it) => from_hir_fmt(db, it, mod_path),
347 ModuleDef::Static(it) => from_hir_fmt(db, it, mod_path), 345 ModuleDef::Static(it) => from_hir_fmt(db, it, mod_path),
@@ -353,18 +351,10 @@ fn hover_for_definition(
353 }, 351 },
354 Definition::Local(it) => hover_for_local(it, db), 352 Definition::Local(it) => hover_for_local(it, db),
355 Definition::SelfType(impl_def) => { 353 Definition::SelfType(impl_def) => {
356 impl_def.target_ty(db).as_adt().and_then(|adt| match adt { 354 impl_def.target_ty(db).as_adt().and_then(|adt| from_hir_fmt(db, adt, mod_path))
357 Adt::Struct(it) => from_hir_fmt(db, it, mod_path),
358 Adt::Union(it) => from_hir_fmt(db, it, mod_path),
359 Adt::Enum(it) => from_hir_fmt(db, it, mod_path),
360 })
361 } 355 }
356 Definition::GenericParam(it) => from_hir_fmt(db, it, None),
362 Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), 357 Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))),
363 Definition::GenericParam(it) => match it {
364 GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))),
365 GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))),
366 GenericParam::ConstParam(it) => Some(Markup::fenced_block(&it.display(db))),
367 },
368 }; 358 };
369 359
370 fn from_hir_fmt<D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> 360 fn from_hir_fmt<D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup>
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index d4c367f66..d57ce4027 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -60,7 +60,7 @@ pub(super) fn ra_fixture(
60 for range in inj.map_range_up(hl_range.range) { 60 for range in inj.map_range_up(hl_range.range) {
61 if let Some(range) = literal.map_range_up(range) { 61 if let Some(range) = literal.map_range_up(range) {
62 hl_range.range = range; 62 hl_range.range = range;
63 hl.add(hl_range.clone()); 63 hl.add(hl_range);
64 } 64 }
65 } 65 }
66 } 66 }
diff --git a/crates/ide_assists/src/handlers/expand_glob_import.rs b/crates/ide_assists/src/handlers/expand_glob_import.rs
index 5b540df5c..83aa11d52 100644
--- a/crates/ide_assists/src/handlers/expand_glob_import.rs
+++ b/crates/ide_assists/src/handlers/expand_glob_import.rs
@@ -73,8 +73,8 @@ fn find_parent_and_path(
73) -> Option<(Either<ast::UseTree, ast::UseTreeList>, ast::Path)> { 73) -> Option<(Either<ast::UseTree, ast::UseTreeList>, ast::Path)> {
74 return star.ancestors().find_map(|n| { 74 return star.ancestors().find_map(|n| {
75 find_use_tree_list(n.clone()) 75 find_use_tree_list(n.clone())
76 .and_then(|(u, p)| Some((Either::Right(u), p))) 76 .map(|(u, p)| (Either::Right(u), p))
77 .or_else(|| find_use_tree(n).and_then(|(u, p)| Some((Either::Left(u), p)))) 77 .or_else(|| find_use_tree(n).map(|(u, p)| (Either::Left(u), p)))
78 }); 78 });
79 79
80 fn find_use_tree_list(n: SyntaxNode) -> Option<(ast::UseTreeList, ast::Path)> { 80 fn find_use_tree_list(n: SyntaxNode) -> Option<(ast::UseTreeList, ast::Path)> {
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index 335e0ed95..596c536a7 100644
--- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -145,11 +145,8 @@ fn insert_import(
145 variant_hir_name: &Name, 145 variant_hir_name: &Name,
146) -> Option<()> { 146) -> Option<()> {
147 let db = ctx.db(); 147 let db = ctx.db();
148 let mod_path = module.find_use_path_prefixed( 148 let mod_path =
149 db, 149 module.find_use_path_prefixed(db, *enum_module_def, ctx.config.insert_use.prefix_kind);
150 enum_module_def.clone(),
151 ctx.config.insert_use.prefix_kind,
152 );
153 if let Some(mut mod_path) = mod_path { 150 if let Some(mut mod_path) = mod_path {
154 mod_path.pop_segment(); 151 mod_path.pop_segment();
155 mod_path.push_segment(variant_hir_name.clone()); 152 mod_path.push_segment(variant_hir_name.clone());
diff --git a/crates/ide_assists/src/handlers/move_bounds.rs b/crates/ide_assists/src/handlers/move_bounds.rs
index 48efa67ed..9ad0c9816 100644
--- a/crates/ide_assists/src/handlers/move_bounds.rs
+++ b/crates/ide_assists/src/handlers/move_bounds.rs
@@ -40,9 +40,9 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext
40 let where_clause: ast::WhereClause = match_ast! { 40 let where_clause: ast::WhereClause = match_ast! {
41 match parent { 41 match parent {
42 ast::Fn(it) => it.get_or_create_where_clause(), 42 ast::Fn(it) => it.get_or_create_where_clause(),
43 // ast::Trait(it) => it.get_or_create_where_clause(), 43 ast::Trait(it) => it.get_or_create_where_clause(),
44 ast::Impl(it) => it.get_or_create_where_clause(), 44 ast::Impl(it) => it.get_or_create_where_clause(),
45 // ast::Enum(it) => it.get_or_create_where_clause(), 45 ast::Enum(it) => it.get_or_create_where_clause(),
46 ast::Struct(it) => it.get_or_create_where_clause(), 46 ast::Struct(it) => it.get_or_create_where_clause(),
47 _ => return, 47 _ => return,
48 } 48 }
@@ -82,12 +82,8 @@ mod tests {
82 fn move_bounds_to_where_clause_fn() { 82 fn move_bounds_to_where_clause_fn() {
83 check_assist( 83 check_assist(
84 move_bounds_to_where_clause, 84 move_bounds_to_where_clause,
85 r#" 85 r#"fn foo<T: u32, $0F: FnOnce(T) -> T>() {}"#,
86 fn foo<T: u32, $0F: FnOnce(T) -> T>() {} 86 r#"fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {}"#,
87 "#,
88 r#"
89 fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {}
90 "#,
91 ); 87 );
92 } 88 }
93 89
@@ -95,12 +91,8 @@ mod tests {
95 fn move_bounds_to_where_clause_impl() { 91 fn move_bounds_to_where_clause_impl() {
96 check_assist( 92 check_assist(
97 move_bounds_to_where_clause, 93 move_bounds_to_where_clause,
98 r#" 94 r#"impl<U: u32, $0T> A<U, T> {}"#,
99 impl<U: u32, $0T> A<U, T> {} 95 r#"impl<U, T> A<U, T> where U: u32 {}"#,
100 "#,
101 r#"
102 impl<U, T> A<U, T> where U: u32 {}
103 "#,
104 ); 96 );
105 } 97 }
106 98
@@ -108,12 +100,8 @@ mod tests {
108 fn move_bounds_to_where_clause_struct() { 100 fn move_bounds_to_where_clause_struct() {
109 check_assist( 101 check_assist(
110 move_bounds_to_where_clause, 102 move_bounds_to_where_clause,
111 r#" 103 r#"struct A<$0T: Iterator<Item = u32>> {}"#,
112 struct A<$0T: Iterator<Item = u32>> {} 104 r#"struct A<T> where T: Iterator<Item = u32> {}"#,
113 "#,
114 r#"
115 struct A<T> where T: Iterator<Item = u32> {}
116 "#,
117 ); 105 );
118 } 106 }
119 107
@@ -121,12 +109,8 @@ mod tests {
121 fn move_bounds_to_where_clause_tuple_struct() { 109 fn move_bounds_to_where_clause_tuple_struct() {
122 check_assist( 110 check_assist(
123 move_bounds_to_where_clause, 111 move_bounds_to_where_clause,
124 r#" 112 r#"struct Pair<$0T: u32>(T, T);"#,
125 struct Pair<$0T: u32>(T, T); 113 r#"struct Pair<T>(T, T) where T: u32;"#,
126 "#,
127 r#"
128 struct Pair<T>(T, T) where T: u32;
129 "#,
130 ); 114 );
131 } 115 }
132} 116}
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 3b582ed07..09882c4f3 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -56,7 +56,7 @@ impl Builder {
56 56
57impl Completions { 57impl Completions {
58 pub(crate) fn add(&mut self, item: CompletionItem) { 58 pub(crate) fn add(&mut self, item: CompletionItem) {
59 self.buf.push(item.into()) 59 self.buf.push(item)
60 } 60 }
61 61
62 pub(crate) fn add_all<I>(&mut self, items: I) 62 pub(crate) fn add_all<I>(&mut self, items: I)
diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs
index 46cef58f0..476eecff0 100644
--- a/crates/ide_completion/src/completions/pattern.rs
+++ b/crates/ide_completion/src/completions/pattern.rs
@@ -26,11 +26,11 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
26 let add_resolution = match &res { 26 let add_resolution = match &res {
27 hir::ScopeDef::ModuleDef(def) => match def { 27 hir::ScopeDef::ModuleDef(def) => match def {
28 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => { 28 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => {
29 acc.add_struct_pat(ctx, strukt.clone(), Some(name.clone())); 29 acc.add_struct_pat(ctx, *strukt, Some(name.clone()));
30 true 30 true
31 } 31 }
32 hir::ModuleDef::Variant(variant) if !ctx.is_irrefutable_pat_binding => { 32 hir::ModuleDef::Variant(variant) if !ctx.is_irrefutable_pat_binding => {
33 acc.add_variant_pat(ctx, variant.clone(), Some(name.clone())); 33 acc.add_variant_pat(ctx, *variant, Some(name.clone()));
34 true 34 true
35 } 35 }
36 hir::ModuleDef::Adt(hir::Adt::Enum(..)) 36 hir::ModuleDef::Adt(hir::Adt::Enum(..))
diff --git a/crates/ide_completion/src/completions/postfix/format_like.rs b/crates/ide_completion/src/completions/postfix/format_like.rs
index cee4eec10..3f1c6730b 100644
--- a/crates/ide_completion/src/completions/postfix/format_like.rs
+++ b/crates/ide_completion/src/completions/postfix/format_like.rs
@@ -89,7 +89,7 @@ enum State {
89impl FormatStrParser { 89impl FormatStrParser {
90 pub(crate) fn new(input: String) -> Self { 90 pub(crate) fn new(input: String) -> Self {
91 Self { 91 Self {
92 input: input.into(), 92 input: input,
93 output: String::new(), 93 output: String::new(),
94 extracted_expressions: Vec::new(), 94 extracted_expressions: Vec::new(),
95 state: State::NotExpr, 95 state: State::NotExpr,
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 4e4923e0d..12921e12b 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -81,7 +81,7 @@ impl<'a> RenderContext<'a> {
81 } 81 }
82 82
83 fn snippet_cap(&self) -> Option<SnippetCap> { 83 fn snippet_cap(&self) -> Option<SnippetCap> {
84 self.completion.config.snippet_cap.clone() 84 self.completion.config.snippet_cap
85 } 85 }
86 86
87 fn db(&self) -> &'a RootDatabase { 87 fn db(&self) -> &'a RootDatabase {
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index f86e5ce93..75167ff39 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -181,7 +181,7 @@ impl NameClass {
181 }, 181 },
182 ast::SelfParam(it) => { 182 ast::SelfParam(it) => {
183 let def = sema.to_def(&it)?; 183 let def = sema.to_def(&it)?;
184 Some(NameClass::Definition(Definition::Local(def.into()))) 184 Some(NameClass::Definition(Definition::Local(def)))
185 }, 185 },
186 ast::RecordField(it) => { 186 ast::RecordField(it) => {
187 let field: hir::Field = sema.to_def(&it)?; 187 let field: hir::Field = sema.to_def(&it)?;
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index df66d8ea0..9e0cb91c3 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -80,7 +80,7 @@ impl ImportScope {
80 }) 80 })
81 .last() 81 .last()
82 .map(|last_inner_element| { 82 .map(|last_inner_element| {
83 (InsertPosition::After(last_inner_element.into()), AddBlankLine::BeforeTwice) 83 (InsertPosition::After(last_inner_element), AddBlankLine::BeforeTwice)
84 }) 84 })
85 .unwrap_or_else(|| self.first_insert_pos()) 85 .unwrap_or_else(|| self.first_insert_pos())
86 } 86 }
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs
index f56221a6c..324817cd0 100644
--- a/crates/ide_db/src/search.rs
+++ b/crates/ide_db/src/search.rs
@@ -161,15 +161,9 @@ impl Definition {
161 161
162 if let Definition::Local(var) = self { 162 if let Definition::Local(var) = self {
163 let range = match var.parent(db) { 163 let range = match var.parent(db) {
164 DefWithBody::Function(f) => { 164 DefWithBody::Function(f) => f.source(db).map(|src| src.value.syntax().text_range()),
165 f.source(db).and_then(|src| Some(src.value.syntax().text_range())) 165 DefWithBody::Const(c) => c.source(db).map(|src| src.value.syntax().text_range()),
166 } 166 DefWithBody::Static(s) => s.source(db).map(|src| src.value.syntax().text_range()),
167 DefWithBody::Const(c) => {
168 c.source(db).and_then(|src| Some(src.value.syntax().text_range()))
169 }
170 DefWithBody::Static(s) => {
171 s.source(db).and_then(|src| Some(src.value.syntax().text_range()))
172 }
173 }; 167 };
174 let mut res = FxHashMap::default(); 168 let mut res = FxHashMap::default();
175 res.insert(file_id, range); 169 res.insert(file_id, range);
@@ -179,33 +173,29 @@ impl Definition {
179 if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { 173 if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self {
180 let range = match param.parent(db) { 174 let range = match param.parent(db) {
181 hir::GenericDef::Function(it) => { 175 hir::GenericDef::Function(it) => {
182 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 176 it.source(db).map(|src| src.value.syntax().text_range())
183 } 177 }
184 hir::GenericDef::Adt(it) => match it { 178 hir::GenericDef::Adt(it) => match it {
185 hir::Adt::Struct(it) => { 179 hir::Adt::Struct(it) => {
186 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 180 it.source(db).map(|src| src.value.syntax().text_range())
187 }
188 hir::Adt::Union(it) => {
189 it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
190 }
191 hir::Adt::Enum(it) => {
192 it.source(db).and_then(|src| Some(src.value.syntax().text_range()))
193 } 181 }
182 hir::Adt::Union(it) => it.source(db).map(|src| src.value.syntax().text_range()),
183 hir::Adt::Enum(it) => it.source(db).map(|src| src.value.syntax().text_range()),
194 }, 184 },
195 hir::GenericDef::Trait(it) => { 185 hir::GenericDef::Trait(it) => {
196 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 186 it.source(db).map(|src| src.value.syntax().text_range())
197 } 187 }
198 hir::GenericDef::TypeAlias(it) => { 188 hir::GenericDef::TypeAlias(it) => {
199 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 189 it.source(db).map(|src| src.value.syntax().text_range())
200 } 190 }
201 hir::GenericDef::Impl(it) => { 191 hir::GenericDef::Impl(it) => {
202 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 192 it.source(db).map(|src| src.value.syntax().text_range())
203 } 193 }
204 hir::GenericDef::Variant(it) => { 194 hir::GenericDef::Variant(it) => {
205 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 195 it.source(db).map(|src| src.value.syntax().text_range())
206 } 196 }
207 hir::GenericDef::Const(it) => { 197 hir::GenericDef::Const(it) => {
208 it.source(db).and_then(|src| Some(src.value.syntax().text_range())) 198 it.source(db).map(|src| src.value.syntax().text_range())
209 } 199 }
210 }; 200 };
211 let mut res = FxHashMap::default(); 201 let mut res = FxHashMap::default();
diff --git a/crates/ide_ssr/src/lib.rs b/crates/ide_ssr/src/lib.rs
index 00585f448..47434f4af 100644
--- a/crates/ide_ssr/src/lib.rs
+++ b/crates/ide_ssr/src/lib.rs
@@ -139,11 +139,8 @@ impl<'db> MatchFinder<'db> {
139 pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> { 139 pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> {
140 use ide_db::base_db::SourceDatabaseExt; 140 use ide_db::base_db::SourceDatabaseExt;
141 use ide_db::symbol_index::SymbolsDatabase; 141 use ide_db::symbol_index::SymbolsDatabase;
142 if let Some(first_file_id) = db 142 if let Some(first_file_id) =
143 .local_roots() 143 db.local_roots().iter().next().and_then(|root| db.source_root(*root).iter().next())
144 .iter()
145 .next()
146 .and_then(|root| db.source_root(root.clone()).iter().next())
147 { 144 {
148 Ok(MatchFinder::in_context( 145 Ok(MatchFinder::in_context(
149 db, 146 db,
diff --git a/crates/ide_ssr/src/matching.rs b/crates/ide_ssr/src/matching.rs
index e1adb381e..b3072fb9f 100644
--- a/crates/ide_ssr/src/matching.rs
+++ b/crates/ide_ssr/src/matching.rs
@@ -127,7 +127,7 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
127 restrict_range: &Option<FileRange>, 127 restrict_range: &Option<FileRange>,
128 sema: &'sema Semantics<'db, ide_db::RootDatabase>, 128 sema: &'sema Semantics<'db, ide_db::RootDatabase>,
129 ) -> Result<Match, MatchFailed> { 129 ) -> Result<Match, MatchFailed> {
130 let match_state = Matcher { sema, restrict_range: restrict_range.clone(), rule }; 130 let match_state = Matcher { sema, restrict_range: *restrict_range, rule };
131 // First pass at matching, where we check that node types and idents match. 131 // First pass at matching, where we check that node types and idents match.
132 match_state.attempt_match_node(&mut Phase::First, &rule.pattern.node, code)?; 132 match_state.attempt_match_node(&mut Phase::First, &rule.pattern.node, code)?;
133 match_state.validate_range(&sema.original_range(code))?; 133 match_state.validate_range(&sema.original_range(code))?;
diff --git a/crates/mbe/src/benchmark.rs b/crates/mbe/src/benchmark.rs
index 503ad1355..ba814a2e1 100644
--- a/crates/mbe/src/benchmark.rs
+++ b/crates/mbe/src/benchmark.rs
@@ -120,7 +120,7 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt
120 Some("pat") => parent.token_trees.push(make_ident("foo")), 120 Some("pat") => parent.token_trees.push(make_ident("foo")),
121 Some("path") => parent.token_trees.push(make_ident("foo")), 121 Some("path") => parent.token_trees.push(make_ident("foo")),
122 Some("literal") => parent.token_trees.push(make_literal("1")), 122 Some("literal") => parent.token_trees.push(make_literal("1")),
123 Some("expr") => parent.token_trees.push(make_ident("foo").into()), 123 Some("expr") => parent.token_trees.push(make_ident("foo")),
124 Some("lifetime") => { 124 Some("lifetime") => {
125 parent.token_trees.push(make_punct('\'')); 125 parent.token_trees.push(make_punct('\''));
126 parent.token_trees.push(make_ident("a")); 126 parent.token_trees.push(make_ident("a"));
@@ -157,17 +157,15 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt
157 if i + 1 != cnt { 157 if i + 1 != cnt {
158 if let Some(sep) = separator { 158 if let Some(sep) = separator {
159 match sep { 159 match sep {
160 Separator::Literal(it) => parent 160 Separator::Literal(it) => {
161 .token_trees 161 parent.token_trees.push(tt::Leaf::Literal(it.clone()).into())
162 .push(tt::Leaf::Literal(it.clone().into()).into()), 162 }
163 Separator::Ident(it) => parent 163 Separator::Ident(it) => {
164 .token_trees 164 parent.token_trees.push(tt::Leaf::Ident(it.clone()).into())
165 .push(tt::Leaf::Ident(it.clone().into()).into()), 165 }
166 Separator::Puncts(puncts) => { 166 Separator::Puncts(puncts) => {
167 for it in puncts { 167 for it in puncts {
168 parent 168 parent.token_trees.push(tt::Leaf::Punct(*it).into())
169 .token_trees
170 .push(tt::Leaf::Punct(it.clone().into()).into())
171 } 169 }
172 } 170 }
173 }; 171 };
@@ -176,8 +174,7 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt
176 } 174 }
177 } 175 }
178 Op::Subtree { tokens, delimiter } => { 176 Op::Subtree { tokens, delimiter } => {
179 let mut subtree = 177 let mut subtree = tt::Subtree { delimiter: *delimiter, token_trees: Vec::new() };
180 tt::Subtree { delimiter: delimiter.clone(), token_trees: Vec::new() };
181 tokens.iter().for_each(|it| { 178 tokens.iter().for_each(|it| {
182 collect_from_op(it, &mut subtree, seed); 179 collect_from_op(it, &mut subtree, seed);
183 }); 180 });
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 2c69e8968..b6782b4ba 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -540,7 +540,7 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
540 let mut src = TtIter::new(src); 540 let mut src = TtIter::new(src);
541 let mut stack: SmallVec<[TtIter; 1]> = SmallVec::new(); 541 let mut stack: SmallVec<[TtIter; 1]> = SmallVec::new();
542 let mut res = Match::default(); 542 let mut res = Match::default();
543 let mut error_reover_item = None; 543 let mut error_recover_item = None;
544 544
545 let mut bindings_builder = BindingsBuilder::default(); 545 let mut bindings_builder = BindingsBuilder::default();
546 546
@@ -579,9 +579,9 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
579 stdx::always!(cur_items.is_empty()); 579 stdx::always!(cur_items.is_empty());
580 580
581 if error_items.len() > 0 { 581 if error_items.len() > 0 {
582 error_reover_item = error_items.pop().map(|it| it.bindings); 582 error_recover_item = error_items.pop().map(|it| it.bindings);
583 } else if eof_items.len() > 0 { 583 } else if eof_items.len() > 0 {
584 error_reover_item = Some(eof_items[0].bindings.clone()); 584 error_recover_item = Some(eof_items[0].bindings.clone());
585 } 585 }
586 586
587 // We need to do some post processing after the `match_loop_inner`. 587 // We need to do some post processing after the `match_loop_inner`.
@@ -594,8 +594,8 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
594 res.bindings = bindings_builder.build(&eof_items[0].bindings); 594 res.bindings = bindings_builder.build(&eof_items[0].bindings);
595 } else { 595 } else {
596 // Error recovery 596 // Error recovery
597 if error_reover_item.is_some() { 597 if let Some(item) = error_recover_item {
598 res.bindings = bindings_builder.build(&error_reover_item.unwrap()); 598 res.bindings = bindings_builder.build(&item);
599 } 599 }
600 res.add_err(ExpandError::UnexpectedToken); 600 res.add_err(ExpandError::UnexpectedToken);
601 } 601 }
@@ -618,7 +618,7 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
618 } 618 }
619 res.add_err(err!("leftover tokens")); 619 res.add_err(err!("leftover tokens"));
620 620
621 if let Some(error_reover_item) = error_reover_item { 621 if let Some(error_reover_item) = error_recover_item {
622 res.bindings = bindings_builder.build(&error_reover_item); 622 res.bindings = bindings_builder.build(&error_reover_item);
623 } 623 }
624 return res; 624 return res;
@@ -722,7 +722,7 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
722 input 722 input
723 .expect_literal() 723 .expect_literal()
724 .map(|literal| { 724 .map(|literal| {
725 let lit = tt::Leaf::from(literal.clone()); 725 let lit = literal.clone();
726 match neg { 726 match neg {
727 None => Some(lit.into()), 727 None => Some(lit.into()),
728 Some(neg) => Some(tt::TokenTree::Subtree(tt::Subtree { 728 Some(neg) => Some(tt::TokenTree::Subtree(tt::Subtree {
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 8671322e1..7b5b8ec16 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -262,7 +262,7 @@ fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), Par
262 if puncts.len() == 3 { 262 if puncts.len() == 3 {
263 return Err(ParseError::InvalidRepeat); 263 return Err(ParseError::InvalidRepeat);
264 } 264 }
265 puncts.push(punct.clone()) 265 puncts.push(*punct)
266 } 266 }
267 _ => return Err(ParseError::InvalidRepeat), 267 _ => return Err(ParseError::InvalidRepeat),
268 } 268 }
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index b715ebfc4..85163c4b3 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -130,7 +130,7 @@ pub fn parse_exprs_with_sep(tt: &tt::Subtree, sep: char) -> Vec<tt::Subtree> {
130 res.push(match expanded.value { 130 res.push(match expanded.value {
131 None => break, 131 None => break,
132 Some(tt @ tt::TokenTree::Leaf(_)) => { 132 Some(tt @ tt::TokenTree::Leaf(_)) => {
133 tt::Subtree { delimiter: None, token_trees: vec![tt.into()] } 133 tt::Subtree { delimiter: None, token_trees: vec![tt] }
134 } 134 }
135 Some(tt::TokenTree::Subtree(tt)) => tt, 135 Some(tt::TokenTree::Subtree(tt)) => tt,
136 }); 136 });
@@ -727,7 +727,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
727 // Note: We always assume the semi-colon would be the last token in 727 // Note: We always assume the semi-colon would be the last token in
728 // other parts of RA such that we don't add whitespace here. 728 // other parts of RA such that we don't add whitespace here.
729 if curr.spacing == tt::Spacing::Alone && curr.char != ';' { 729 if curr.spacing == tt::Spacing::Alone && curr.char != ';' {
730 self.inner.token(WHITESPACE, " ".into()); 730 self.inner.token(WHITESPACE, " ");
731 self.text_pos += TextSize::of(' '); 731 self.text_pos += TextSize::of(' ');
732 } 732 }
733 } 733 }
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs
index eca0bcc18..25c374b9b 100644
--- a/crates/mbe/src/tests.rs
+++ b/crates/mbe/src/tests.rs
@@ -35,7 +35,7 @@ mod rule_parsing {
35 fn test_invalid_arms() { 35 fn test_invalid_arms() {
36 fn check(macro_body: &str, err: ParseError) { 36 fn check(macro_body: &str, err: ParseError) {
37 let m = parse_macro_arm(macro_body); 37 let m = parse_macro_arm(macro_body);
38 assert_eq!(m, Err(err.into())); 38 assert_eq!(m, Err(err));
39 } 39 }
40 check("invalid", ParseError::Expected("expected subtree".into())); 40 check("invalid", ParseError::Expected("expected subtree".into()));
41 41
diff --git a/crates/proc_macro_api/src/process.rs b/crates/proc_macro_api/src/process.rs
index 3ce851fe8..30bb1b687 100644
--- a/crates/proc_macro_api/src/process.rs
+++ b/crates/proc_macro_api/src/process.rs
@@ -154,5 +154,5 @@ fn send_request(
154 req: Request, 154 req: Request,
155) -> io::Result<Option<Response>> { 155) -> io::Result<Option<Response>> {
156 req.write(&mut writer)?; 156 req.write(&mut writer)?;
157 Ok(Response::read(&mut reader)?) 157 Response::read(&mut reader)
158} 158}
diff --git a/crates/proc_macro_api/src/rpc.rs b/crates/proc_macro_api/src/rpc.rs
index 64cfdafc5..9a68e2cc5 100644
--- a/crates/proc_macro_api/src/rpc.rs
+++ b/crates/proc_macro_api/src/rpc.rs
@@ -236,13 +236,10 @@ mod tests {
236 subtree 236 subtree
237 .token_trees 237 .token_trees
238 .push(TokenTree::Leaf(Ident { text: "Foo".into(), id: TokenId(1) }.into())); 238 .push(TokenTree::Leaf(Ident { text: "Foo".into(), id: TokenId(1) }.into()));
239 subtree.token_trees.push(TokenTree::Subtree( 239 subtree.token_trees.push(TokenTree::Subtree(Subtree {
240 Subtree { 240 delimiter: Some(Delimiter { id: TokenId(2), kind: DelimiterKind::Brace }),
241 delimiter: Some(Delimiter { id: TokenId(2), kind: DelimiterKind::Brace }), 241 token_trees: vec![],
242 token_trees: vec![], 242 }));
243 }
244 .into(),
245 ));
246 subtree 243 subtree
247 } 244 }
248 245
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 0ad832c0e..76994de71 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -161,7 +161,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
161 return Vec::new(); 161 return Vec::new();
162 } 162 }
163 163
164 let severity = diagnostic_severity(config, rd.level.clone(), rd.code.clone()); 164 let severity = diagnostic_severity(config, rd.level, rd.code.clone());
165 165
166 let mut source = String::from("rustc"); 166 let mut source = String::from("rustc");
167 let mut code = rd.code.as_ref().map(|c| c.code.clone()); 167 let mut code = rd.code.as_ref().map(|c| c.code.clone());
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 6fb7da79c..b6f484e51 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -1134,7 +1134,7 @@ pub(crate) fn handle_code_lens_resolve(
1134) -> Result<CodeLens> { 1134) -> Result<CodeLens> {
1135 let annotation = from_proto::annotation(&snap, code_lens)?; 1135 let annotation = from_proto::annotation(&snap, code_lens)?;
1136 1136
1137 Ok(to_proto::code_lens(&snap, snap.analysis.resolve_annotation(annotation)?)?) 1137 to_proto::code_lens(&snap, snap.analysis.resolve_annotation(annotation)?)
1138} 1138}
1139 1139
1140pub(crate) fn handle_document_highlight( 1140pub(crate) fn handle_document_highlight(
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index 3ca7f8040..2ac487632 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -36,7 +36,7 @@ impl Progress {
36 36
37impl GlobalState { 37impl GlobalState {
38 pub(crate) fn show_message(&mut self, typ: lsp_types::MessageType, message: String) { 38 pub(crate) fn show_message(&mut self, typ: lsp_types::MessageType, message: String) {
39 let message = message.into(); 39 let message = message;
40 self.send_notification::<lsp_types::notification::ShowMessage>( 40 self.send_notification::<lsp_types::notification::ShowMessage>(
41 lsp_types::ShowMessageParams { typ, message }, 41 lsp_types::ShowMessageParams { typ, message },
42 ) 42 )
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 70eaae5e8..c63fe2915 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -287,7 +287,7 @@ pub(crate) fn signature_help(
287 let params = call_info 287 let params = call_info
288 .parameter_ranges() 288 .parameter_ranges()
289 .iter() 289 .iter()
290 .map(|it| [u32::from(it.start()).into(), u32::from(it.end()).into()]) 290 .map(|it| [u32::from(it.start()), u32::from(it.end())])
291 .map(|label_offsets| lsp_types::ParameterInformation { 291 .map(|label_offsets| lsp_types::ParameterInformation {
292 label: lsp_types::ParameterLabel::LabelOffsets(label_offsets), 292 label: lsp_types::ParameterLabel::LabelOffsets(label_offsets),
293 documentation: None, 293 documentation: None,
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 0b3b76d4a..64fac13a7 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -479,7 +479,7 @@ impl ast::MatchArmList {
479 Some(t) => t, 479 Some(t) => t,
480 None => return self.clone(), 480 None => return self.clone(),
481 }; 481 };
482 let position = InsertPosition::Before(r_curly.into()); 482 let position = InsertPosition::Before(r_curly);
483 let arm_ws = tokens::WsBuilder::new(" "); 483 let arm_ws = tokens::WsBuilder::new(" ");
484 let match_indent = &leading_indent(self.syntax()).unwrap_or_default(); 484 let match_indent = &leading_indent(self.syntax()).unwrap_or_default();
485 let match_ws = tokens::WsBuilder::new(&format!("\n{}", match_indent)); 485 let match_ws = tokens::WsBuilder::new(&format!("\n{}", match_indent));
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index 06cde591d..449b058fb 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -8,7 +8,7 @@ use parser::T;
8use crate::{ 8use crate::{
9 ast, 9 ast,
10 ted::{self, Position}, 10 ted::{self, Position},
11 AstNode, Direction, SyntaxKind, 11 AstNode, Direction, SyntaxElement,
12}; 12};
13 13
14use super::NameOwner; 14use super::NameOwner;
@@ -36,8 +36,8 @@ impl GenericParamsOwnerEdit for ast::Fn {
36impl GenericParamsOwnerEdit for ast::Impl { 36impl GenericParamsOwnerEdit for ast::Impl {
37 fn get_or_create_where_clause(&self) -> WhereClause { 37 fn get_or_create_where_clause(&self) -> WhereClause {
38 if self.where_clause().is_none() { 38 if self.where_clause().is_none() {
39 let position = if let Some(ty) = self.self_ty() { 39 let position = if let Some(items) = self.assoc_item_list() {
40 Position::after(ty.syntax().clone()) 40 Position::before(items.syntax().clone())
41 } else { 41 } else {
42 Position::last_child_of(self.syntax().clone()) 42 Position::last_child_of(self.syntax().clone())
43 }; 43 };
@@ -46,6 +46,21 @@ impl GenericParamsOwnerEdit for ast::Impl {
46 self.where_clause().unwrap() 46 self.where_clause().unwrap()
47 } 47 }
48} 48}
49
50impl GenericParamsOwnerEdit for ast::Trait {
51 fn get_or_create_where_clause(&self) -> WhereClause {
52 if self.where_clause().is_none() {
53 let position = if let Some(items) = self.assoc_item_list() {
54 Position::before(items.syntax().clone())
55 } else {
56 Position::last_child_of(self.syntax().clone())
57 };
58 create_where_clause(position)
59 }
60 self.where_clause().unwrap()
61 }
62}
63
49impl GenericParamsOwnerEdit for ast::Struct { 64impl GenericParamsOwnerEdit for ast::Struct {
50 fn get_or_create_where_clause(&self) -> WhereClause { 65 fn get_or_create_where_clause(&self) -> WhereClause {
51 if self.where_clause().is_none() { 66 if self.where_clause().is_none() {
@@ -68,26 +83,35 @@ impl GenericParamsOwnerEdit for ast::Struct {
68 } 83 }
69} 84}
70 85
86impl GenericParamsOwnerEdit for ast::Enum {
87 fn get_or_create_where_clause(&self) -> WhereClause {
88 if self.where_clause().is_none() {
89 let position = if let Some(gpl) = self.generic_param_list() {
90 Position::after(gpl.syntax().clone())
91 } else if let Some(name) = self.name() {
92 Position::after(name.syntax().clone())
93 } else {
94 Position::last_child_of(self.syntax().clone())
95 };
96 create_where_clause(position)
97 }
98 self.where_clause().unwrap()
99 }
100}
101
71fn create_where_clause(position: Position) { 102fn create_where_clause(position: Position) {
72 let elements = vec![ 103 let where_clause: SyntaxElement =
73 make::tokens::single_space().into(), 104 make::where_clause(empty()).clone_for_update().syntax().clone().into();
74 make::where_clause(empty()).clone_for_update().syntax().clone().into(), 105 ted::insert(position, where_clause);
75 ];
76 ted::insert_all(position, elements);
77} 106}
78 107
79impl ast::WhereClause { 108impl ast::WhereClause {
80 pub fn add_predicate(&self, predicate: ast::WherePred) { 109 pub fn add_predicate(&self, predicate: ast::WherePred) {
81 if let Some(pred) = self.predicates().last() { 110 if let Some(pred) = self.predicates().last() {
82 if !pred.syntax().siblings_with_tokens(Direction::Next).any(|it| it.kind() == T![,]) { 111 if !pred.syntax().siblings_with_tokens(Direction::Next).any(|it| it.kind() == T![,]) {
83 ted::append_child(self.syntax().clone(), make::token(T![,])); 112 ted::append_child_raw(self.syntax().clone(), make::token(T![,]));
84 } 113 }
85 } 114 }
86 if self.syntax().children_with_tokens().last().map(|it| it.kind())
87 != Some(SyntaxKind::WHITESPACE)
88 {
89 ted::append_child(self.syntax().clone(), make::tokens::single_space());
90 }
91 ted::append_child(self.syntax().clone(), predicate.syntax().clone()) 115 ted::append_child(self.syntax().clone(), predicate.syntax().clone())
92 } 116 }
93} 117}
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs
index 8d6175ed9..442dfa14a 100644
--- a/crates/syntax/src/ted.rs
+++ b/crates/syntax/src/ted.rs
@@ -1,8 +1,12 @@
1//! Primitive tree editor, ed for trees 1//! Primitive tree editor, ed for trees.
2#![allow(unused)] 2//!
3//! The `_raw`-suffixed functions insert elements as is, unsuffixed versions fix
4//! up elements around the edges.
3use std::ops::RangeInclusive; 5use std::ops::RangeInclusive;
4 6
5use crate::{SyntaxElement, SyntaxNode}; 7use parser::T;
8
9use crate::{ast::make, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken};
6 10
7#[derive(Debug)] 11#[derive(Debug)]
8pub struct Position { 12pub struct Position {
@@ -45,7 +49,23 @@ impl Position {
45pub fn insert(position: Position, elem: impl Into<SyntaxElement>) { 49pub fn insert(position: Position, elem: impl Into<SyntaxElement>) {
46 insert_all(position, vec![elem.into()]) 50 insert_all(position, vec![elem.into()])
47} 51}
48pub fn insert_all(position: Position, elements: Vec<SyntaxElement>) { 52pub fn insert_raw(position: Position, elem: impl Into<SyntaxElement>) {
53 insert_all_raw(position, vec![elem.into()])
54}
55pub fn insert_all(position: Position, mut elements: Vec<SyntaxElement>) {
56 if let Some(first) = elements.first() {
57 if let Some(ws) = ws_before(&position, first) {
58 elements.insert(0, ws.into())
59 }
60 }
61 if let Some(last) = elements.last() {
62 if let Some(ws) = ws_after(&position, last) {
63 elements.push(ws.into())
64 }
65 }
66 insert_all_raw(position, elements)
67}
68pub fn insert_all_raw(position: Position, elements: Vec<SyntaxElement>) {
49 let (parent, index) = match position.repr { 69 let (parent, index) = match position.repr {
50 PositionRepr::FirstChild(parent) => (parent, 0), 70 PositionRepr::FirstChild(parent) => (parent, 0),
51 PositionRepr::After(child) => (child.parent().unwrap(), child.index() + 1), 71 PositionRepr::After(child) => (child.parent().unwrap(), child.index() + 1),
@@ -76,3 +96,31 @@ pub fn append_child(node: impl Into<SyntaxNode>, child: impl Into<SyntaxElement>
76 let position = Position::last_child_of(node); 96 let position = Position::last_child_of(node);
77 insert(position, child) 97 insert(position, child)
78} 98}
99pub fn append_child_raw(node: impl Into<SyntaxNode>, child: impl Into<SyntaxElement>) {
100 let position = Position::last_child_of(node);
101 insert_raw(position, child)
102}
103
104fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
105 let prev = match &position.repr {
106 PositionRepr::FirstChild(_) => return None,
107 PositionRepr::After(it) => it,
108 };
109 ws_between(prev, new)
110}
111fn ws_after(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
112 let next = match &position.repr {
113 PositionRepr::FirstChild(parent) => parent.first_child_or_token()?,
114 PositionRepr::After(sibling) => sibling.next_sibling_or_token()?,
115 };
116 ws_between(new, &next)
117}
118fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken> {
119 if left.kind() == SyntaxKind::WHITESPACE || right.kind() == SyntaxKind::WHITESPACE {
120 return None;
121 }
122 if right.kind() == T![;] || right.kind() == T![,] {
123 return None;
124 }
125 Some(make::tokens::single_space())
126}
diff --git a/xtask/src/metrics.rs b/xtask/src/metrics.rs
index 3d8d7589b..97395738b 100644
--- a/xtask/src/metrics.rs
+++ b/xtask/src/metrics.rs
@@ -26,7 +26,8 @@ impl flags::Metrics {
26 } 26 }
27 { 27 {
28 let _d = pushd("./target/rustc-perf")?; 28 let _d = pushd("./target/rustc-perf")?;
29 cmd!("git reset --hard c52ee623e231e7690a93be88d943016968c1036b").run()?; 29 let revision = &metrics.perf_revision;
30 cmd!("git reset --hard {revision}").run()?;
30 } 31 }
31 32
32 let _env = pushenv("RA_METRICS", "1"); 33 let _env = pushenv("RA_METRICS", "1");
@@ -108,6 +109,7 @@ struct Metrics {
108 host: Host, 109 host: Host,
109 timestamp: SystemTime, 110 timestamp: SystemTime,
110 revision: String, 111 revision: String,
112 perf_revision: String,
111 metrics: BTreeMap<String, (u64, Unit)>, 113 metrics: BTreeMap<String, (u64, Unit)>,
112} 114}
113 115
@@ -123,7 +125,8 @@ impl Metrics {
123 let host = Host::new()?; 125 let host = Host::new()?;
124 let timestamp = SystemTime::now(); 126 let timestamp = SystemTime::now();
125 let revision = cmd!("git rev-parse HEAD").read()?; 127 let revision = cmd!("git rev-parse HEAD").read()?;
126 Ok(Metrics { host, timestamp, revision, metrics: BTreeMap::new() }) 128 let perf_revision = "c52ee623e231e7690a93be88d943016968c1036b".into();
129 Ok(Metrics { host, timestamp, revision, perf_revision, metrics: BTreeMap::new() })
127 } 130 }
128 131
129 fn report(&mut self, name: &str, value: u64, unit: Unit) { 132 fn report(&mut self, name: &str, value: u64, unit: Unit) {
@@ -141,6 +144,7 @@ impl Metrics {
141 let timestamp = self.timestamp.duration_since(UNIX_EPOCH).unwrap(); 144 let timestamp = self.timestamp.duration_since(UNIX_EPOCH).unwrap();
142 obj.number("timestamp", timestamp.as_secs() as f64); 145 obj.number("timestamp", timestamp.as_secs() as f64);
143 obj.string("revision", &self.revision); 146 obj.string("revision", &self.revision);
147 obj.string("perf_revision", &self.perf_revision);
144 let mut metrics = obj.object("metrics"); 148 let mut metrics = obj.object("metrics");
145 for (k, (value, unit)) in &self.metrics { 149 for (k, (value, unit)) in &self.metrics {
146 metrics.array(k).number(*value as f64).string(unit); 150 metrics.array(k).number(*value as f64).string(unit);