aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/base_db/src/fixture.rs12
-rw-r--r--crates/base_db/src/input.rs27
-rw-r--r--crates/hir/src/display.rs467
-rw-r--r--crates/hir/src/lib.rs129
-rw-r--r--crates/hir/src/semantics.rs30
-rw-r--r--crates/hir/src/source_analyzer.rs4
-rw-r--r--crates/hir_def/src/adt.rs10
-rw-r--r--crates/hir_def/src/body/lower.rs105
-rw-r--r--crates/hir_def/src/data.rs22
-rw-r--r--crates/hir_def/src/item_tree.rs24
-rw-r--r--crates/hir_def/src/item_tree/lower.rs35
-rw-r--r--crates/hir_def/src/path.rs11
-rw-r--r--crates/hir_expand/src/db.rs3
-rw-r--r--crates/hir_expand/src/lib.rs5
-rw-r--r--crates/hir_ty/src/autoderef.rs4
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs207
-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/tests/macros.rs16
-rw-r--r--crates/hir_ty/src/traits.rs4
-rw-r--r--crates/hir_ty/src/traits/chalk.rs20
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs15
-rw-r--r--crates/ide/src/call_hierarchy.rs11
-rw-r--r--crates/ide/src/display.rs4
-rw-r--r--crates/ide/src/display/navigation_target.rs44
-rw-r--r--crates/ide/src/display/short_label.rs128
-rw-r--r--crates/ide/src/doc_links.rs2
-rw-r--r--crates/ide/src/extend_selection.rs13
-rw-r--r--crates/ide/src/goto_definition.rs4
-rw-r--r--crates/ide/src/goto_type_definition.rs2
-rw-r--r--crates/ide/src/hover.rs188
-rw-r--r--crates/ide/src/join_lines.rs44
-rw-r--r--crates/ide/src/matching_brace.rs2
-rw-r--r--crates/ide/src/references.rs30
-rw-r--r--crates/ide/src/runnables.rs3
-rw-r--r--crates/ide/src/syntax_highlighting.rs19
-rw-r--r--crates/ide/src/syntax_highlighting/format.rs2
-rw-r--r--crates/ide/src/syntax_tree.rs2
-rw-r--r--crates/ide/src/typing.rs2
-rw-r--r--crates/ide_assists/src/handlers/add_turbo_fish.rs2
-rw-r--r--crates/ide_assists/src/handlers/change_visibility.rs2
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs2
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs20
-rw-r--r--crates/ide_assists/src/handlers/flip_trait_bound.rs2
-rw-r--r--crates/ide_assists/src/handlers/generate_is_empty_from_len.rs35
-rw-r--r--crates/ide_assists/src/handlers/invert_if.rs2
-rw-r--r--crates/ide_assists/src/handlers/move_bounds.rs94
-rw-r--r--crates/ide_assists/src/handlers/split_import.rs2
-rw-r--r--crates/ide_assists/src/handlers/unwrap_block.rs2
-rw-r--r--crates/ide_completion/src/completions/dot.rs24
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs8
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs2
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs56
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs7
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs50
-rw-r--r--crates/ide_completion/src/context.rs21
-rw-r--r--crates/ide_completion/src/lib.rs6
-rw-r--r--crates/ide_completion/src/patterns.rs16
-rw-r--r--crates/ide_completion/src/render.rs230
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs13
-rw-r--r--crates/ide_completion/src/render/function.rs66
-rw-r--r--crates/ide_db/src/call_info.rs2
-rw-r--r--crates/ide_db/src/search.rs2
-rw-r--r--crates/ide_ssr/src/resolving.rs2
-rw-r--r--crates/mbe/src/tests.rs11
-rw-r--r--crates/parser/src/grammar.rs6
-rw-r--r--crates/parser/src/grammar/expressions.rs6
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/algo.rs35
-rw-r--r--crates/syntax/src/ast.rs7
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs139
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs10
-rw-r--r--crates/syntax/src/ast/make.rs14
-rw-r--r--crates/syntax/src/ast/node_ext.rs4
-rw-r--r--crates/syntax/src/lib.rs1
-rw-r--r--crates/syntax/src/parsing/reparsing.rs6
-rw-r--r--crates/syntax/src/ted.rs78
-rw-r--r--crates/test_utils/src/fixture.rs15
87 files changed, 2070 insertions, 843 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index 5c9824814..cad6866aa 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -57,7 +57,7 @@
57//! fn insert_source_code_here() {} 57//! fn insert_source_code_here() {}
58//! " 58//! "
59//! ``` 59//! ```
60use std::{str::FromStr, sync::Arc}; 60use std::{mem, str::FromStr, sync::Arc};
61 61
62use cfg::CfgOptions; 62use cfg::CfgOptions;
63use rustc_hash::FxHashMap; 63use rustc_hash::FxHashMap;
@@ -148,6 +148,7 @@ impl ChangeFixture {
148 let mut file_set = FileSet::default(); 148 let mut file_set = FileSet::default();
149 let source_root_prefix = "/".to_string(); 149 let source_root_prefix = "/".to_string();
150 let mut file_id = FileId(0); 150 let mut file_id = FileId(0);
151 let mut roots = Vec::new();
151 152
152 let mut file_position = None; 153 let mut file_position = None;
153 154
@@ -168,6 +169,10 @@ impl ChangeFixture {
168 let meta = FileMeta::from(entry); 169 let meta = FileMeta::from(entry);
169 assert!(meta.path.starts_with(&source_root_prefix)); 170 assert!(meta.path.starts_with(&source_root_prefix));
170 171
172 if meta.introduce_new_source_root {
173 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
174 }
175
171 if let Some(krate) = meta.krate { 176 if let Some(krate) = meta.krate {
172 let crate_name = CrateName::normalize_dashes(&krate); 177 let crate_name = CrateName::normalize_dashes(&krate);
173 let crate_id = crate_graph.add_crate_root( 178 let crate_id = crate_graph.add_crate_root(
@@ -215,7 +220,8 @@ impl ChangeFixture {
215 } 220 }
216 } 221 }
217 222
218 change.set_roots(vec![SourceRoot::new_local(file_set)]); 223 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
224 change.set_roots(roots);
219 change.set_crate_graph(crate_graph); 225 change.set_crate_graph(crate_graph);
220 226
221 ChangeFixture { file_position, files, change } 227 ChangeFixture { file_position, files, change }
@@ -229,6 +235,7 @@ struct FileMeta {
229 cfg: CfgOptions, 235 cfg: CfgOptions,
230 edition: Edition, 236 edition: Edition,
231 env: Env, 237 env: Env,
238 introduce_new_source_root: bool,
232} 239}
233 240
234impl From<Fixture> for FileMeta { 241impl From<Fixture> for FileMeta {
@@ -247,6 +254,7 @@ impl From<Fixture> for FileMeta {
247 .as_ref() 254 .as_ref()
248 .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()), 255 .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()),
249 env: f.env.into_iter().collect(), 256 env: f.env.into_iter().collect(),
257 introduce_new_source_root: f.introduce_new_source_root,
250 } 258 }
251 } 259 }
252} 260}
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index b5f7e4200..d0def2181 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -274,6 +274,33 @@ impl CrateGraph {
274 deps.into_iter() 274 deps.into_iter()
275 } 275 }
276 276
277 /// Returns an iterator over all transitive reverse dependencies of the given crate.
278 pub fn transitive_reverse_dependencies(
279 &self,
280 of: CrateId,
281 ) -> impl Iterator<Item = CrateId> + '_ {
282 let mut worklist = vec![of];
283 let mut rev_deps = FxHashSet::default();
284 let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
285 self.arena.iter().for_each(|(&krate, data)| {
286 data.dependencies
287 .iter()
288 .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate))
289 });
290
291 while let Some(krate) = worklist.pop() {
292 if let Some(krate_rev_deps) = inverted_graph.get(&krate) {
293 krate_rev_deps
294 .iter()
295 .copied()
296 .filter(|&rev_dep| rev_deps.insert(rev_dep))
297 .for_each(|rev_dep| worklist.push(rev_dep));
298 }
299 }
300
301 rev_deps.into_iter()
302 }
303
277 /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate 304 /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate
278 /// come before the crate itself). 305 /// come before the crate itself).
279 pub fn crates_in_topological_order(&self) -> Vec<CrateId> { 306 pub fn crates_in_topological_order(&self) -> Vec<CrateId> {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
new file mode 100644
index 000000000..9f6d7be48
--- /dev/null
+++ b/crates/hir/src/display.rs
@@ -0,0 +1,467 @@
1//! HirDisplay implementations for various hir types.
2use hir_def::{
3 adt::VariantData,
4 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
5 type_ref::{TypeBound, TypeRef},
6 AdtId, GenericDefId,
7};
8use hir_ty::display::{
9 write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
10 HirFormatter,
11};
12use syntax::ast::{self, NameOwner};
13
14use crate::{
15 Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam,
16 Module, Static, Struct, Substitution, Trait, Type, TypeAlias, TypeParam, Union, Variant,
17};
18
19impl HirDisplay for Function {
20 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
21 let data = f.db.function_data(self.id);
22 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
23 let qual = &data.qualifier;
24 if qual.is_default {
25 write!(f, "default ")?;
26 }
27 if qual.is_const {
28 write!(f, "const ")?;
29 }
30 if qual.is_async {
31 write!(f, "async ")?;
32 }
33 if qual.is_unsafe {
34 write!(f, "unsafe ")?;
35 }
36 if let Some(abi) = &qual.abi {
37 // FIXME: String escape?
38 write!(f, "extern \"{}\" ", abi)?;
39 }
40 write!(f, "fn {}", data.name)?;
41
42 write_generic_params(GenericDefId::FunctionId(self.id), f)?;
43
44 write!(f, "(")?;
45
46 let write_self_param = |ty: &TypeRef, f: &mut HirFormatter| match ty {
47 TypeRef::Path(p) if p.is_self_type() => write!(f, "self"),
48 TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner,TypeRef::Path(p) if p.is_self_type()) =>
49 {
50 write!(f, "&")?;
51 if let Some(lifetime) = lifetime {
52 write!(f, "{} ", lifetime.name)?;
53 }
54 if let hir_def::type_ref::Mutability::Mut = mut_ {
55 write!(f, "mut ")?;
56 }
57 write!(f, "self")
58 }
59 _ => {
60 write!(f, "self: ")?;
61 ty.hir_fmt(f)
62 }
63 };
64
65 let mut first = true;
66 for (param, type_ref) in self.assoc_fn_params(f.db).into_iter().zip(&data.params) {
67 if !first {
68 write!(f, ", ")?;
69 } else {
70 first = false;
71 if data.has_self_param {
72 write_self_param(type_ref, f)?;
73 continue;
74 }
75 }
76 match param.pattern_source(f.db) {
77 Some(ast::Pat::IdentPat(p)) if p.name().is_some() => {
78 write!(f, "{}: ", p.name().unwrap())?
79 }
80 _ => write!(f, "_: ")?,
81 }
82 // FIXME: Use resolved `param.ty` or raw `type_ref`?
83 // The former will ignore lifetime arguments currently.
84 type_ref.hir_fmt(f)?;
85 }
86 write!(f, ")")?;
87
88 // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
89 // Use ugly pattern match to strip the Future trait.
90 // Better way?
91 let ret_type = if !qual.is_async {
92 &data.ret_type
93 } else {
94 match &data.ret_type {
95 TypeRef::ImplTrait(bounds) => match &bounds[0] {
96 TypeBound::Path(path) => {
97 path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings
98 [0]
99 .type_ref
100 .as_ref()
101 .unwrap()
102 }
103 _ => panic!("Async fn ret_type should be impl Future"),
104 },
105 _ => panic!("Async fn ret_type should be impl Future"),
106 }
107 };
108
109 match ret_type {
110 TypeRef::Tuple(tup) if tup.is_empty() => {}
111 ty => {
112 write!(f, " -> ")?;
113 ty.hir_fmt(f)?;
114 }
115 }
116
117 write_where_clause(GenericDefId::FunctionId(self.id), f)?;
118
119 Ok(())
120 }
121}
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
133impl HirDisplay for Struct {
134 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
135 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
136 write!(f, "struct ")?;
137 write!(f, "{}", self.name(f.db))?;
138 let def_id = GenericDefId::AdtId(AdtId::StructId(self.id));
139 write_generic_params(def_id, f)?;
140 write_where_clause(def_id, f)?;
141 Ok(())
142 }
143}
144
145impl HirDisplay for Enum {
146 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
147 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
148 write!(f, "enum ")?;
149 write!(f, "{}", self.name(f.db))?;
150 let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id));
151 write_generic_params(def_id, f)?;
152 write_where_clause(def_id, f)?;
153 Ok(())
154 }
155}
156
157impl HirDisplay for Union {
158 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
159 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
160 write!(f, "union ")?;
161 write!(f, "{}", self.name(f.db))?;
162 let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id));
163 write_generic_params(def_id, f)?;
164 write_where_clause(def_id, f)?;
165 Ok(())
166 }
167}
168
169impl HirDisplay for Field {
170 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
171 write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?;
172 write!(f, "{}: ", self.name(f.db))?;
173 self.signature_ty(f.db).hir_fmt(f)
174 }
175}
176
177impl HirDisplay for Variant {
178 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
179 write!(f, "{}", self.name(f.db))?;
180 let data = self.variant_data(f.db);
181 match &*data {
182 VariantData::Unit => {}
183 VariantData::Tuple(fields) => {
184 write!(f, "(")?;
185 let mut first = true;
186 for (_, field) in fields.iter() {
187 if first {
188 first = false;
189 } else {
190 write!(f, ", ")?;
191 }
192 // Enum variant fields must be pub.
193 field.type_ref.hir_fmt(f)?;
194 }
195 write!(f, ")")?;
196 }
197 VariantData::Record(fields) => {
198 write!(f, " {{")?;
199 let mut first = true;
200 for (_, field) in fields.iter() {
201 if first {
202 first = false;
203 write!(f, " ")?;
204 } else {
205 write!(f, ", ")?;
206 }
207 // Enum variant fields must be pub.
208 write!(f, "{}: ", field.name)?;
209 field.type_ref.hir_fmt(f)?;
210 }
211 write!(f, " }}")?;
212 }
213 }
214 Ok(())
215 }
216}
217
218impl HirDisplay for Type {
219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
220 self.ty.value.hir_fmt(f)
221 }
222}
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
234impl HirDisplay for TypeParam {
235 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
236 write!(f, "{}", self.name(f.db))?;
237 let bounds = f.db.generic_predicates_for_param(self.id);
238 let substs = Substitution::type_params(f.db, self.id.parent);
239 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
240 if !(predicates.is_empty() || f.omit_verbose_types()) {
241 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
242 }
243 Ok(())
244 }
245}
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
253impl HirDisplay for ConstParam {
254 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
255 write!(f, "const {}: ", self.name(f.db))?;
256 self.ty(f.db).hir_fmt(f)
257 }
258}
259
260fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
261 let params = f.db.generic_params(def);
262 if params.lifetimes.is_empty()
263 && params.consts.is_empty()
264 && params
265 .types
266 .iter()
267 .all(|(_, param)| !matches!(param.provenance, TypeParamProvenance::TypeParamList))
268 {
269 return Ok(());
270 }
271 write!(f, "<")?;
272
273 let mut first = true;
274 let mut delim = |f: &mut HirFormatter| {
275 if first {
276 first = false;
277 Ok(())
278 } else {
279 write!(f, ", ")
280 }
281 };
282 for (_, lifetime) in params.lifetimes.iter() {
283 delim(f)?;
284 write!(f, "{}", lifetime.name)?;
285 }
286 for (_, ty) in params.types.iter() {
287 if ty.provenance != TypeParamProvenance::TypeParamList {
288 continue;
289 }
290 if let Some(name) = &ty.name {
291 delim(f)?;
292 write!(f, "{}", name)?;
293 if let Some(default) = &ty.default {
294 write!(f, " = ")?;
295 default.hir_fmt(f)?;
296 }
297 }
298 }
299 for (_, konst) in params.consts.iter() {
300 delim(f)?;
301 write!(f, "const {}: ", konst.name)?;
302 konst.ty.hir_fmt(f)?;
303 }
304
305 write!(f, ">")?;
306 Ok(())
307}
308
309fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
310 let params = f.db.generic_params(def);
311 if params.where_predicates.is_empty() {
312 return Ok(());
313 }
314
315 let write_target = |target: &WherePredicateTypeTarget, f: &mut HirFormatter| match target {
316 WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f),
317 WherePredicateTypeTarget::TypeParam(id) => match &params.types[*id].name {
318 Some(name) => write!(f, "{}", name),
319 None => write!(f, "{{unnamed}}"),
320 },
321 };
322
323 write!(f, "\nwhere")?;
324
325 for (pred_idx, pred) in params.where_predicates.iter().enumerate() {
326 let prev_pred =
327 if pred_idx == 0 { None } else { Some(&params.where_predicates[pred_idx - 1]) };
328
329 let new_predicate = |f: &mut HirFormatter| {
330 write!(f, "{}", if pred_idx == 0 { "\n " } else { ",\n " })
331 };
332
333 match pred {
334 WherePredicate::TypeBound { target, bound } => {
335 if matches!(prev_pred, Some(WherePredicate::TypeBound { target: target_, .. }) if target_ == target)
336 {
337 write!(f, " + ")?;
338 } else {
339 new_predicate(f)?;
340 write_target(target, f)?;
341 write!(f, ": ")?;
342 }
343 bound.hir_fmt(f)?;
344 }
345 WherePredicate::Lifetime { target, bound } => {
346 if matches!(prev_pred, Some(WherePredicate::Lifetime { target: target_, .. }) if target_ == target)
347 {
348 write!(f, " + {}", bound.name)?;
349 } else {
350 new_predicate(f)?;
351 write!(f, "{}: {}", target.name, bound.name)?;
352 }
353 }
354 WherePredicate::ForLifetime { lifetimes, target, bound } => {
355 if matches!(
356 prev_pred,
357 Some(WherePredicate::ForLifetime { lifetimes: lifetimes_, target: target_, .. })
358 if lifetimes_ == lifetimes && target_ == target,
359 ) {
360 write!(f, " + ")?;
361 } else {
362 new_predicate(f)?;
363 write!(f, "for<")?;
364 for (idx, lifetime) in lifetimes.iter().enumerate() {
365 if idx != 0 {
366 write!(f, ", ")?;
367 }
368 write!(f, "{}", lifetime)?;
369 }
370 write!(f, "> ")?;
371 write_target(target, f)?;
372 write!(f, ": ")?;
373 }
374 bound.hir_fmt(f)?;
375 }
376 }
377 }
378
379 // End of final predicate. There must be at least one predicate here.
380 write!(f, ",")?;
381
382 Ok(())
383}
384
385impl HirDisplay for Const {
386 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
387 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
388 let data = f.db.const_data(self.id);
389 write!(f, "const ")?;
390 match &data.name {
391 Some(name) => write!(f, "{}: ", name)?,
392 None => write!(f, "_: ")?,
393 }
394 data.type_ref.hir_fmt(f)?;
395 Ok(())
396 }
397}
398
399impl HirDisplay for Static {
400 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
401 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
402 let data = f.db.static_data(self.id);
403 write!(f, "static ")?;
404 if data.mutable {
405 write!(f, "mut ")?;
406 }
407 match &data.name {
408 Some(name) => write!(f, "{}: ", name)?,
409 None => write!(f, "_: ")?,
410 }
411 data.type_ref.hir_fmt(f)?;
412 Ok(())
413 }
414}
415
416impl HirDisplay for Trait {
417 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
418 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
419 let data = f.db.trait_data(self.id);
420 if data.is_unsafe {
421 write!(f, "unsafe ")?;
422 }
423 if data.is_auto {
424 write!(f, "auto ")?;
425 }
426 write!(f, "trait {}", data.name)?;
427 let def_id = GenericDefId::TraitId(self.id);
428 write_generic_params(def_id, f)?;
429 if !data.bounds.is_empty() {
430 write!(f, ": ")?;
431 f.write_joined(&*data.bounds, " + ")?;
432 }
433 write_where_clause(def_id, f)?;
434 Ok(())
435 }
436}
437
438impl HirDisplay for TypeAlias {
439 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
440 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
441 let data = f.db.type_alias_data(self.id);
442 write!(f, "type {}", data.name)?;
443 if !data.bounds.is_empty() {
444 write!(f, ": ")?;
445 f.write_joined(&data.bounds, " + ")?;
446 }
447 if let Some(ty) = &data.type_ref {
448 write!(f, " = ")?;
449 ty.hir_fmt(f)?;
450 }
451 Ok(())
452 }
453}
454
455impl HirDisplay for Module {
456 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
457 // FIXME: Module doesn't have visibility saved in data.
458 match self.name(f.db) {
459 Some(name) => write!(f, "mod {}", name),
460 None if self.crate_root(f.db) == *self => match self.krate().display_name(f.db) {
461 Some(name) => write!(f, "extern crate {}", name),
462 None => write!(f, "extern crate {{unknown}}"),
463 },
464 None => write!(f, "mod {{unnamed}}"),
465 }
466 }
467}
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index c5161dadd..12dd5fb38 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -29,6 +29,8 @@ mod has_source;
29pub mod diagnostics; 29pub mod diagnostics;
30pub mod db; 30pub mod db;
31 31
32mod display;
33
32use std::{iter, sync::Arc}; 34use std::{iter, sync::Arc};
33 35
34use arrayvec::ArrayVec; 36use arrayvec::ArrayVec;
@@ -50,14 +52,15 @@ use hir_def::{
50use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; 52use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
51use hir_ty::{ 53use hir_ty::{
52 autoderef, 54 autoderef,
53 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
54 method_resolution::{self, TyFingerprint}, 55 method_resolution::{self, TyFingerprint},
56 primitive::UintTy,
55 to_assoc_type_id, 57 to_assoc_type_id,
56 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
57 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 59 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
58 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, 60 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution,
59 TyDefId, TyKind, TyVariableKind, 61 Ty, TyDefId, TyKind, TyVariableKind,
60}; 62};
63use itertools::Itertools;
61use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
62use stdx::{format_to, impl_from}; 65use stdx::{format_to, impl_from};
63use syntax::{ 66use syntax::{
@@ -139,7 +142,6 @@ impl Crate {
139 .collect() 142 .collect()
140 } 143 }
141 144
142 // FIXME: add `transitive_reverse_dependencies`.
143 pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { 145 pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
144 let crate_graph = db.crate_graph(); 146 let crate_graph = db.crate_graph();
145 crate_graph 147 crate_graph
@@ -151,6 +153,14 @@ impl Crate {
151 .collect() 153 .collect()
152 } 154 }
153 155
156 pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
157 db.crate_graph()
158 .transitive_reverse_dependencies(self.id)
159 .into_iter()
160 .map(|id| Crate { id })
161 .collect()
162 }
163
154 pub fn root_module(self, db: &dyn HirDatabase) -> Module { 164 pub fn root_module(self, db: &dyn HirDatabase) -> Module {
155 let def_map = db.crate_def_map(self.id); 165 let def_map = db.crate_def_map(self.id);
156 Module { id: def_map.module_id(def_map.root()) } 166 Module { id: def_map.module_id(def_map.root()) }
@@ -508,7 +518,7 @@ impl Field {
508 VariantDef::Union(it) => it.id.into(), 518 VariantDef::Union(it) => it.id.into(),
509 VariantDef::Variant(it) => it.parent.id.into(), 519 VariantDef::Variant(it) => it.parent.id.into(),
510 }; 520 };
511 let substs = Substs::type_params(db, generic_def_id); 521 let substs = Substitution::type_params(db, generic_def_id);
512 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);
513 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)
514 } 524 }
@@ -571,6 +581,12 @@ impl Struct {
571 } 581 }
572} 582}
573 583
584impl HasVisibility for Struct {
585 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
586 db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
587 }
588}
589
574#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 590#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
575pub struct Union { 591pub struct Union {
576 pub(crate) id: UnionId, 592 pub(crate) id: UnionId,
@@ -603,6 +619,12 @@ impl Union {
603 } 619 }
604} 620}
605 621
622impl HasVisibility for Union {
623 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
624 db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
625 }
626}
627
606#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 628#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
607pub struct Enum { 629pub struct Enum {
608 pub(crate) id: EnumId, 630 pub(crate) id: EnumId,
@@ -630,6 +652,12 @@ impl Enum {
630 } 652 }
631} 653}
632 654
655impl HasVisibility for Enum {
656 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
657 db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
658 }
659}
660
633#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 661#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
634pub struct Variant { 662pub struct Variant {
635 pub(crate) parent: Enum, 663 pub(crate) parent: Enum,
@@ -821,7 +849,8 @@ impl Function {
821 db.function_data(self.id) 849 db.function_data(self.id)
822 .params 850 .params
823 .iter() 851 .iter()
824 .map(|type_ref| { 852 .enumerate()
853 .map(|(idx, type_ref)| {
825 let ty = Type { 854 let ty = Type {
826 krate, 855 krate,
827 ty: InEnvironment { 856 ty: InEnvironment {
@@ -829,7 +858,7 @@ impl Function {
829 environment: environment.clone(), 858 environment: environment.clone(),
830 }, 859 },
831 }; 860 };
832 Param { ty } 861 Param { func: self, ty, idx }
833 }) 862 })
834 .collect() 863 .collect()
835 } 864 }
@@ -843,7 +872,7 @@ impl Function {
843 } 872 }
844 873
845 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { 874 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
846 db.function_data(self.id).is_unsafe 875 db.function_data(self.id).qualifier.is_unsafe
847 } 876 }
848 877
849 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 878 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
@@ -892,6 +921,9 @@ impl From<hir_ty::Mutability> for Access {
892 921
893#[derive(Debug)] 922#[derive(Debug)]
894pub struct Param { 923pub struct Param {
924 func: Function,
925 /// The index in parameter list, including self parameter.
926 idx: usize,
895 ty: Type, 927 ty: Type,
896} 928}
897 929
@@ -899,6 +931,15 @@ impl Param {
899 pub fn ty(&self) -> &Type { 931 pub fn ty(&self) -> &Type {
900 &self.ty 932 &self.ty
901 } 933 }
934
935 pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
936 let params = self.func.source(db)?.value.param_list()?;
937 if params.self_param().is_some() {
938 params.params().nth(self.idx.checked_sub(1)?)?.pat()
939 } else {
940 params.params().nth(self.idx)?.pat()
941 }
942 }
902} 943}
903 944
904#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 945#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -921,6 +962,14 @@ impl SelfParam {
921 }) 962 })
922 .unwrap_or(Access::Owned) 963 .unwrap_or(Access::Owned)
923 } 964 }
965
966 pub fn display(self, db: &dyn HirDatabase) -> &'static str {
967 match self.access(db) {
968 Access::Shared => "&self",
969 Access::Exclusive => "&mut self",
970 Access::Owned => "self",
971 }
972 }
924} 973}
925 974
926impl HasVisibility for Function { 975impl HasVisibility for Function {
@@ -948,6 +997,10 @@ impl Const {
948 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 997 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
949 db.const_data(self.id).name.clone() 998 db.const_data(self.id).name.clone()
950 } 999 }
1000
1001 pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
1002 db.const_data(self.id).type_ref.clone()
1003 }
951} 1004}
952 1005
953impl HasVisibility for Const { 1006impl HasVisibility for Const {
@@ -981,6 +1034,12 @@ impl Static {
981 } 1034 }
982} 1035}
983 1036
1037impl HasVisibility for Static {
1038 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1039 db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1040 }
1041}
1042
984#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1043#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
985pub struct Trait { 1044pub struct Trait {
986 pub(crate) id: TraitId, 1045 pub(crate) id: TraitId,
@@ -1000,7 +1059,13 @@ impl Trait {
1000 } 1059 }
1001 1060
1002 pub fn is_auto(self, db: &dyn HirDatabase) -> bool { 1061 pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
1003 db.trait_data(self.id).auto 1062 db.trait_data(self.id).is_auto
1063 }
1064}
1065
1066impl HasVisibility for Trait {
1067 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1068 db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1004 } 1069 }
1005} 1070}
1006 1071
@@ -1406,25 +1471,12 @@ impl TypeParam {
1406 let resolver = self.id.parent.resolver(db.upcast()); 1471 let resolver = self.id.parent.resolver(db.upcast());
1407 let krate = self.id.parent.module(db.upcast()).krate(); 1472 let krate = self.id.parent.module(db.upcast()).krate();
1408 let ty = params.get(local_idx)?.clone(); 1473 let ty = params.get(local_idx)?.clone();
1409 let subst = Substs::type_params(db, self.id.parent); 1474 let subst = Substitution::type_params(db, self.id.parent);
1410 let ty = ty.subst(&subst.prefix(local_idx)); 1475 let ty = ty.subst(&subst.prefix(local_idx));
1411 Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) 1476 Some(Type::new_with_resolver_inner(db, krate, &resolver, ty))
1412 } 1477 }
1413} 1478}
1414 1479
1415impl HirDisplay for TypeParam {
1416 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1417 write!(f, "{}", self.name(f.db))?;
1418 let bounds = f.db.generic_predicates_for_param(self.id);
1419 let substs = Substs::type_params(f.db, self.id.parent);
1420 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
1421 if !(predicates.is_empty() || f.omit_verbose_types()) {
1422 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
1423 }
1424 Ok(())
1425 }
1426}
1427
1428#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1480#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1429pub struct LifetimeParam { 1481pub struct LifetimeParam {
1430 pub(crate) id: LifetimeParamId, 1482 pub(crate) id: LifetimeParamId,
@@ -1497,11 +1549,17 @@ impl Impl {
1497 }; 1549 };
1498 1550
1499 let mut all = Vec::new(); 1551 let mut all = Vec::new();
1500 def_crates.into_iter().for_each(|id| { 1552 def_crates.iter().for_each(|&id| {
1501 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) 1553 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1502 }); 1554 });
1503 let fp = TyFingerprint::for_impl(&ty.value); 1555 let fp = TyFingerprint::for_impl(&ty.value);
1504 for id in db.crate_graph().iter() { 1556 for id in def_crates
1557 .iter()
1558 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
1559 .map(|Crate { id }| id)
1560 .chain(def_crates.iter().copied())
1561 .unique()
1562 {
1505 match fp { 1563 match fp {
1506 Some(fp) => all.extend( 1564 Some(fp) => all.extend(
1507 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), 1565 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
@@ -1516,7 +1574,8 @@ impl Impl {
1516 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { 1574 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
1517 let krate = trait_.module(db).krate(); 1575 let krate = trait_.module(db).krate();
1518 let mut all = Vec::new(); 1576 let mut all = Vec::new();
1519 for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) { 1577 for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter().chain(Some(krate))
1578 {
1520 let impls = db.trait_impls_in_crate(id); 1579 let impls = db.trait_impls_in_crate(id);
1521 all.extend(impls.for_trait(trait_.id).map(Self::from)) 1580 all.extend(impls.for_trait(trait_.id).map(Self::from))
1522 } 1581 }
@@ -1615,7 +1674,7 @@ impl Type {
1615 krate: CrateId, 1674 krate: CrateId,
1616 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, 1675 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>,
1617 ) -> Type { 1676 ) -> Type {
1618 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();
1619 let ty = db.ty(def.into()).subst(&substs); 1678 let ty = db.ty(def.into()).subst(&substs);
1620 Type::new(db, krate, def, ty) 1679 Type::new(db, krate, def, ty)
1621 } 1680 }
@@ -1631,6 +1690,10 @@ impl Type {
1631 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) 1690 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1632 } 1691 }
1633 1692
1693 pub fn is_usize(&self) -> bool {
1694 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1695 }
1696
1634 pub fn remove_ref(&self) -> Option<Type> { 1697 pub fn remove_ref(&self) -> Option<Type> {
1635 match &self.ty.value.interned(&Interner) { 1698 match &self.ty.value.interned(&Interner) {
1636 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), 1699 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
@@ -1691,7 +1754,7 @@ impl Type {
1691 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 {
1692 let trait_ref = hir_ty::TraitRef { 1755 let trait_ref = hir_ty::TraitRef {
1693 trait_: trait_.id, 1756 trait_: trait_.id,
1694 substs: Substs::build_for_def(db, trait_.id) 1757 substs: Substitution::build_for_def(db, trait_.id)
1695 .push(self.ty.value.clone()) 1758 .push(self.ty.value.clone())
1696 .fill(args.iter().map(|t| t.ty.value.clone())) 1759 .fill(args.iter().map(|t| t.ty.value.clone()))
1697 .build(), 1760 .build(),
@@ -1715,7 +1778,7 @@ impl Type {
1715 args: &[Type], 1778 args: &[Type],
1716 alias: TypeAlias, 1779 alias: TypeAlias,
1717 ) -> Option<Type> { 1780 ) -> Option<Type> {
1718 let subst = Substs::build_for_def(db, trait_.id) 1781 let subst = Substitution::build_for_def(db, trait_.id)
1719 .push(self.ty.value.clone()) 1782 .push(self.ty.value.clone())
1720 .fill(args.iter().map(|t| t.ty.value.clone())) 1783 .fill(args.iter().map(|t| t.ty.value.clone()))
1721 .build(); 1784 .build();
@@ -1982,7 +2045,7 @@ impl Type {
1982 fn walk_substs( 2045 fn walk_substs(
1983 db: &dyn HirDatabase, 2046 db: &dyn HirDatabase,
1984 type_: &Type, 2047 type_: &Type,
1985 substs: &Substs, 2048 substs: &Substitution,
1986 cb: &mut impl FnMut(Type), 2049 cb: &mut impl FnMut(Type),
1987 ) { 2050 ) {
1988 for ty in substs.iter() { 2051 for ty in substs.iter() {
@@ -2054,12 +2117,6 @@ impl Type {
2054 } 2117 }
2055} 2118}
2056 2119
2057impl HirDisplay for Type {
2058 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
2059 self.ty.value.hir_fmt(f)
2060 }
2061}
2062
2063// FIXME: closures 2120// FIXME: closures
2064#[derive(Debug)] 2121#[derive(Debug)]
2065pub struct Callable { 2122pub struct Callable {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 519339c0c..03c9371b5 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -143,6 +143,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
143 self.imp.diagnostics_display_range(diagnostics) 143 self.imp.diagnostics_display_range(diagnostics)
144 } 144 }
145 145
146 pub fn token_ancestors_with_macros(
147 &self,
148 token: SyntaxToken,
149 ) -> impl Iterator<Item = SyntaxNode> + '_ {
150 token.parent().into_iter().flat_map(move |it| self.ancestors_with_macros(it))
151 }
146 pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { 152 pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
147 self.imp.ancestors_with_macros(node) 153 self.imp.ancestors_with_macros(node)
148 } 154 }
@@ -270,8 +276,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
270 self.imp.scope(node) 276 self.imp.scope(node)
271 } 277 }
272 278
273 pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> { 279 pub fn scope_at_offset(&self, token: &SyntaxToken, offset: TextSize) -> SemanticsScope<'db> {
274 self.imp.scope_at_offset(node, offset) 280 self.imp.scope_at_offset(&token.parent().unwrap(), offset)
275 } 281 }
276 282
277 pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> { 283 pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
@@ -341,7 +347,10 @@ impl<'db> SemanticsImpl<'db> {
341 347
342 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { 348 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
343 let _p = profile::span("descend_into_macros"); 349 let _p = profile::span("descend_into_macros");
344 let parent = token.parent(); 350 let parent = match token.parent() {
351 Some(it) => it,
352 None => return token,
353 };
345 let sa = self.analyze(&parent); 354 let sa = self.analyze(&parent);
346 355
347 let token = successors(Some(InFile::new(sa.file_id, token)), |token| { 356 let token = successors(Some(InFile::new(sa.file_id, token)), |token| {
@@ -360,7 +369,9 @@ impl<'db> SemanticsImpl<'db> {
360 .as_ref()? 369 .as_ref()?
361 .map_token_down(token.as_ref())?; 370 .map_token_down(token.as_ref())?;
362 371
363 self.cache(find_root(&token.value.parent()), token.file_id); 372 if let Some(parent) = token.value.parent() {
373 self.cache(find_root(&parent), token.file_id);
374 }
364 375
365 Some(token) 376 Some(token)
366 }) 377 })
@@ -378,7 +389,7 @@ impl<'db> SemanticsImpl<'db> {
378 // Handle macro token cases 389 // Handle macro token cases
379 node.token_at_offset(offset) 390 node.token_at_offset(offset)
380 .map(|token| self.descend_into_macros(token)) 391 .map(|token| self.descend_into_macros(token))
381 .map(|it| self.ancestors_with_macros(it.parent())) 392 .map(|it| self.token_ancestors_with_macros(it))
382 .flatten() 393 .flatten()
383 } 394 }
384 395
@@ -394,6 +405,13 @@ impl<'db> SemanticsImpl<'db> {
394 src.with_value(&node).original_file_range(self.db.upcast()) 405 src.with_value(&node).original_file_range(self.db.upcast())
395 } 406 }
396 407
408 fn token_ancestors_with_macros(
409 &self,
410 token: SyntaxToken,
411 ) -> impl Iterator<Item = SyntaxNode> + '_ {
412 token.parent().into_iter().flat_map(move |parent| self.ancestors_with_macros(parent))
413 }
414
397 fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { 415 fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
398 let node = self.find_file(node); 416 let node = self.find_file(node);
399 node.ancestors_with_macros(self.db.upcast()).map(|it| it.value) 417 node.ancestors_with_macros(self.db.upcast()).map(|it| it.value)
@@ -405,7 +423,7 @@ impl<'db> SemanticsImpl<'db> {
405 offset: TextSize, 423 offset: TextSize,
406 ) -> impl Iterator<Item = SyntaxNode> + '_ { 424 ) -> impl Iterator<Item = SyntaxNode> + '_ {
407 node.token_at_offset(offset) 425 node.token_at_offset(offset)
408 .map(|token| self.ancestors_with_macros(token.parent())) 426 .map(|token| self.token_ancestors_with_macros(token))
409 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) 427 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
410 } 428 }
411 429
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 4d59293e9..117f32a9e 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)> {
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs
index efbde17d8..1b9bb8235 100644
--- a/crates/hir_def/src/adt.rs
+++ b/crates/hir_def/src/adt.rs
@@ -31,12 +31,14 @@ pub struct StructData {
31 pub name: Name, 31 pub name: Name,
32 pub variant_data: Arc<VariantData>, 32 pub variant_data: Arc<VariantData>,
33 pub repr: Option<ReprKind>, 33 pub repr: Option<ReprKind>,
34 pub visibility: RawVisibility,
34} 35}
35 36
36#[derive(Debug, Clone, PartialEq, Eq)] 37#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct EnumData { 38pub struct EnumData {
38 pub name: Name, 39 pub name: Name,
39 pub variants: Arena<EnumVariantData>, 40 pub variants: Arena<EnumVariantData>,
41 pub visibility: RawVisibility,
40} 42}
41 43
42#[derive(Debug, Clone, PartialEq, Eq)] 44#[derive(Debug, Clone, PartialEq, Eq)]
@@ -102,6 +104,7 @@ impl StructData {
102 name: strukt.name.clone(), 104 name: strukt.name.clone(),
103 variant_data: Arc::new(variant_data), 105 variant_data: Arc::new(variant_data),
104 repr, 106 repr,
107 visibility: item_tree[strukt.visibility].clone(),
105 }) 108 })
106 } 109 }
107 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { 110 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
@@ -118,6 +121,7 @@ impl StructData {
118 name: union.name.clone(), 121 name: union.name.clone(),
119 variant_data: Arc::new(variant_data), 122 variant_data: Arc::new(variant_data),
120 repr, 123 repr,
124 visibility: item_tree[union.visibility].clone(),
121 }) 125 })
122 } 126 }
123} 127}
@@ -150,7 +154,11 @@ impl EnumData {
150 } 154 }
151 } 155 }
152 156
153 Arc::new(EnumData { name: enum_.name.clone(), variants }) 157 Arc::new(EnumData {
158 name: enum_.name.clone(),
159 variants,
160 visibility: item_tree[enum_.visibility].clone(),
161 })
154 } 162 }
155 163
156 pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> { 164 pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> {
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 8934ae6c9..7052058f2 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -519,7 +519,7 @@ impl ExprCollector<'_> {
519 } 519 }
520 ast::Expr::MacroCall(e) => { 520 ast::Expr::MacroCall(e) => {
521 let mut ids = vec![]; 521 let mut ids = vec![];
522 self.collect_macro_call(e, syntax_ptr.clone(), |this, expansion| { 522 self.collect_macro_call(e, syntax_ptr.clone(), true, |this, expansion| {
523 ids.push(match expansion { 523 ids.push(match expansion {
524 Some(it) => this.collect_expr(it), 524 Some(it) => this.collect_expr(it),
525 None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), 525 None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
@@ -527,6 +527,17 @@ impl ExprCollector<'_> {
527 }); 527 });
528 ids[0] 528 ids[0]
529 } 529 }
530 ast::Expr::MacroStmts(e) => {
531 // FIXME: these statements should be held by some hir containter
532 for stmt in e.statements() {
533 self.collect_stmt(stmt);
534 }
535 if let Some(expr) = e.expr() {
536 self.collect_expr(expr)
537 } else {
538 self.alloc_expr(Expr::Missing, syntax_ptr)
539 }
540 }
530 } 541 }
531 } 542 }
532 543
@@ -534,6 +545,7 @@ impl ExprCollector<'_> {
534 &mut self, 545 &mut self,
535 e: ast::MacroCall, 546 e: ast::MacroCall,
536 syntax_ptr: AstPtr<ast::Expr>, 547 syntax_ptr: AstPtr<ast::Expr>,
548 is_error_recoverable: bool,
537 mut collector: F, 549 mut collector: F,
538 ) { 550 ) {
539 // File containing the macro call. Expansion errors will be attached here. 551 // File containing the macro call. Expansion errors will be attached here.
@@ -567,7 +579,7 @@ impl ExprCollector<'_> {
567 Some((mark, expansion)) => { 579 Some((mark, expansion)) => {
568 // FIXME: Statements are too complicated to recover from error for now. 580 // FIXME: Statements are too complicated to recover from error for now.
569 // It is because we don't have any hygiene for local variable expansion right now. 581 // It is because we don't have any hygiene for local variable expansion right now.
570 if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { 582 if !is_error_recoverable && res.err.is_some() {
571 self.expander.exit(self.db, mark); 583 self.expander.exit(self.db, mark);
572 collector(self, None); 584 collector(self, None);
573 } else { 585 } else {
@@ -591,56 +603,55 @@ impl ExprCollector<'_> {
591 } 603 }
592 604
593 fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Vec<Statement>> { 605 fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Vec<Statement>> {
594 let stmt = 606 let stmt = match s {
595 match s { 607 ast::Stmt::LetStmt(stmt) => {
596 ast::Stmt::LetStmt(stmt) => { 608 self.check_cfg(&stmt)?;
597 self.check_cfg(&stmt)?; 609
598 610 let pat = self.collect_pat_opt(stmt.pat());
599 let pat = self.collect_pat_opt(stmt.pat()); 611 let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it));
600 let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); 612 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
601 let initializer = stmt.initializer().map(|e| self.collect_expr(e)); 613 vec![Statement::Let { pat, type_ref, initializer }]
602 vec![Statement::Let { pat, type_ref, initializer }] 614 }
603 } 615 ast::Stmt::ExprStmt(stmt) => {
604 ast::Stmt::ExprStmt(stmt) => { 616 self.check_cfg(&stmt)?;
605 self.check_cfg(&stmt)?; 617
606 618 // Note that macro could be expended to multiple statements
607 // Note that macro could be expended to multiple statements 619 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() {
608 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { 620 let syntax_ptr = AstPtr::new(&stmt.expr().unwrap());
609 let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); 621 let mut stmts = vec![];
610 let mut stmts = vec![]; 622
611 623 self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| {
612 self.collect_macro_call(m, syntax_ptr.clone(), |this, expansion| { 624 match expansion {
613 match expansion { 625 Some(expansion) => {
614 Some(expansion) => { 626 let statements: ast::MacroStmts = expansion;
615 let statements: ast::MacroStmts = expansion; 627
616 628 statements.statements().for_each(|stmt| {
617 statements.statements().for_each(|stmt| { 629 if let Some(mut r) = this.collect_stmt(stmt) {
618 if let Some(mut r) = this.collect_stmt(stmt) { 630 stmts.append(&mut r);
619 stmts.append(&mut r);
620 }
621 });
622 if let Some(expr) = statements.expr() {
623 stmts.push(Statement::Expr(this.collect_expr(expr)));
624 } 631 }
625 } 632 });
626 None => { 633 if let Some(expr) = statements.expr() {
627 stmts.push(Statement::Expr( 634 stmts.push(Statement::Expr(this.collect_expr(expr)));
628 this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
629 ));
630 } 635 }
631 } 636 }
632 }); 637 None => {
633 stmts 638 stmts.push(Statement::Expr(
634 } else { 639 this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
635 vec![Statement::Expr(self.collect_expr_opt(stmt.expr()))] 640 ));
636 } 641 }
642 }
643 });
644 stmts
645 } else {
646 vec![Statement::Expr(self.collect_expr_opt(stmt.expr()))]
637 } 647 }
638 ast::Stmt::Item(item) => { 648 }
639 self.check_cfg(&item)?; 649 ast::Stmt::Item(item) => {
650 self.check_cfg(&item)?;
640 651
641 return None; 652 return None;
642 } 653 }
643 }; 654 };
644 655
645 Some(stmt) 656 Some(stmt)
646 } 657 }
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index aea53d527..74a2194e5 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -9,7 +9,7 @@ use crate::{
9 attr::Attrs, 9 attr::Attrs,
10 body::Expander, 10 body::Expander,
11 db::DefDatabase, 11 db::DefDatabase,
12 item_tree::{AssocItem, ItemTreeId, ModItem}, 12 item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem},
13 type_ref::{TypeBound, TypeRef}, 13 type_ref::{TypeBound, TypeRef},
14 visibility::RawVisibility, 14 visibility::RawVisibility,
15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, 15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -26,9 +26,9 @@ pub struct FunctionData {
26 /// can be called as a method. 26 /// can be called as a method.
27 pub has_self_param: bool, 27 pub has_self_param: bool,
28 pub has_body: bool, 28 pub has_body: bool,
29 pub is_unsafe: bool, 29 pub qualifier: FunctionQualifier,
30 pub is_in_extern_block: bool,
30 pub is_varargs: bool, 31 pub is_varargs: bool,
31 pub is_extern: bool,
32 pub visibility: RawVisibility, 32 pub visibility: RawVisibility,
33} 33}
34 34
@@ -46,9 +46,9 @@ impl FunctionData {
46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), 46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
47 has_self_param: func.has_self_param, 47 has_self_param: func.has_self_param,
48 has_body: func.has_body, 48 has_body: func.has_body,
49 is_unsafe: func.is_unsafe, 49 qualifier: func.qualifier.clone(),
50 is_in_extern_block: func.is_in_extern_block,
50 is_varargs: func.is_varargs, 51 is_varargs: func.is_varargs,
51 is_extern: func.is_extern,
52 visibility: item_tree[func.visibility].clone(), 52 visibility: item_tree[func.visibility].clone(),
53 }) 53 })
54 } 54 }
@@ -87,7 +87,10 @@ impl TypeAliasData {
87pub struct TraitData { 87pub struct TraitData {
88 pub name: Name, 88 pub name: Name,
89 pub items: Vec<(Name, AssocItemId)>, 89 pub items: Vec<(Name, AssocItemId)>,
90 pub auto: bool, 90 pub is_auto: bool,
91 pub is_unsafe: bool,
92 pub visibility: RawVisibility,
93 pub bounds: Box<[TypeBound]>,
91} 94}
92 95
93impl TraitData { 96impl TraitData {
@@ -96,10 +99,13 @@ impl TraitData {
96 let item_tree = db.item_tree(tr_loc.id.file_id); 99 let item_tree = db.item_tree(tr_loc.id.file_id);
97 let tr_def = &item_tree[tr_loc.id.value]; 100 let tr_def = &item_tree[tr_loc.id.value];
98 let name = tr_def.name.clone(); 101 let name = tr_def.name.clone();
99 let auto = tr_def.auto; 102 let is_auto = tr_def.is_auto;
103 let is_unsafe = tr_def.is_unsafe;
100 let module_id = tr_loc.container; 104 let module_id = tr_loc.container;
101 let container = AssocContainerId::TraitId(tr); 105 let container = AssocContainerId::TraitId(tr);
102 let mut expander = Expander::new(db, tr_loc.id.file_id, module_id); 106 let mut expander = Expander::new(db, tr_loc.id.file_id, module_id);
107 let visibility = item_tree[tr_def.visibility].clone();
108 let bounds = tr_def.bounds.clone();
103 109
104 let items = collect_items( 110 let items = collect_items(
105 db, 111 db,
@@ -111,7 +117,7 @@ impl TraitData {
111 100, 117 100,
112 ); 118 );
113 119
114 Arc::new(TraitData { name, items, auto }) 120 Arc::new(TraitData { name, items, is_auto, is_unsafe, visibility, bounds })
115 } 121 }
116 122
117 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ { 123 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 09bcb10dc..7bb22c4c4 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -24,7 +24,7 @@ use la_arena::{Arena, Idx, RawIdx};
24use profile::Count; 24use profile::Count;
25use rustc_hash::FxHashMap; 25use rustc_hash::FxHashMap;
26use smallvec::SmallVec; 26use smallvec::SmallVec;
27use syntax::{ast, match_ast, SyntaxKind}; 27use syntax::{ast, match_ast, SmolStr, SyntaxKind};
28 28
29use crate::{ 29use crate::{
30 attr::{Attrs, RawAttrs}, 30 attr::{Attrs, RawAttrs},
@@ -110,6 +110,11 @@ impl ItemTree {
110 // still need to collect inner items. 110 // still need to collect inner items.
111 ctx.lower_inner_items(e.syntax()) 111 ctx.lower_inner_items(e.syntax())
112 }, 112 },
113 ast::ExprStmt(stmt) => {
114 // Macros can expand to stmt. We return an empty item tree in this case, but
115 // still need to collect inner items.
116 ctx.lower_inner_items(stmt.syntax())
117 },
113 _ => { 118 _ => {
114 panic!("cannot create item tree from {:?} {}", syntax, syntax); 119 panic!("cannot create item tree from {:?} {}", syntax, syntax);
115 }, 120 },
@@ -551,16 +556,25 @@ pub struct Function {
551 pub generic_params: GenericParamsId, 556 pub generic_params: GenericParamsId,
552 pub has_self_param: bool, 557 pub has_self_param: bool,
553 pub has_body: bool, 558 pub has_body: bool,
554 pub is_unsafe: bool, 559 pub qualifier: FunctionQualifier,
555 /// Whether the function is located in an `extern` block (*not* whether it is an 560 /// Whether the function is located in an `extern` block (*not* whether it is an
556 /// `extern "abi" fn`). 561 /// `extern "abi" fn`).
557 pub is_extern: bool, 562 pub is_in_extern_block: bool,
558 pub params: Box<[Idx<TypeRef>]>, 563 pub params: Box<[Idx<TypeRef>]>,
559 pub is_varargs: bool, 564 pub is_varargs: bool,
560 pub ret_type: Idx<TypeRef>, 565 pub ret_type: Idx<TypeRef>,
561 pub ast_id: FileAstId<ast::Fn>, 566 pub ast_id: FileAstId<ast::Fn>,
562} 567}
563 568
569#[derive(Debug, Clone, PartialEq, Eq)]
570pub struct FunctionQualifier {
571 pub is_default: bool,
572 pub is_const: bool,
573 pub is_async: bool,
574 pub is_unsafe: bool,
575 pub abi: Option<SmolStr>,
576}
577
564#[derive(Debug, Clone, Eq, PartialEq)] 578#[derive(Debug, Clone, Eq, PartialEq)]
565pub struct Struct { 579pub struct Struct {
566 pub name: Name, 580 pub name: Name,
@@ -624,7 +638,9 @@ pub struct Trait {
624 pub name: Name, 638 pub name: Name,
625 pub visibility: RawVisibilityId, 639 pub visibility: RawVisibilityId,
626 pub generic_params: GenericParamsId, 640 pub generic_params: GenericParamsId,
627 pub auto: bool, 641 pub is_auto: bool,
642 pub is_unsafe: bool,
643 pub bounds: Box<[TypeBound]>,
628 pub items: Box<[AssocItem]>, 644 pub items: Box<[AssocItem]>,
629 pub ast_id: FileAstId<ast::Trait>, 645 pub ast_id: FileAstId<ast::Trait>,
630} 646}
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 240fdacf9..7e91b991d 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -391,14 +391,33 @@ impl Ctx {
391 let has_body = func.body().is_some(); 391 let has_body = func.body().is_some();
392 392
393 let ast_id = self.source_ast_id_map.ast_id(func); 393 let ast_id = self.source_ast_id_map.ast_id(func);
394 let qualifier = FunctionQualifier {
395 is_default: func.default_token().is_some(),
396 is_const: func.const_token().is_some(),
397 is_async: func.async_token().is_some(),
398 is_unsafe: func.unsafe_token().is_some(),
399 abi: func.abi().map(|abi| {
400 // FIXME: Abi::abi() -> Option<SyntaxToken>?
401 match abi.syntax().last_token() {
402 Some(tok) if tok.kind() == SyntaxKind::STRING => {
403 // FIXME: Better way to unescape?
404 tok.text().trim_matches('"').into()
405 }
406 _ => {
407 // `extern` default to be `extern "C"`.
408 "C".into()
409 }
410 }
411 }),
412 };
394 let mut res = Function { 413 let mut res = Function {
395 name, 414 name,
396 visibility, 415 visibility,
397 generic_params: GenericParamsId::EMPTY, 416 generic_params: GenericParamsId::EMPTY,
398 has_self_param, 417 has_self_param,
399 has_body, 418 has_body,
400 is_unsafe: func.unsafe_token().is_some(), 419 qualifier,
401 is_extern: false, 420 is_in_extern_block: false,
402 params, 421 params,
403 is_varargs, 422 is_varargs,
404 ret_type, 423 ret_type,
@@ -481,7 +500,9 @@ impl Ctx {
481 let visibility = self.lower_visibility(trait_def); 500 let visibility = self.lower_visibility(trait_def);
482 let generic_params = 501 let generic_params =
483 self.lower_generic_params_and_inner_items(GenericsOwner::Trait(trait_def), trait_def); 502 self.lower_generic_params_and_inner_items(GenericsOwner::Trait(trait_def), trait_def);
484 let auto = trait_def.auto_token().is_some(); 503 let is_auto = trait_def.auto_token().is_some();
504 let is_unsafe = trait_def.unsafe_token().is_some();
505 let bounds = self.lower_type_bounds(trait_def);
485 let items = trait_def.assoc_item_list().map(|list| { 506 let items = trait_def.assoc_item_list().map(|list| {
486 self.with_inherited_visibility(visibility, |this| { 507 self.with_inherited_visibility(visibility, |this| {
487 list.assoc_items() 508 list.assoc_items()
@@ -501,7 +522,9 @@ impl Ctx {
501 name, 522 name,
502 visibility, 523 visibility,
503 generic_params, 524 generic_params,
504 auto, 525 is_auto,
526 is_unsafe,
527 bounds: bounds.into(),
505 items: items.unwrap_or_default(), 528 items: items.unwrap_or_default(),
506 ast_id, 529 ast_id,
507 }; 530 };
@@ -608,8 +631,8 @@ impl Ctx {
608 ast::ExternItem::Fn(ast) => { 631 ast::ExternItem::Fn(ast) => {
609 let func_id = self.lower_function(&ast)?; 632 let func_id = self.lower_function(&ast)?;
610 let func = &mut self.data().functions[func_id.index]; 633 let func = &mut self.data().functions[func_id.index];
611 func.is_unsafe = is_intrinsic_fn_unsafe(&func.name); 634 func.qualifier.is_unsafe = is_intrinsic_fn_unsafe(&func.name);
612 func.is_extern = true; 635 func.is_in_extern_block = true;
613 func_id.into() 636 func_id.into()
614 } 637 }
615 ast::ExternItem::Static(ast) => { 638 ast::ExternItem::Static(ast) => {
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index 0e60dc2b6..8c923bb7b 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -9,7 +9,10 @@ use std::{
9 9
10use crate::{body::LowerCtx, type_ref::LifetimeRef}; 10use crate::{body::LowerCtx, type_ref::LifetimeRef};
11use base_db::CrateId; 11use base_db::CrateId;
12use hir_expand::{hygiene::Hygiene, name::Name}; 12use hir_expand::{
13 hygiene::Hygiene,
14 name::{name, Name},
15};
13use syntax::ast; 16use syntax::ast;
14 17
15use crate::{ 18use crate::{
@@ -209,6 +212,12 @@ impl Path {
209 }; 212 };
210 Some(res) 213 Some(res)
211 } 214 }
215
216 pub fn is_self_type(&self) -> bool {
217 self.type_anchor.is_none()
218 && self.generic_args == &[None]
219 && self.mod_path.as_ident() == Some(&name!(Self))
220 }
212} 221}
213 222
214#[derive(Debug, Clone, PartialEq, Eq, Hash)] 223#[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 9086e6c17..a3070f1f9 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -401,13 +401,14 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
401 401
402 match parent.kind() { 402 match parent.kind() {
403 MACRO_ITEMS | SOURCE_FILE => FragmentKind::Items, 403 MACRO_ITEMS | SOURCE_FILE => FragmentKind::Items,
404 MACRO_STMTS => FragmentKind::Statement,
404 ITEM_LIST => FragmentKind::Items, 405 ITEM_LIST => FragmentKind::Items,
405 LET_STMT => { 406 LET_STMT => {
406 // FIXME: Handle Pattern 407 // FIXME: Handle Pattern
407 FragmentKind::Expr 408 FragmentKind::Expr
408 } 409 }
409 EXPR_STMT => FragmentKind::Statements, 410 EXPR_STMT => FragmentKind::Statements,
410 BLOCK_EXPR => FragmentKind::Expr, 411 BLOCK_EXPR => FragmentKind::Statements,
411 ARG_LIST => FragmentKind::Expr, 412 ARG_LIST => FragmentKind::Expr,
412 TRY_EXPR => FragmentKind::Expr, 413 TRY_EXPR => FragmentKind::Expr,
413 TUPLE_EXPR => FragmentKind::Expr, 414 TUPLE_EXPR => FragmentKind::Expr,
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index e388ddacc..eee430af1 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -510,7 +510,10 @@ impl InFile<SyntaxToken> {
510 self, 510 self,
511 db: &dyn db::AstDatabase, 511 db: &dyn db::AstDatabase,
512 ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ { 512 ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ {
513 self.map(|it| it.parent()).ancestors_with_macros(db) 513 self.value
514 .parent()
515 .into_iter()
516 .flat_map(move |parent| InFile::new(self.file_id, parent).ancestors_with_macros(db))
514 } 517 }
515} 518}
516 519
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 3605ca581..982ad5b9e 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -91,7 +91,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
91 91
92 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
94 if data.is_extern { 94 if data.is_in_extern_block {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 96 return;
97 } 97 }
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 20bb64827..44a7e5506 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -32,7 +32,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
32 let def = self.owner.into(); 32 let def = self.owner.into();
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).is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe,
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 37 };
38 if is_unsafe 38 if is_unsafe
@@ -86,7 +86,7 @@ fn walk_unsafe(
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def(db) { 88 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).is_unsafe { 89 if db.function_data(func).qualifier.is_unsafe {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
92 } 92 }
@@ -103,7 +103,7 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 103 Expr::MethodCall { .. } => {
104 if infer 104 if infer
105 .method_resolution(current) 105 .method_resolution(current)
106 .map(|func| db.function_data(func).is_unsafe) 106 .map(|func| db.function_data(func).qualifier.is_unsafe)
107 .unwrap_or(false) 107 .unwrap_or(false)
108 { 108 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index c1062387e..7ce0f864c 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -5,7 +5,13 @@ use std::{borrow::Cow, fmt};
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
7use hir_def::{ 7use hir_def::{
8 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, 8 db::DefDatabase,
9 find_path,
10 generics::TypeParamProvenance,
11 item_scope::ItemInNs,
12 path::{GenericArg, Path, PathKind},
13 type_ref::{TypeBound, TypeRef},
14 visibility::Visibility,
9 AssocContainerId, Lookup, ModuleId, TraitId, 15 AssocContainerId, Lookup, ModuleId, TraitId,
10}; 16};
11use hir_expand::name::Name; 17use hir_expand::name::Name;
@@ -14,7 +20,7 @@ use crate::{
14 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,
15 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,
16 CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy, 22 CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
17 ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind, 23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
18}; 24};
19 25
20pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -232,7 +238,7 @@ where
232 238
233const TYPE_HINT_TRUNCATION: &str = "…"; 239const TYPE_HINT_TRUNCATION: &str = "…";
234 240
235impl HirDisplay for &Ty { 241impl<T: HirDisplay> HirDisplay for &'_ T {
236 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 242 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
237 HirDisplay::hir_fmt(*self, f) 243 HirDisplay::hir_fmt(*self, f)
238 } 244 }
@@ -556,7 +562,7 @@ impl HirDisplay for Ty {
556 } 562 }
557 TypeParamProvenance::ArgumentImplTrait => { 563 TypeParamProvenance::ArgumentImplTrait => {
558 let bounds = f.db.generic_predicates_for_param(id); 564 let bounds = f.db.generic_predicates_for_param(id);
559 let substs = Substs::type_params_for_generics(f.db, &generics); 565 let substs = Substitution::type_params_for_generics(f.db, &generics);
560 write_bounds_like_dyn_trait_with_prefix( 566 write_bounds_like_dyn_trait_with_prefix(
561 "impl", 567 "impl",
562 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 568 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
@@ -761,12 +767,6 @@ impl HirDisplay for TraitRef {
761 } 767 }
762} 768}
763 769
764impl HirDisplay for &GenericPredicate {
765 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
766 HirDisplay::hir_fmt(*self, f)
767 }
768}
769
770impl HirDisplay for GenericPredicate { 770impl HirDisplay for GenericPredicate {
771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
772 if f.should_truncate() { 772 if f.should_truncate() {
@@ -825,3 +825,190 @@ impl HirDisplay for Obligation {
825 } 825 }
826 } 826 }
827} 827}
828
829pub fn write_visibility(
830 module_id: ModuleId,
831 vis: Visibility,
832 f: &mut HirFormatter,
833) -> Result<(), HirDisplayError> {
834 match vis {
835 Visibility::Public => write!(f, "pub "),
836 Visibility::Module(vis_id) => {
837 let def_map = module_id.def_map(f.db.upcast());
838 let root_module_id = def_map.module_id(def_map.root());
839 if vis_id == module_id {
840 // pub(self) or omitted
841 Ok(())
842 } else if root_module_id == vis_id {
843 write!(f, "pub(crate) ")
844 } else if module_id.containing_module(f.db.upcast()) == Some(vis_id) {
845 write!(f, "pub(super) ")
846 } else {
847 write!(f, "pub(in ...) ")
848 }
849 }
850 }
851}
852
853impl HirDisplay for TypeRef {
854 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
855 match self {
856 TypeRef::Never => write!(f, "!")?,
857 TypeRef::Placeholder => write!(f, "_")?,
858 TypeRef::Tuple(elems) => {
859 write!(f, "(")?;
860 f.write_joined(elems, ", ")?;
861 if elems.len() == 1 {
862 write!(f, ",")?;
863 }
864 write!(f, ")")?;
865 }
866 TypeRef::Path(path) => path.hir_fmt(f)?,
867 TypeRef::RawPtr(inner, mutability) => {
868 let mutability = match mutability {
869 hir_def::type_ref::Mutability::Shared => "*const ",
870 hir_def::type_ref::Mutability::Mut => "*mut ",
871 };
872 write!(f, "{}", mutability)?;
873 inner.hir_fmt(f)?;
874 }
875 TypeRef::Reference(inner, lifetime, mutability) => {
876 let mutability = match mutability {
877 hir_def::type_ref::Mutability::Shared => "",
878 hir_def::type_ref::Mutability::Mut => "mut ",
879 };
880 write!(f, "&")?;
881 if let Some(lifetime) = lifetime {
882 write!(f, "{} ", lifetime.name)?;
883 }
884 write!(f, "{}", mutability)?;
885 inner.hir_fmt(f)?;
886 }
887 TypeRef::Array(inner) => {
888 write!(f, "[")?;
889 inner.hir_fmt(f)?;
890 // FIXME: Array length?
891 write!(f, "; _]")?;
892 }
893 TypeRef::Slice(inner) => {
894 write!(f, "[")?;
895 inner.hir_fmt(f)?;
896 write!(f, "]")?;
897 }
898 TypeRef::Fn(tys, is_varargs) => {
899 // FIXME: Function pointer qualifiers.
900 write!(f, "fn(")?;
901 f.write_joined(&tys[..tys.len() - 1], ", ")?;
902 if *is_varargs {
903 write!(f, "{}...", if tys.len() == 1 { "" } else { ", " })?;
904 }
905 write!(f, ")")?;
906 let ret_ty = tys.last().unwrap();
907 match ret_ty {
908 TypeRef::Tuple(tup) if tup.is_empty() => {}
909 _ => {
910 write!(f, " -> ")?;
911 ret_ty.hir_fmt(f)?;
912 }
913 }
914 }
915 TypeRef::ImplTrait(bounds) => {
916 write!(f, "impl ")?;
917 f.write_joined(bounds, " + ")?;
918 }
919 TypeRef::DynTrait(bounds) => {
920 write!(f, "dyn ")?;
921 f.write_joined(bounds, " + ")?;
922 }
923 TypeRef::Error => write!(f, "{{error}}")?,
924 }
925 Ok(())
926 }
927}
928
929impl HirDisplay for TypeBound {
930 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
931 match self {
932 TypeBound::Path(path) => path.hir_fmt(f),
933 TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
934 TypeBound::Error => write!(f, "{{error}}"),
935 }
936 }
937}
938
939impl HirDisplay for Path {
940 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
941 match (self.type_anchor(), self.kind()) {
942 (Some(anchor), _) => {
943 write!(f, "<")?;
944 anchor.hir_fmt(f)?;
945 write!(f, ">")?;
946 }
947 (_, PathKind::Plain) => {}
948 (_, PathKind::Abs) => write!(f, "::")?,
949 (_, PathKind::Crate) => write!(f, "crate")?,
950 (_, PathKind::Super(0)) => write!(f, "self")?,
951 (_, PathKind::Super(n)) => {
952 write!(f, "super")?;
953 for _ in 0..*n {
954 write!(f, "::super")?;
955 }
956 }
957 (_, PathKind::DollarCrate(_)) => write!(f, "{{extern_crate}}")?,
958 }
959
960 for (seg_idx, segment) in self.segments().iter().enumerate() {
961 if seg_idx != 0 {
962 write!(f, "::")?;
963 }
964 write!(f, "{}", segment.name)?;
965 if let Some(generic_args) = segment.args_and_bindings {
966 // We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
967 // Do we actually format expressions?
968 write!(f, "<")?;
969 let mut first = true;
970 for arg in &generic_args.args {
971 if first {
972 first = false;
973 if generic_args.has_self_type {
974 // FIXME: Convert to `<Ty as Trait>` form.
975 write!(f, "Self = ")?;
976 }
977 } else {
978 write!(f, ", ")?;
979 }
980 arg.hir_fmt(f)?;
981 }
982 for binding in &generic_args.bindings {
983 if first {
984 first = false;
985 } else {
986 write!(f, ", ")?;
987 }
988 write!(f, "{}", binding.name)?;
989 match &binding.type_ref {
990 Some(ty) => {
991 write!(f, " = ")?;
992 ty.hir_fmt(f)?
993 }
994 None => {
995 write!(f, ": ")?;
996 f.write_joined(&binding.bounds, " + ")?;
997 }
998 }
999 }
1000 write!(f, ">")?;
1001 }
1002 }
1003 Ok(())
1004 }
1005}
1006
1007impl HirDisplay for GenericArg {
1008 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1009 match self {
1010 GenericArg::Type(ty) => ty.hir_fmt(f),
1011 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1012 }
1013 }
1014}
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/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index fb3afaedc..af4f8bb11 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -216,6 +216,22 @@ fn expr_macro_expanded_in_various_places() {
216} 216}
217 217
218#[test] 218#[test]
219fn expr_macro_expanded_in_stmts() {
220 check_infer(
221 r#"
222 macro_rules! id { ($($es:tt)*) => { $($es)* } }
223 fn foo() {
224 id! { let a = (); }
225 }
226 "#,
227 expect![[r#"
228 !0..8 'leta=();': ()
229 57..84 '{ ...); } }': ()
230 "#]],
231 );
232}
233
234#[test]
219fn infer_type_value_macro_having_same_name() { 235fn infer_type_value_macro_having_same_name() {
220 check_infer( 236 check_infer(
221 r#" 237 r#"
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 232cf9cd0..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,9 +427,9 @@ pub(crate) fn trait_datum_query(
427 let trait_data = db.trait_data(trait_); 427 let trait_data = db.trait_data(t