aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cargo/config1
-rw-r--r--Cargo.lock1
-rw-r--r--crates/cfg/src/cfg_expr.rs2
-rw-r--r--crates/hir/Cargo.toml1
-rw-r--r--crates/hir/src/lib.rs174
-rw-r--r--crates/hir/src/semantics.rs8
-rw-r--r--crates/hir/src/semantics/source_to_def.rs22
-rw-r--r--crates/hir/src/source_analyzer.rs5
-rw-r--r--crates/hir_def/Cargo.toml2
-rw-r--r--crates/hir_def/src/attr.rs48
-rw-r--r--crates/hir_def/src/body.rs19
-rw-r--r--crates/hir_def/src/body/lower.rs24
-rw-r--r--crates/hir_def/src/item_tree.rs12
-rw-r--r--crates/hir_def/src/lib.rs10
-rw-r--r--crates/hir_def/src/nameres/tests/diagnostics.rs3
-rw-r--r--crates/hir_def/src/test_db.rs9
-rw-r--r--crates/hir_expand/src/builtin_derive.rs2
-rw-r--r--crates/hir_expand/src/db.rs2
-rw-r--r--crates/hir_expand/src/name.rs2
-rw-r--r--crates/hir_ty/Cargo.toml4
-rw-r--r--crates/hir_ty/src/autoderef.rs15
-rw-r--r--crates/hir_ty/src/db.rs23
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs21
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs8
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs198
-rw-r--r--crates/hir_ty/src/infer.rs98
-rw-r--r--crates/hir_ty/src/infer/coerce.rs42
-rw-r--r--crates/hir_ty/src/infer/expr.rs253
-rw-r--r--crates/hir_ty/src/infer/pat.rs49
-rw-r--r--crates/hir_ty/src/infer/path.rs18
-rw-r--r--crates/hir_ty/src/infer/unify.rs133
-rw-r--r--crates/hir_ty/src/lib.rs435
-rw-r--r--crates/hir_ty/src/lower.rs708
-rw-r--r--crates/hir_ty/src/method_resolution.rs96
-rw-r--r--crates/hir_ty/src/op.rs66
-rw-r--r--crates/hir_ty/src/tests.rs10
-rw-r--r--crates/hir_ty/src/tests/traits.rs216
-rw-r--r--crates/hir_ty/src/traits.rs38
-rw-r--r--crates/hir_ty/src/traits/chalk.rs85
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs287
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs9
-rw-r--r--crates/ide/Cargo.toml3
-rw-r--r--crates/ide/src/annotations.rs83
-rw-r--r--crates/ide/src/diagnostics.rs163
-rw-r--r--crates/ide/src/diagnostics/unlinked_file.rs156
-rw-r--r--crates/ide/src/file_structure.rs228
-rw-r--r--crates/ide/src/goto_definition.rs11
-rw-r--r--crates/ide/src/goto_implementation.rs130
-rw-r--r--crates/ide/src/inlay_hints.rs2
-rw-r--r--crates/ide/src/join_lines.rs4
-rw-r--r--crates/ide/src/lib.rs15
-rw-r--r--crates/ide/src/parent_module.rs79
-rw-r--r--crates/ide/src/references.rs26
-rw-r--r--crates/ide/src/references/rename.rs3
-rw-r--r--crates/ide/src/runnables.rs445
-rw-r--r--crates/ide/src/typing.rs3
-rw-r--r--crates/ide_assists/Cargo.toml2
-rw-r--r--crates/ide_assists/src/handlers/add_turbo_fish.rs33
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs87
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs248
-rw-r--r--crates/ide_assists/src/handlers/generate_is_empty_from_len.rs255
-rw-r--r--crates/ide_assists/src/lib.rs4
-rw-r--r--crates/ide_assists/src/tests/generated.rs59
-rw-r--r--crates/ide_completion/Cargo.toml2
-rw-r--r--crates/ide_completion/src/completions/attribute.rs35
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs7
-rw-r--r--crates/ide_completion/src/completions/keyword.rs44
-rw-r--r--crates/ide_completion/src/completions/mod_.rs6
-rw-r--r--crates/ide_completion/src/completions/pattern.rs116
-rw-r--r--crates/ide_completion/src/completions/postfix.rs7
-rw-r--r--crates/ide_completion/src/completions/postfix/format_like.rs2
-rw-r--r--crates/ide_completion/src/completions/record.rs15
-rw-r--r--crates/ide_completion/src/completions/snippet.rs25
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs32
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs88
-rw-r--r--crates/ide_completion/src/context.rs295
-rw-r--r--crates/ide_completion/src/item.rs188
-rw-r--r--crates/ide_completion/src/lib.rs5
-rw-r--r--crates/ide_completion/src/render.rs355
-rw-r--r--crates/ide_completion/src/render/builder_ext.rs6
-rw-r--r--crates/ide_completion/src/render/const_.rs10
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs21
-rw-r--r--crates/ide_completion/src/render/function.rs30
-rw-r--r--crates/ide_completion/src/render/macro_.rs26
-rw-r--r--crates/ide_completion/src/render/pattern.rs54
-rw-r--r--crates/ide_completion/src/render/type_alias.rs10
-rw-r--r--crates/ide_db/Cargo.toml2
-rw-r--r--crates/ide_db/src/defs.rs2
-rw-r--r--crates/ide_db/src/helpers.rs28
-rw-r--r--crates/ide_db/src/search.rs20
-rw-r--r--crates/ide_ssr/Cargo.toml2
-rw-r--r--crates/mbe/Cargo.toml2
-rw-r--r--crates/mbe/src/expander.rs4
-rw-r--r--crates/mbe/src/expander/matcher.rs266
-rw-r--r--crates/mbe/src/expander/transcriber.rs19
-rw-r--r--crates/mbe/src/syntax_bridge.rs8
-rw-r--r--crates/parser/src/grammar.rs2
-rw-r--r--crates/proc_macro_api/src/lib.rs3
-rw-r--r--crates/proc_macro_api/src/version.rs17
-rw-r--r--crates/proc_macro_srv/src/tests/mod.rs7
-rw-r--r--crates/proc_macro_srv/src/tests/utils.rs2
-rw-r--r--crates/project_model/src/rustc_cfg.rs2
-rw-r--r--crates/rust-analyzer/build.rs5
-rw-r--r--crates/rust-analyzer/src/bin/flags.rs3
-rw-r--r--crates/rust-analyzer/src/bin/main.rs1
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs11
-rw-r--r--crates/rust-analyzer/src/config.rs2
-rw-r--r--crates/rust-analyzer/src/handlers.rs52
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs13
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs4
-rw-r--r--crates/rust-analyzer/src/main_loop.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs50
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/ast/make.rs3
-rw-r--r--crates/syntax/src/parsing/text_tree_sink.rs4
-rw-r--r--crates/tt/src/lib.rs47
-rw-r--r--docs/dev/architecture.md6
-rw-r--r--docs/dev/lsp-extensions.md18
-rw-r--r--docs/dev/style.md4
-rw-r--r--docs/user/generated_config.adoc2
-rw-r--r--docs/user/manual.adoc2
-rw-r--r--editors/code/package.json16
-rw-r--r--editors/code/src/commands.ts81
-rw-r--r--editors/code/src/lsp_ext.ts6
-rw-r--r--editors/code/src/main.ts1
-rw-r--r--xtask/src/codegen.rs2
-rw-r--r--xtask/src/flags.rs2
-rw-r--r--xtask/src/main.rs22
-rw-r--r--xtask/src/metrics.rs3
131 files changed, 5037 insertions, 2297 deletions
diff --git a/.cargo/config b/.cargo/config
index f6b0b66bf..1447614b7 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -3,6 +3,7 @@ xtask = "run --package xtask --bin xtask --"
3install-ra = "run --package xtask --bin xtask -- install" # for backwards compat 3install-ra = "run --package xtask --bin xtask -- install" # for backwards compat
4tq = "test -- -q" 4tq = "test -- -q"
5qt = "tq" 5qt = "tq"
6lint = "clippy --all-targets -- -Aclippy::collapsible_if -Aclippy::needless_pass_by_value -Aclippy::nonminimal_bool -Aclippy::redundant_pattern_matching --cap-lints warn"
6 7
7[target.x86_64-pc-windows-msvc] 8[target.x86_64-pc-windows-msvc]
8linker = "rust-lld" 9linker = "rust-lld"
diff --git a/Cargo.lock b/Cargo.lock
index b1fef2e80..b2d009e38 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -486,6 +486,7 @@ dependencies = [
486 "log", 486 "log",
487 "profile", 487 "profile",
488 "rustc-hash", 488 "rustc-hash",
489 "smallvec",
489 "stdx", 490 "stdx",
490 "syntax", 491 "syntax",
491 "tt", 492 "tt",
diff --git a/crates/cfg/src/cfg_expr.rs b/crates/cfg/src/cfg_expr.rs
index 42327f1e1..069fc01d0 100644
--- a/crates/cfg/src/cfg_expr.rs
+++ b/crates/cfg/src/cfg_expr.rs
@@ -49,7 +49,7 @@ impl fmt::Display for CfgAtom {
49 } 49 }
50} 50}
51 51
52#[derive(Debug, Clone, PartialEq, Eq)] 52#[derive(Debug, Clone, PartialEq, Eq, Hash)]
53pub enum CfgExpr { 53pub enum CfgExpr {
54 Invalid, 54 Invalid,
55 Atom(CfgAtom), 55 Atom(CfgAtom),
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml
index d4ea7327e..55e9c3f0c 100644
--- a/crates/hir/Cargo.toml
+++ b/crates/hir/Cargo.toml
@@ -15,6 +15,7 @@ rustc-hash = "1.1.0"
15either = "1.5.3" 15either = "1.5.3"
16arrayvec = "0.5.1" 16arrayvec = "0.5.1"
17itertools = "0.10.0" 17itertools = "0.10.0"
18smallvec = "1.4.0"
18 19
19stdx = { path = "../stdx", version = "0.0.0" } 20stdx = { path = "../stdx", version = "0.0.0" }
20syntax = { path = "../syntax", version = "0.0.0" } 21syntax = { path = "../syntax", version = "0.0.0" }
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 58adc8fd3..c5161dadd 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -51,11 +51,12 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
51use hir_ty::{ 51use hir_ty::{
52 autoderef, 52 autoderef,
53 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, 53 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
54 method_resolution, 54 method_resolution::{self, TyFingerprint},
55 to_assoc_type_id,
55 traits::{FnTrait, Solution, SolutionVariables}, 56 traits::{FnTrait, Solution, SolutionVariables},
56 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 57 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
57 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, 58 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty,
58 Ty, TyDefId, TyVariableKind, 59 TyDefId, TyKind, TyVariableKind,
59}; 60};
60use rustc_hash::FxHashSet; 61use rustc_hash::FxHashSet;
61use stdx::{format_to, impl_from}; 62use stdx::{format_to, impl_from};
@@ -266,8 +267,7 @@ impl ModuleDef {
266 } 267 }
267 268
268 pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> { 269 pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
269 let mut segments = Vec::new(); 270 let mut segments = vec![self.name(db)?.to_string()];
270 segments.push(self.name(db)?.to_string());
271 for m in self.module(db)?.path_to_root(db) { 271 for m in self.module(db)?.path_to_root(db) {
272 segments.extend(m.name(db).map(|it| it.to_string())) 272 segments.extend(m.name(db).map(|it| it.to_string()))
273 } 273 }
@@ -677,7 +677,7 @@ impl_from!(Struct, Union, Enum for Adt);
677impl Adt { 677impl Adt {
678 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 678 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
679 let subst = db.generic_defaults(self.into()); 679 let subst = db.generic_defaults(self.into());
680 subst.iter().any(|ty| &ty.value == &Ty::Unknown) 680 subst.iter().any(|ty| ty.value.is_unknown())
681 } 681 }
682 682
683 /// Turns this ADT into a type. Any type parameters of the ADT will be 683 /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -696,8 +696,8 @@ impl Adt {
696 } 696 }
697 } 697 }
698 698
699 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 699 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
700 Some(self.module(db).krate()) 700 self.module(db).krate()
701 } 701 }
702 702
703 pub fn name(self, db: &dyn HirDatabase) -> Name { 703 pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -802,7 +802,7 @@ impl Function {
802 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); 802 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
803 let ret_type = &db.function_data(self.id).ret_type; 803 let ret_type = &db.function_data(self.id).ret_type;
804 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 804 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
805 let ty = Ty::from_hir_ext(&ctx, ret_type).0; 805 let ty = ctx.lower_ty(ret_type);
806 Type::new_with_resolver_inner(db, krate, &resolver, ty) 806 Type::new_with_resolver_inner(db, krate, &resolver, ty)
807 } 807 }
808 808
@@ -817,7 +817,7 @@ impl Function {
817 let resolver = self.id.resolver(db.upcast()); 817 let resolver = self.id.resolver(db.upcast());
818 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); 818 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
819 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 819 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
820 let environment = TraitEnvironment::lower(db, &resolver); 820 let environment = db.trait_environment(self.id.into());
821 db.function_data(self.id) 821 db.function_data(self.id)
822 .params 822 .params
823 .iter() 823 .iter()
@@ -825,7 +825,7 @@ impl Function {
825 let ty = Type { 825 let ty = Type {
826 krate, 826 krate,
827 ty: InEnvironment { 827 ty: InEnvironment {
828 value: Ty::from_hir_ext(&ctx, type_ref).0, 828 value: ctx.lower_ty(type_ref),
829 environment: environment.clone(), 829 environment: environment.clone(),
830 }, 830 },
831 }; 831 };
@@ -1012,15 +1012,15 @@ pub struct TypeAlias {
1012impl TypeAlias { 1012impl TypeAlias {
1013 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 1013 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
1014 let subst = db.generic_defaults(self.id.into()); 1014 let subst = db.generic_defaults(self.id.into());
1015 subst.iter().any(|ty| &ty.value == &Ty::Unknown) 1015 subst.iter().any(|ty| ty.value.is_unknown())
1016 } 1016 }
1017 1017
1018 pub fn module(self, db: &dyn HirDatabase) -> Module { 1018 pub fn module(self, db: &dyn HirDatabase) -> Module {
1019 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1019 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1020 } 1020 }
1021 1021
1022 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 1022 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1023 Some(self.module(db).krate()) 1023 self.module(db).krate()
1024 } 1024 }
1025 1025
1026 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1026 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1384,7 +1384,7 @@ impl TypeParam {
1384 pub fn ty(self, db: &dyn HirDatabase) -> Type { 1384 pub fn ty(self, db: &dyn HirDatabase) -> Type {
1385 let resolver = self.id.parent.resolver(db.upcast()); 1385 let resolver = self.id.parent.resolver(db.upcast());
1386 let krate = self.id.parent.module(db.upcast()).krate(); 1386 let krate = self.id.parent.module(db.upcast()).krate();
1387 let ty = Ty::Placeholder(self.id); 1387 let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id)).intern(&Interner);
1388 Type::new_with_resolver_inner(db, krate, &resolver, ty) 1388 Type::new_with_resolver_inner(db, krate, &resolver, ty)
1389 } 1389 }
1390 1390
@@ -1483,9 +1483,44 @@ impl Impl {
1483 1483
1484 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1484 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1485 } 1485 }
1486 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { 1486
1487 let impls = db.trait_impls_in_crate(krate.id); 1487 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
1488 impls.for_trait(trait_.id).map(Self::from).collect() 1488 let def_crates = match ty.value.def_crates(db, krate) {
1489 Some(def_crates) => def_crates,
1490 None => return Vec::new(),
1491 };
1492
1493 let filter = |impl_def: &Impl| {
1494 let target_ty = impl_def.target_ty(db);
1495 let rref = target_ty.remove_ref();
1496 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value))
1497 };
1498
1499 let mut all = Vec::new();
1500 def_crates.into_iter().for_each(|id| {
1501 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1502 });
1503 let fp = TyFingerprint::for_impl(&ty.value);
1504 for id in db.crate_graph().iter() {
1505 match fp {
1506 Some(fp) => all.extend(
1507 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
1508 ),
1509 None => all
1510 .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)),
1511 }
1512 }
1513 all
1514 }
1515
1516 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
1517 let krate = trait_.module(db).krate();
1518 let mut all = Vec::new();
1519 for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) {
1520 let impls = db.trait_impls_in_crate(id);
1521 all.extend(impls.for_trait(trait_.id).map(Self::from))
1522 }
1523 all
1489 } 1524 }
1490 1525
1491 // FIXME: the return type is wrong. This should be a hir version of 1526 // FIXME: the return type is wrong. This should be a hir version of
@@ -1499,7 +1534,7 @@ impl Impl {
1499 let resolver = self.id.resolver(db.upcast()); 1534 let resolver = self.id.resolver(db.upcast());
1500 let krate = self.id.lookup(db.upcast()).container.krate(); 1535 let krate = self.id.lookup(db.upcast()).container.krate();
1501 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 1536 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
1502 let ty = Ty::from_hir(&ctx, &impl_data.target_type); 1537 let ty = ctx.lower_ty(&impl_data.target_type);
1503 Type::new_with_resolver_inner(db, krate, &resolver, ty) 1538 Type::new_with_resolver_inner(db, krate, &resolver, ty)
1504 } 1539 }
1505 1540
@@ -1563,13 +1598,15 @@ impl Type {
1563 resolver: &Resolver, 1598 resolver: &Resolver,
1564 ty: Ty, 1599 ty: Ty,
1565 ) -> Type { 1600 ) -> Type {
1566 let environment = TraitEnvironment::lower(db, &resolver); 1601 let environment =
1602 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1567 Type { krate, ty: InEnvironment { value: ty, environment } } 1603 Type { krate, ty: InEnvironment { value: ty, environment } }
1568 } 1604 }
1569 1605
1570 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { 1606 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1571 let resolver = lexical_env.resolver(db.upcast()); 1607 let resolver = lexical_env.resolver(db.upcast());
1572 let environment = TraitEnvironment::lower(db, &resolver); 1608 let environment =
1609 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1573 Type { krate, ty: InEnvironment { value: ty, environment } } 1610 Type { krate, ty: InEnvironment { value: ty, environment } }
1574 } 1611 }
1575 1612
@@ -1584,25 +1621,25 @@ impl Type {
1584 } 1621 }
1585 1622
1586 pub fn is_unit(&self) -> bool { 1623 pub fn is_unit(&self) -> bool {
1587 matches!(self.ty.value, Ty::Tuple(0, ..)) 1624 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..))
1588 } 1625 }
1589 pub fn is_bool(&self) -> bool { 1626 pub fn is_bool(&self) -> bool {
1590 matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) 1627 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1591 } 1628 }
1592 1629
1593 pub fn is_mutable_reference(&self) -> bool { 1630 pub fn is_mutable_reference(&self) -> bool {
1594 matches!(self.ty.value, Ty::Ref(hir_ty::Mutability::Mut, ..)) 1631 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1595 } 1632 }
1596 1633
1597 pub fn remove_ref(&self) -> Option<Type> { 1634 pub fn remove_ref(&self) -> Option<Type> {
1598 match &self.ty.value { 1635 match &self.ty.value.interned(&Interner) {
1599 Ty::Ref(.., substs) => Some(self.derived(substs[0].clone())), 1636 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
1600 _ => None, 1637 _ => None,
1601 } 1638 }
1602 } 1639 }
1603 1640
1604 pub fn is_unknown(&self) -> bool { 1641 pub fn is_unknown(&self) -> bool {
1605 matches!(self.ty.value, Ty::Unknown) 1642 self.ty.value.is_unknown()
1606 } 1643 }
1607 1644
1608 /// Checks that particular type `ty` implements `std::future::Future`. 1645 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1683,8 +1720,11 @@ impl Type {
1683 .fill(args.iter().map(|t| t.ty.value.clone())) 1720 .fill(args.iter().map(|t| t.ty.value.clone()))
1684 .build(); 1721 .build();
1685 let predicate = ProjectionPredicate { 1722 let predicate = ProjectionPredicate {
1686 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, 1723 projection_ty: ProjectionTy {
1687 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), 1724 associated_ty_id: to_assoc_type_id(alias.id),
1725 substitution: subst,
1726 },
1727 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
1688 }; 1728 };
1689 let goal = Canonical { 1729 let goal = Canonical {
1690 value: InEnvironment::new( 1730 value: InEnvironment::new(
@@ -1712,26 +1752,23 @@ impl Type {
1712 } 1752 }
1713 1753
1714 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1754 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1715 let def = match self.ty.value { 1755 let def = self.ty.value.callable_def(db);
1716 Ty::FnDef(def, _) => Some(def),
1717 _ => None,
1718 };
1719 1756
1720 let sig = self.ty.value.callable_sig(db)?; 1757 let sig = self.ty.value.callable_sig(db)?;
1721 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) 1758 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1722 } 1759 }
1723 1760
1724 pub fn is_closure(&self) -> bool { 1761 pub fn is_closure(&self) -> bool {
1725 matches!(&self.ty.value, Ty::Closure { .. }) 1762 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. })
1726 } 1763 }
1727 1764
1728 pub fn is_fn(&self) -> bool { 1765 pub fn is_fn(&self) -> bool {
1729 matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) 1766 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1730 } 1767 }
1731 1768
1732 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1769 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1733 let adt_id = match self.ty.value { 1770 let adt_id = match self.ty.value.interned(&Interner) {
1734 Ty::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1771 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1735 _ => return false, 1772 _ => return false,
1736 }; 1773 };
1737 1774
@@ -1743,24 +1780,45 @@ impl Type {
1743 } 1780 }
1744 1781
1745 pub fn is_raw_ptr(&self) -> bool { 1782 pub fn is_raw_ptr(&self) -> bool {
1746 matches!(&self.ty.value, Ty::Raw(..)) 1783 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..))
1747 } 1784 }
1748 1785
1749 pub fn contains_unknown(&self) -> bool { 1786 pub fn contains_unknown(&self) -> bool {
1750 return go(&self.ty.value); 1787 return go(&self.ty.value);
1751 1788
1752 fn go(ty: &Ty) -> bool { 1789 fn go(ty: &Ty) -> bool {
1753 match ty { 1790 match ty.interned(&Interner) {
1754 Ty::Unknown => true, 1791 TyKind::Unknown => true,
1755 _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), 1792
1793 TyKind::Adt(_, substs)
1794 | TyKind::AssociatedType(_, substs)
1795 | TyKind::Tuple(_, substs)
1796 | TyKind::OpaqueType(_, substs)
1797 | TyKind::FnDef(_, substs)
1798 | TyKind::Closure(_, substs) => substs.iter().any(go),
1799
1800 TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
1801 go(ty)
1802 }
1803
1804 TyKind::Scalar(_)
1805 | TyKind::Str
1806 | TyKind::Never
1807 | TyKind::Placeholder(_)
1808 | TyKind::BoundVar(_)
1809 | TyKind::InferenceVar(_, _)
1810 | TyKind::Dyn(_)
1811 | TyKind::Function(_)
1812 | TyKind::Alias(_)
1813 | TyKind::ForeignType(_) => false,
1756 } 1814 }
1757 } 1815 }
1758 } 1816 }
1759 1817
1760 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1818 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1761 let (variant_id, substs) = match self.ty.value { 1819 let (variant_id, substs) = match self.ty.value.interned(&Interner) {
1762 Ty::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1820 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1763 Ty::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1821 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1764 _ => return Vec::new(), 1822 _ => return Vec::new(),
1765 }; 1823 };
1766 1824
@@ -1775,7 +1833,7 @@ impl Type {
1775 } 1833 }
1776 1834
1777 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1835 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1778 if let Ty::Tuple(_, substs) = &self.ty.value { 1836 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) {
1779 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1837 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1780 } else { 1838 } else {
1781 Vec::new() 1839 Vec::new()
@@ -1910,12 +1968,6 @@ impl Type {
1910 self.ty.value.associated_type_parent_trait(db).map(Into::into) 1968 self.ty.value.associated_type_parent_trait(db).map(Into::into)
1911 } 1969 }
1912 1970
1913 // FIXME: provide required accessors such that it becomes implementable from outside.
1914 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1915 let rref = other.remove_ref();
1916 self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value))
1917 }
1918
1919 fn derived(&self, ty: Ty) -> Type { 1971 fn derived(&self, ty: Ty) -> Type {
1920 Type { 1972 Type {
1921 krate: self.krate, 1973 krate: self.krate,
@@ -1957,36 +2009,40 @@ impl Type {
1957 2009
1958 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2010 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1959 let ty = type_.ty.value.strip_references(); 2011 let ty = type_.ty.value.strip_references();
1960 match ty { 2012 match ty.interned(&Interner) {
1961 Ty::Adt(..) => { 2013 TyKind::Adt(..) => {
1962 cb(type_.derived(ty.clone())); 2014 cb(type_.derived(ty.clone()));
1963 } 2015 }
1964 Ty::AssociatedType(..) => { 2016 TyKind::AssociatedType(..) => {
1965 if let Some(_) = ty.associated_type_parent_trait(db) { 2017 if let Some(_) = ty.associated_type_parent_trait(db) {
1966 cb(type_.derived(ty.clone())); 2018 cb(type_.derived(ty.clone()));
1967 } 2019 }
1968 } 2020 }
1969 Ty::OpaqueType(..) => { 2021 TyKind::OpaqueType(..) => {
1970 if let Some(bounds) = ty.impl_trait_bounds(db) { 2022 if let Some(bounds) = ty.impl_trait_bounds(db) {
1971 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2023 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1972 } 2024 }
1973 } 2025 }
1974 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 2026 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
1975 if let Some(bounds) = ty.impl_trait_bounds(db) { 2027 if let Some(bounds) = ty.impl_trait_bounds(db) {
1976 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2028 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1977 } 2029 }
1978 2030
1979 walk_substs(db, type_, &opaque_ty.parameters, cb); 2031 walk_substs(db, type_, &opaque_ty.substitution, cb);
1980 } 2032 }
1981 Ty::Placeholder(_) => { 2033 TyKind::Placeholder(_) => {
1982 if let Some(bounds) = ty.impl_trait_bounds(db) { 2034 if let Some(bounds) = ty.impl_trait_bounds(db) {
1983 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2035 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1984 } 2036 }
1985 } 2037 }
1986 Ty::Dyn(bounds) => { 2038 TyKind::Dyn(bounds) => {
1987 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 2039 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1988 } 2040 }
1989 2041
2042 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
2043 walk_type(db, &type_.derived(ty.clone()), cb);
2044 }
2045
1990 _ => {} 2046 _ => {}
1991 } 2047 }
1992 if let Some(substs) = ty.substs() { 2048 if let Some(substs) = ty.substs() {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 945638cc5..519339c0c 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -259,6 +259,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
259 } 259 }
260 260
261 pub fn to_module_def(&self, file: FileId) -> Option<Module> { 261 pub fn to_module_def(&self, file: FileId) -> Option<Module> {
262 self.imp.to_module_def(file).next()
263 }
264
265 pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
262 self.imp.to_module_def(file) 266 self.imp.to_module_def(file)
263 } 267 }
264 268
@@ -537,8 +541,8 @@ impl<'db> SemanticsImpl<'db> {
537 f(&mut ctx) 541 f(&mut ctx)
538 } 542 }
539 543
540 fn to_module_def(&self, file: FileId) -> Option<Module> { 544 fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
541 self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) 545 self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
542 } 546 }
543 547
544 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { 548 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 6c612ee86..e9d820140 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -12,6 +12,7 @@ use hir_def::{
12}; 12};
13use hir_expand::{name::AsName, AstId, MacroDefKind}; 13use hir_expand::{name::AsName, AstId, MacroDefKind};
14use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
15use smallvec::SmallVec;
15use stdx::impl_from; 16use stdx::impl_from;
16use syntax::{ 17use syntax::{
17 ast::{self, NameOwner}, 18 ast::{self, NameOwner},
@@ -28,14 +29,19 @@ pub(super) struct SourceToDefCtx<'a, 'b> {
28} 29}
29 30
30impl SourceToDefCtx<'_, '_> { 31impl SourceToDefCtx<'_, '_> {
31 pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> { 32 pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> {
32 let _p = profile::span("SourceBinder::to_module_def"); 33 let _p = profile::span("SourceBinder::to_module_def");
33 self.db.relevant_crates(file).iter().find_map(|&crate_id| { 34 let mut mods = SmallVec::new();
35 for &crate_id in self.db.relevant_crates(file).iter() {
34 // FIXME: inner items 36 // FIXME: inner items
35 let crate_def_map = self.db.crate_def_map(crate_id); 37 let crate_def_map = self.db.crate_def_map(crate_id);
36 let local_id = crate_def_map.modules_for_file(file).next()?; 38 mods.extend(
37 Some(crate_def_map.module_id(local_id)) 39 crate_def_map
38 }) 40 .modules_for_file(file)
41 .map(|local_id| crate_def_map.module_id(local_id)),
42 )
43 }
44 mods
39 } 45 }
40 46
41 pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { 47 pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> {
@@ -55,7 +61,7 @@ impl SourceToDefCtx<'_, '_> {
55 Some(parent_declaration) => self.module_to_def(parent_declaration), 61 Some(parent_declaration) => self.module_to_def(parent_declaration),
56 None => { 62 None => {
57 let file_id = src.file_id.original_file(self.db.upcast()); 63 let file_id = src.file_id.original_file(self.db.upcast());
58 self.file_to_def(file_id) 64 self.file_to_def(file_id).get(0).copied()
59 } 65 }
60 }?; 66 }?;
61 67
@@ -185,7 +191,7 @@ impl SourceToDefCtx<'_, '_> {
185 ) -> Option<MacroDefId> { 191 ) -> Option<MacroDefId> {
186 let kind = MacroDefKind::Declarative; 192 let kind = MacroDefKind::Declarative;
187 let file_id = src.file_id.original_file(self.db.upcast()); 193 let file_id = src.file_id.original_file(self.db.upcast());
188 let krate = self.file_to_def(file_id)?.krate(); 194 let krate = self.file_to_def(file_id).get(0).copied()?.krate();
189 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); 195 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
190 let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast())); 196 let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast()));
191 Some(MacroDefId { krate, ast_id, kind, local_inner: false }) 197 Some(MacroDefId { krate, ast_id, kind, local_inner: false })
@@ -245,7 +251,7 @@ impl SourceToDefCtx<'_, '_> {
245 return Some(res); 251 return Some(res);
246 } 252 }
247 253
248 let def = self.file_to_def(src.file_id.original_file(self.db.upcast()))?; 254 let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?;
249 Some(def.into()) 255 Some(def.into())
250 } 256 }
251 257
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index d546512cb..4d59293e9 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -161,8 +161,9 @@ impl SourceAnalyzer {
161 db: &dyn HirDatabase, 161 db: &dyn HirDatabase,
162 field: &ast::RecordExprField, 162 field: &ast::RecordExprField,
163 ) -> Option<(Field, Option<Local>)> { 163 ) -> Option<(Field, Option<Local>)> {
164 let expr = field.expr()?; 164 let expr_id =
165 let expr_id = self.expr_id(db, &expr)?; 165 self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?;
166
166 let local = if field.name_ref().is_some() { 167 let local = if field.name_ref().is_some() {
167 None 168 None
168 } else { 169 } else {
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml
index c2d99280f..475d337f3 100644
--- a/crates/hir_def/Cargo.toml
+++ b/crates/hir_def/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2018"
10doctest = false 10doctest = false
11 11
12[dependencies] 12[dependencies]
13cov-mark = "1.1" 13cov-mark = { version = "1.1", features = ["thread-local"] }
14log = "0.4.8" 14log = "0.4.8"
15once_cell = "1.3.1" 15once_cell = "1.3.1"
16rustc-hash = "1.1.0" 16rustc-hash = "1.1.0"
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 97cdbbb9e..7b41b148c 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -9,6 +9,7 @@ use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile};
9use itertools::Itertools; 9use itertools::Itertools;
10use la_arena::ArenaMap; 10use la_arena::ArenaMap;
11use mbe::ast_to_token_tree; 11use mbe::ast_to_token_tree;
12use smallvec::{smallvec, SmallVec};
12use syntax::{ 13use syntax::{
13 ast::{self, AstNode, AttrsOwner}, 14 ast::{self, AstNode, AttrsOwner},
14 match_ast, AstToken, SmolStr, SyntaxNode, 15 match_ast, AstToken, SmolStr, SyntaxNode,
@@ -134,53 +135,42 @@ impl RawAttrs {
134 let crate_graph = db.crate_graph(); 135 let crate_graph = db.crate_graph();
135 let new_attrs = self 136 let new_attrs = self
136 .iter() 137 .iter()
137 .filter_map(|attr| { 138 .flat_map(|attr| -> SmallVec<[_; 1]> {
138 let attr = attr.clone(); 139 let attr = attr.clone();
139 let is_cfg_attr = 140 let is_cfg_attr =
140 attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); 141 attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]);
141 if !is_cfg_attr { 142 if !is_cfg_attr {
142 return Some(attr); 143 return smallvec![attr];
143 } 144 }
144 145
145 let subtree = match &attr.input { 146 let subtree = match &attr.input {
146 Some(AttrInput::TokenTree(it)) => it, 147 Some(AttrInput::TokenTree(it)) => it,
147 _ => return Some(attr), 148 _ => return smallvec![attr],
148 }; 149 };
149 150
150 // Input subtree is: `(cfg, attr)` 151 // Input subtree is: `(cfg, $(attr),+)`
151 // Split it up into a `cfg` and an `attr` subtree. 152 // Split it up into a `cfg` subtree and the `attr` subtrees.
152 // FIXME: There should be a common API for this. 153 // FIXME: There should be a common API for this.
153 let mut saw_comma = false; 154 let mut parts = subtree.token_trees.split(
154 let (mut cfg, attr): (Vec<_>, Vec<_>) = 155 |tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ','),
155 subtree.clone().token_trees.into_iter().partition(|tree| { 156 );
156 if saw_comma { 157 let cfg = parts.next().unwrap();
157 return false; 158 let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() };
158 }
159
160 match tree {
161 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
162 saw_comma = true;
163 }
164 _ => {}
165 }
166
167 true
168 });
169 cfg.pop(); // `,` ends up in here
170
171 let attr = Subtree { delimiter: None, token_trees: attr };
172 let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg };
173 let cfg = CfgExpr::parse(&cfg); 159 let cfg = CfgExpr::parse(&cfg);
160 let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| {
161 let tree = Subtree { delimiter: None, token_trees: attr.to_vec() };
162 let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?;
163 let hygiene = Hygiene::new_unhygienic(); // FIXME
164 Attr::from_src(attr, &hygiene)
165 });
174 166
175 let cfg_options = &crate_graph[krate].cfg_options; 167 let cfg_options = &crate_graph[krate].cfg_options;
176 if cfg_options.check(&cfg) == Some(false) { 168 if cfg_options.check(&cfg) == Some(false) {
177 None 169 smallvec![]
178 } else { 170 } else {
179 cov_mark::hit!(cfg_attr_active); 171 cov_mark::hit!(cfg_attr_active);
180 172
181 let attr = ast::Attr::parse(&format!("#[{}]", attr)).ok()?; 173 attrs.collect()
182 let hygiene = Hygiene::new_unhygienic(); // FIXME
183 Attr::from_src(attr, &hygiene)
184 } 174 }
185 }) 175 })
186 .collect(); 176 .collect();
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 19c4eb521..8bcc350ce 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -253,11 +253,18 @@ pub type LabelSource = InFile<LabelPtr>;
253pub struct BodySourceMap { 253pub struct BodySourceMap {
254 expr_map: FxHashMap<ExprSource, ExprId>, 254 expr_map: FxHashMap<ExprSource, ExprId>,
255 expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>, 255 expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
256
256 pat_map: FxHashMap<PatSource, PatId>, 257 pat_map: FxHashMap<PatSource, PatId>,
257 pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, 258 pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
259
258 label_map: FxHashMap<LabelSource, LabelId>, 260 label_map: FxHashMap<LabelSource, LabelId>,
259 label_map_back: ArenaMap<LabelId, LabelSource>, 261 label_map_back: ArenaMap<LabelId, LabelSource>,
260 field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, 262
263 /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
264 /// Instead, we use id of expression (`92`) to identify the field.
265 field_map: FxHashMap<InFile<AstPtr<ast::RecordExprField>>, ExprId>,
266 field_map_back: FxHashMap<ExprId, InFile<AstPtr<ast::RecordExprField>>>,
267
261 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, 268 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
262 269
263 /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in 270 /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in
@@ -337,6 +344,8 @@ impl Index<LabelId> for Body {
337 } 344 }
338} 345}
339 346
347// FIXME: Change `node_` prefix to something more reasonable.
348// Perhaps `expr_syntax` and `expr_id`?
340impl BodySourceMap { 349impl BodySourceMap {
341 pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { 350 pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
342 self.expr_map_back[expr].clone() 351 self.expr_map_back[expr].clone()
@@ -375,8 +384,12 @@ impl BodySourceMap {
375 self.label_map.get(&src).cloned() 384 self.label_map.get(&src).cloned()
376 } 385 }
377 386
378 pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> { 387 pub fn field_syntax(&self, expr: ExprId) -> InFile<AstPtr<ast::RecordExprField>> {
379 self.field_map[&(expr, field)].clone() 388 self.field_map_back[&expr].clone()
389 }
390 pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> {
391 let src = node.map(|it| AstPtr::new(it));
392 self.field_map.get(&src).cloned()
380 } 393 }
381 394
382 pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) { 395 pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) {
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 8c8eb8007..8934ae6c9 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -379,23 +379,22 @@ impl ExprCollector<'_> {
379 } 379 }
380 ast::Expr::RecordExpr(e) => { 380 ast::Expr::RecordExpr(e) => {
381 let path = e.path().and_then(|path| self.expander.parse_path(path)); 381 let path = e.path().and_then(|path| self.expander.parse_path(path));
382 let mut field_ptrs = Vec::new();
383 let record_lit = if let Some(nfl) = e.record_expr_field_list() { 382 let record_lit = if let Some(nfl) = e.record_expr_field_list() {
384 let fields = nfl 383 let fields = nfl
385 .fields() 384 .fields()
386 .inspect(|field| field_ptrs.push(AstPtr::new(field)))
387 .filter_map(|field| { 385 .filter_map(|field| {
388 self.check_cfg(&field)?; 386 self.check_cfg(&field)?;
389 387
390 let name = field.field_name()?.as_name(); 388 let name = field.field_name()?.as_name();
391 389
392 Some(RecordLitField { 390 let expr = match field.expr() {
393 name, 391 Some(e) => self.collect_expr(e),
394 expr: match field.expr() { 392 None => self.missing_expr(),
395 Some(e) => self.collect_expr(e), 393 };
396 None => self.missing_expr(), 394 let src = self.expander.to_source(AstPtr::new(&field));
397 }, 395 self.source_map.field_map.insert(src.clone(), expr);
398 }) 396 self.source_map.field_map_back.insert(expr, src);
397 Some(RecordLitField { name, expr })
399 }) 398 })
400 .collect(); 399 .collect();
401 let spread = nfl.spread().map(|s| self.collect_expr(s)); 400 let spread = nfl.spread().map(|s| self.collect_expr(s));
@@ -404,12 +403,7 @@ impl ExprCollector<'_> {
404 Expr::RecordLit { path, fields: Vec::new(), spread: None } 403 Expr::RecordLit { path, fields: Vec::new(), spread: None }
405 }; 404 };
406 405
407 let res = self.alloc_expr(record_lit, syntax_ptr); 406 self.alloc_expr(record_lit, syntax_ptr)
408 for (i, ptr) in field_ptrs.into_iter().enumerate() {
409 let src = self.expander.to_source(ptr);
410 self.source_map.field_map.insert((res, i), src);
411 }
412 res
413 } 407 }
414 ast::Expr::FieldExpr(e) => { 408 ast::Expr::FieldExpr(e) => {
415 let expr = self.collect_expr_opt(e.expr()); 409 let expr = self.collect_expr_opt(e.expr());
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 6bb334573..09bcb10dc 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -209,18 +209,6 @@ impl ItemTree {
209 } 209 }
210 } 210 }
211 211
212 pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source {
213 // This unwrap cannot fail, since it has either succeeded above, or resulted in an empty
214 // ItemTree (in which case there is no valid `FileItemTreeId` to call this method with).
215 let root =
216 db.parse_or_expand(of.file_id).expect("parse_or_expand failed on constructed ItemTree");
217
218 let id = self[of.value].ast_id();
219 let map = db.ast_id_map(of.file_id);
220 let ptr = map.get(id);
221 ptr.to_node(&root)
222 }
223
224 fn data(&self) -> &ItemTreeData { 212 fn data(&self) -> &ItemTreeData {
225 self.data.as_ref().expect("attempted to access data of empty ItemTree") 213 self.data.as_ref().expect("attempted to access data of empty ItemTree")
226 } 214 }
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 6d11c5be4..c6655c5fb 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -341,6 +341,16 @@ pub enum DefWithBodyId {
341 341
342impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); 342impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
343 343
344impl DefWithBodyId {
345 pub fn as_generic_def_id(self) -> Option<GenericDefId> {
346 match self {
347 DefWithBodyId::FunctionId(f) => Some(f.into()),
348 DefWithBodyId::StaticId(_) => None,
349 DefWithBodyId::ConstId(c) => Some(c.into()),
350 }
351 }
352}
353
344#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 354#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
345pub enum AssocItemId { 355pub enum AssocItemId {
346 FunctionId(FunctionId), 356 FunctionId(FunctionId),
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs
index bfc1ab13f..c22ef46fd 100644
--- a/crates/hir_def/src/nameres/tests/diagnostics.rs
+++ b/crates/hir_def/src/nameres/tests/diagnostics.rs
@@ -149,6 +149,9 @@ fn inactive_via_cfg_attr() {
149 #[cfg_attr(not(never), cfg(not(no)))] fn f() {} 149 #[cfg_attr(not(never), cfg(not(no)))] fn f() {}
150 150
151 #[cfg_attr(never, cfg(no))] fn g() {} 151 #[cfg_attr(never, cfg(no))] fn g() {}
152
153 #[cfg_attr(not(never), inline, cfg(no))] fn h() {}
154 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: no is disabled
152 "#, 155 "#,
153 ); 156 );
154} 157}
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
index eda982c85..10977761c 100644
--- a/crates/hir_def/src/test_db.rs
+++ b/crates/hir_def/src/test_db.rs
@@ -15,7 +15,7 @@ use rustc_hash::FxHashSet;
15use syntax::{algo, ast, AstNode, TextRange, TextSize}; 15use syntax::{algo, ast, AstNode, TextRange, TextSize};
16use test_utils::extract_annotations; 16use test_utils::extract_annotations;
17 17
18use crate::{db::DefDatabase, nameres::DefMap, Lookup, ModuleDefId, ModuleId}; 18use crate::{db::DefDatabase, nameres::DefMap, src::HasSource, Lookup, ModuleDefId, ModuleId};
19 19
20#[salsa::database( 20#[salsa::database(
21 base_db::SourceDatabaseExtStorage, 21 base_db::SourceDatabaseExtStorage,
@@ -115,14 +115,9 @@ impl TestDB {
115 if file_id != position.file_id.into() { 115 if file_id != position.file_id.into() {
116 continue; 116 continue;
117 } 117 }
118 let root = self.parse_or_expand(file_id).unwrap();
119 let ast_map = self.ast_id_map(file_id);
120 let item_tree = self.item_tree(file_id);
121 for decl in module.scope.declarations() { 118 for decl in module.scope.declarations() {
122 if let ModuleDefId::FunctionId(it) = decl { 119 if let ModuleDefId::FunctionId(it) = decl {
123 let ast = 120 let range = it.lookup(self).source(self).value.syntax().text_range();
124 ast_map.get(item_tree[it.lookup(self).id.value].ast_id).to_node(&root);
125 let range = ast.syntax().text_range();
126 121
127 if !range.contains(position.offset) { 122 if !range.contains(position.offset) {
128 continue; 123 continue;
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs
index dfdb9cf59..5e908b223 100644
--- a/crates/hir_expand/src/builtin_derive.rs
+++ b/crates/hir_expand/src/builtin_derive.rs
@@ -108,7 +108,7 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, mbe::ExpandError> {
108} 108}
109 109
110fn make_type_args(n: usize, bound: Vec<tt::TokenTree>) -> Vec<tt::TokenTree> { 110fn make_type_args(n: usize, bound: Vec<tt::TokenTree>) -> Vec<tt::TokenTree> {
111 let mut result = Vec::<tt::TokenTree>::new(); 111 let mut result = Vec::<tt::TokenTree>::with_capacity(n * 2);
112 result.push( 112 result.push(
113 tt::Leaf::Punct(tt::Punct { 113 tt::Leaf::Punct(tt::Punct {
114 char: '<', 114 char: '<',
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index cb6e23320..9086e6c17 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -340,6 +340,8 @@ fn parse_macro_with_arg(
340 None => return ExpandResult { value: None, err: result.err }, 340 None => return ExpandResult { value: None, err: result.err },
341 }; 341 };
342 342
343 log::debug!("expanded = {}", tt.as_debug_string());
344
343 let fragment_kind = to_fragment_kind(db, macro_call_id); 345 let fragment_kind = to_fragment_kind(db, macro_call_id);
344 346
345 let (parse, rev_token_map) = match mbe::token_tree_to_syntax_node(&tt, fragment_kind) { 347 let (parse, rev_token_map) = match mbe::token_tree_to_syntax_node(&tt, fragment_kind) {
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index e833e032c..43de9edd6 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -191,6 +191,8 @@ pub mod known {
191 filter_map, 191 filter_map,
192 next, 192 next,
193 iter_mut, 193 iter_mut,
194 len,
195 is_empty,
194 // Builtin macros 196 // Builtin macros
195 file, 197 file,
196 column, 198 column,
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index b9c93f56f..0ef27cd37 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2018"
10doctest = false 10doctest = false
11 11
12[dependencies] 12[dependencies]
13cov-mark = "1.1" 13cov-mark = { version = "1.1", features = ["thread-local"] }
14itertools = "0.10.0" 14itertools = "0.10.0"
15arrayvec = "0.5.1" 15arrayvec = "0.5.1"
16smallvec = "1.2.0" 16smallvec = "1.2.0"
@@ -31,7 +31,7 @@ profile = { path = "../profile", version = "0.0.0" }
31syntax = { path = "../syntax", version = "0.0.0" } 31syntax = { path = "../syntax", version = "0.0.0" }
32 32
33[dev-dependencies] 33[dev-dependencies]
34test_utils = { path = "../test_utils" } 34test_utils = { path = "../test_utils" }
35expect-test = "1.1" 35expect-test = "1.1"
36tracing = "0.1" 36tracing = "0.1"
37tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } 37tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index be1fd1f13..56c6b92d4 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -12,9 +12,10 @@ use log::{info, warn};
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 to_assoc_type_id,
15 traits::{InEnvironment, Solution}, 16 traits::{InEnvironment, Solution},
16 utils::generics, 17 utils::generics,
17 BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty, 18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind,
18}; 19};
19 20
20const AUTODEREF_RECURSION_LIMIT: usize = 10; 21const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -81,8 +82,12 @@ fn deref_by_trait(
81 82
82 // Now do the assoc type projection 83 // Now do the assoc type projection
83 let projection = super::traits::ProjectionPredicate { 84 let projection = super::traits::ProjectionPredicate {
84 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), 85 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
85 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 86 .intern(&Interner),
87 projection_ty: super::ProjectionTy {
88 associated_ty_id: to_assoc_type_id(target),
89 substitution: parameters,
90 },
86 }; 91 };
87 92
88 let obligation = super::Obligation::Projection(projection); 93 let obligation = super::Obligation::Projection(projection);
@@ -114,8 +119,8 @@ fn deref_by_trait(
114 // new variables in that case 119 // new variables in that case
115 120
116 for i in 1..vars.0.kinds.len() { 121 for i in 1..vars.0.kinds.len() {
117 if vars.0.value[i - 1] 122 if vars.0.value[i - 1].interned(&Interner)
118 != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 123 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
119 { 124 {
120 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 125 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
121 return None; 126 return None;
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 06714409f..74a048672 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -12,7 +12,7 @@ use la_arena::ArenaMap;
12use crate::{ 12use crate::{
13 method_resolution::{InherentImpls, TraitImpls}, 13 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 14 traits::chalk,
15 Binders, CallableDefId, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig, 15 Binders, CallableDefId, FnDefId, GenericPredicate, ImplTraitId, InferenceResult, PolyFnSig,
16 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, 16 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
17}; 17};
18use hir_expand::name::Name; 18use hir_expand::name::Name;
@@ -65,6 +65,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
65 #[salsa::invoke(crate::lower::generic_predicates_query)] 65 #[salsa::invoke(crate::lower::generic_predicates_query)]
66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; 66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>;
67 67
68 #[salsa::invoke(crate::lower::trait_environment_query)]
69 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
70
68 #[salsa::invoke(crate::lower::generic_defaults_query)] 71 #[salsa::invoke(crate::lower::generic_defaults_query)]
69 fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; 72 fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>;
70 73
@@ -81,11 +84,11 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
81 #[salsa::interned] 84 #[salsa::interned]
82 fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; 85 fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId;
83 #[salsa::interned] 86 #[salsa::interned]
84 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; 87 fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId;
85 #[salsa::interned] 88 #[salsa::interned]
86 fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; 89 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
87 #[salsa::interned] 90 #[salsa::interned]
88 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> ClosureId; 91 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
89 92
90 #[salsa::invoke(chalk::associated_ty_data_query)] 93 #[salsa::invoke(chalk::associated_ty_data_query)]
91 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; 94 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>;
@@ -100,10 +103,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
100 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; 103 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
101 104
102 #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] 105 #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)]
103 fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc<chalk::FnDefDatum>; 106 fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>;
104 107
105 #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] 108 #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)]
106 fn fn_def_variance(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> chalk::Variances; 109 fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances;
107 110
108 #[salsa::invoke(crate::traits::chalk::adt_variance_query)] 111 #[salsa::invoke(crate::traits::chalk::adt_variance_query)]
109 fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; 112 fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances;
@@ -149,16 +152,16 @@ fn hir_database_is_object_safe() {
149} 152}
150 153
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub struct GlobalTypeParamId(salsa::InternId); 155pub struct InternedTypeParamId(salsa::InternId);
153impl_intern_key!(GlobalTypeParamId); 156impl_intern_key!(InternedTypeParamId);
154 157
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 158#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156pub struct InternedOpaqueTyId(salsa::InternId); 159pub struct InternedOpaqueTyId(salsa::InternId);
157impl_intern_key!(InternedOpaqueTyId); 160impl_intern_key!(InternedOpaqueTyId);
158 161
159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
160pub struct ClosureId(salsa::InternId); 163pub struct InternedClosureId(salsa::InternId);
161impl_intern_key!(ClosureId); 164impl_intern_key!(InternedClosureId);
162 165
163/// This exists just for Chalk, because Chalk just has a single `FnDefId` where 166/// This exists just for Chalk, because Chalk just has a single `FnDefId` where
164/// we have different IDs for struct and enum variant constructors. 167/// we have different IDs for struct and enum variant constructors.
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 2751cd304..b2bfd68d4 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -15,7 +15,7 @@ use crate::{
15 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
16 }, 16 },
17 utils::variant_data, 17 utils::variant_data,
18 AdtId, InferenceResult, Ty, 18 AdtId, InferenceResult, Interner, Ty, TyKind,
19}; 19};
20 20
21pub(crate) use hir_def::{ 21pub(crate) use hir_def::{
@@ -289,11 +289,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
289 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = 289 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
290 db.body_with_source_map(self.owner.into()); 290 db.body_with_source_map(self.owner.into());
291 291
292 let match_expr_ty = match infer.type_of_expr.get(match_expr) { 292 let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() {
293 // If we can't resolve the type of the match expression 293 return;
294 // we cannot perform exhaustiveness checks. 294 } else {
295 None | Some(Ty::Unknown) => return, 295 &infer.type_of_expr[match_expr]
296 Some(ty) => ty,
297 }; 296 };
298 297
299 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; 298 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db };
@@ -379,14 +378,14 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
379 _ => return, 378 _ => return,
380 }; 379 };
381 380
382 let (params, required) = match mismatch.expected { 381 let (params, required) = match mismatch.expected.interned(&Interner) {
383 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
384 if enum_id == core_result_enum => 383 if *enum_id == core_result_enum =>
385 { 384 {
386 (parameters, "Ok".to_string()) 385 (parameters, "Ok".to_string())
387 } 386 }
388 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 387 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
389 if enum_id == core_option_enum => 388 if *enum_id == core_option_enum =>
390 { 389 {
391 (parameters, "Some".to_string()) 390 (parameters, "Some".to_string())
392 } 391 }
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 04d39c571..5a5cdcbf3 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -227,7 +227,7 @@ use hir_def::{
227use la_arena::Idx; 227use la_arena::Idx;
228use smallvec::{smallvec, SmallVec}; 228use smallvec::{smallvec, SmallVec};
229 229
230use crate::{db::HirDatabase, AdtId, InferenceResult, Ty}; 230use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyKind};
231 231
232#[derive(Debug, Clone, Copy)] 232#[derive(Debug, Clone, Copy)]
233/// Either a pattern from the source code being analyzed, represented as 233/// Either a pattern from the source code being analyzed, represented as
@@ -626,13 +626,13 @@ pub(super) fn is_useful(
626 // - enum with no variants 626 // - enum with no variants
627 // - `!` type 627 // - `!` type
628 // In those cases, no match arm is useful. 628 // In those cases, no match arm is useful.
629 match cx.infer[cx.match_expr].strip_references() { 629 match cx.infer[cx.match_expr].strip_references().interned(&Interner) {
630 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { 630 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => {
631 if cx.db.enum_data(*enum_id).variants.is_empty() { 631 if cx.db.enum_data(*enum_id).variants.is_empty() {
632 return Ok(Usefulness::NotUseful); 632 return Ok(Usefulness::NotUseful);
633 } 633 }
634 } 634 }
635 Ty::Never => return Ok(Usefulness::NotUseful), 635 TyKind::Never => return Ok(Usefulness::NotUseful),
636 _ => (), 636 _ => (),
637 } 637 }
638 638
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index e77a20fea..20bb64827 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -11,7 +11,7 @@ use hir_def::{
11}; 11};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty}; 14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyKind};
15 15
16pub(super) struct UnsafeValidator<'a, 'b: 'a> { 16pub(super) struct UnsafeValidator<'a, 'b: 'a> {
17 owner: DefWithBodyId, 17 owner: DefWithBodyId,
@@ -85,7 +85,7 @@ fn walk_unsafe(
85 let expr = &body.exprs[current]; 85 let expr = &body.exprs[current];
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def() { 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).is_unsafe {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
@@ -110,7 +110,7 @@ fn walk_unsafe(
110 } 110 }
111 } 111 }
112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
113 if let Ty::Raw(..) = &infer[*expr] { 113 if let TyKind::Raw(..) = &infer[*expr].interned(&Interner) {
114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
115 } 115 }
116 } 116 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index ab51cb0a6..c1062387e 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -11,9 +11,10 @@ use hir_def::{
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig, 14 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
15 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, 15 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
16 TraitRef, Ty, 16 CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
17 ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind,
17}; 18};
18 19
19pub struct HirFormatter<'a> { 20pub struct HirFormatter<'a> {
@@ -244,19 +245,19 @@ impl HirDisplay for ProjectionTy {
244 } 245 }
245 246
246 let trait_ = f.db.trait_data(self.trait_(f.db)); 247 let trait_ = f.db.trait_data(self.trait_(f.db));
247 let first_parameter = self.parameters[0].into_displayable( 248 let first_parameter = self.substitution[0].into_displayable(
248 f.db, 249 f.db,
249 f.max_size, 250 f.max_size,
250 f.omit_verbose_types, 251 f.omit_verbose_types,
251 f.display_target, 252 f.display_target,
252 ); 253 );
253 write!(f, "<{} as {}", first_parameter, trait_.name)?; 254 write!(f, "<{} as {}", first_parameter, trait_.name)?;
254 if self.parameters.len() > 1 { 255 if self.substitution.len() > 1 {
255 write!(f, "<")?; 256 write!(f, "<")?;
256 f.write_joined(&self.parameters[1..], ", ")?; 257 f.write_joined(&self.substitution[1..], ", ")?;
257 write!(f, ">")?; 258 write!(f, ">")?;
258 } 259 }
259 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; 260 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
260 Ok(()) 261 Ok(())
261 } 262 }
262} 263}
@@ -267,32 +268,29 @@ impl HirDisplay for Ty {
267 return write!(f, "{}", TYPE_HINT_TRUNCATION); 268 return write!(f, "{}", TYPE_HINT_TRUNCATION);
268 } 269 }
269 270
270 match self { 271 match self.interned(&Interner) {
271 Ty::Never => write!(f, "!")?, 272 TyKind::Never => write!(f, "!")?,
272 Ty::Str => write!(f, "str")?, 273 TyKind::Str => write!(f, "str")?,
273 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, 274 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?,
274 Ty::Scalar(Scalar::Char) => write!(f, "char")?, 275 TyKind::Scalar(Scalar::Char) => write!(f, "char")?,
275 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, 276 &TyKind::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
276 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, 277 &TyKind::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
277 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, 278 &TyKind::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
278 Ty::Slice(parameters) => { 279 TyKind::Slice(t) => {
279 let t = parameters.as_single();
280 write!(f, "[")?; 280 write!(f, "[")?;
281 t.hir_fmt(f)?; 281 t.hir_fmt(f)?;
282 write!(f, "]")?; 282 write!(f, "]")?;
283 } 283 }
284 Ty::Array(parameters) => { 284 TyKind::Array(t) => {
285 let t = parameters.as_single();
286 write!(f, "[")?; 285 write!(f, "[")?;
287 t.hir_fmt(f)?; 286 t.hir_fmt(f)?;
288 write!(f, "; _]")?; 287 write!(f, "; _]")?;
289 } 288 }
290 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { 289 TyKind::Raw(m, t) | TyKind::Ref(m, t) => {
291 let t = parameters.as_single();
292 let ty_display = 290 let ty_display =
293 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 291 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
294 292
295 if matches!(self, Ty::Raw(..)) { 293 if matches!(self.interned(&Interner), TyKind::Raw(..)) {
296 write!( 294 write!(
297 f, 295 f,
298 "*{}", 296 "*{}",
@@ -312,22 +310,29 @@ impl HirDisplay for Ty {
312 )?; 310 )?;
313 } 311 }
314 312
313 // FIXME: all this just to decide whether to use parentheses...
315 let datas; 314 let datas;
316 let predicates = match t { 315 let predicates = match t.interned(&Interner) {
317 Ty::Dyn(predicates) if predicates.len() > 1 => { 316 TyKind::Dyn(predicates) if predicates.len() > 1 => {
318 Cow::Borrowed(predicates.as_ref()) 317 Cow::Borrowed(predicates.as_ref())
319 } 318 }
320 &Ty::Alias(AliasTy::Opaque(OpaqueTy { 319 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
321 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 320 opaque_ty_id,
322 ref parameters, 321 substitution: ref parameters,
323 })) => { 322 })) => {
324 datas = 323 let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into());
325 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 324 if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
326 let data = (*datas) 325 datas =
327 .as_ref() 326 f.db.return_type_impl_traits(func)
328 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 327 .expect("impl trait id without data");
329 let bounds = data.subst(parameters); 328 let data = (*datas)
330 Cow::Owned(bounds.value) 329 .as_ref()
330 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
331 let bounds = data.subst(parameters);
332 Cow::Owned(bounds.value)
333 } else {
334 Cow::Borrowed(&[][..])
335 }
331 } 336 }
332 _ => Cow::Borrowed(&[][..]), 337 _ => Cow::Borrowed(&[][..]),
333 }; 338 };
@@ -347,7 +352,7 @@ impl HirDisplay for Ty {
347 write!(f, "{}", ty_display)?; 352 write!(f, "{}", ty_display)?;
348 } 353 }
349 } 354 }
350 Ty::Tuple(_, substs) => { 355 TyKind::Tuple(_, substs) => {
351 if substs.len() == 1 { 356 if substs.len() == 1 {
352 write!(f, "(")?; 357 write!(f, "(")?;
353 substs[0].hir_fmt(f)?; 358 substs[0].hir_fmt(f)?;
@@ -358,12 +363,12 @@ impl HirDisplay for Ty {
358 write!(f, ")")?; 363 write!(f, ")")?;
359 } 364 }
360 } 365 }
361 Ty::Function(fn_ptr) => { 366 TyKind::Function(fn_ptr) => {
362 let sig = CallableSig::from_fn_ptr(fn_ptr); 367 let sig = CallableSig::from_fn_ptr(fn_ptr);
363 sig.hir_fmt(f)?; 368 sig.hir_fmt(f)?;
364 } 369 }
365 Ty::FnDef(def, parameters) => { 370 TyKind::FnDef(def, parameters) => {
366 let def = *def; 371 let def = from_chalk(f.db, *def);
367 let sig = f.db.callable_item_signature(def).subst(parameters); 372 let sig = f.db.callable_item_signature(def).subst(parameters);
368 match def { 373 match def {
369 CallableDefId::FunctionId(ff) => { 374 CallableDefId::FunctionId(ff) => {
@@ -401,7 +406,7 @@ impl HirDisplay for Ty {
401 write!(f, " -> {}", ret_display)?; 406 write!(f, " -> {}", ret_display)?;
402 } 407 }
403 } 408 }
404 Ty::Adt(AdtId(def_id), parameters) => { 409 TyKind::Adt(AdtId(def_id), parameters) => {
405 match f.display_target { 410 match f.display_target {
406 DisplayTarget::Diagnostics | DisplayTarget::Test => { 411 DisplayTarget::Diagnostics | DisplayTarget::Test => {
407 let name = match *def_id { 412 let name = match *def_id {
@@ -427,37 +432,39 @@ impl HirDisplay for Ty {
427 } 432 }
428 433
429 if parameters.len() > 0 { 434 if parameters.len() > 0 {
430 let parameters_to_write = 435 let parameters_to_write = if f.display_target.is_source_code()
431 if f.display_target.is_source_code() || f.omit_verbose_types() { 436 || f.omit_verbose_types()
432 match self 437 {
433 .as_generic_def() 438 match self
434 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 439 .as_generic_def(f.db)
435 .filter(|defaults| !defaults.is_empty()) 440 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
436 { 441 .filter(|defaults| !defaults.is_empty())
437 None => parameters.0.as_ref(), 442 {
438 Some(default_parameters) => { 443 None => parameters.0.as_ref(),
439 let mut default_from = 0; 444 Some(default_parameters) => {
440 for (i, parameter) in parameters.iter().enumerate() { 445 let mut default_from = 0;
441 match (parameter, default_parameters.get(i)) { 446 for (i, parameter) in parameters.iter().enumerate() {
442 (&Ty::Unknown, _) | (_, None) => { 447 match (parameter.interned(&Interner), default_parameters.get(i))
448 {
449 (&TyKind::Unknown, _) | (_, None) => {
450 default_from = i + 1;
451 }
452 (_, Some(default_parameter)) => {
453 let actual_default = default_parameter
454 .clone()
455 .subst(&parameters.prefix(i));
456 if parameter != &actual_default {
443 default_from = i + 1; 457 default_from = i + 1;
444 } 458 }
445 (_, Some(default_parameter)) => {
446 let actual_default = default_parameter
447 .clone()
448 .subst(&parameters.prefix(i));
449 if parameter != &actual_default {
450 default_from = i + 1;
451 }
452 }
453 } 459 }
454 } 460 }
455 &parameters.0[0..default_from]
456 } 461 }
462 &parameters.0[0..default_from]
457 } 463 }
458 } else { 464 }
459 parameters.0.as_ref() 465 } else {
460 }; 466 parameters.0.as_ref()
467 };
461 if !parameters_to_write.is_empty() { 468 if !parameters_to_write.is_empty() {
462 write!(f, "<")?; 469 write!(f, "<")?;
463 f.write_joined(parameters_to_write, ", ")?; 470 f.write_joined(parameters_to_write, ", ")?;
@@ -465,13 +472,14 @@ impl HirDisplay for Ty {
465 } 472 }
466 } 473 }
467 } 474 }
468 Ty::AssociatedType(type_alias, parameters) => { 475 TyKind::AssociatedType(assoc_type_id, parameters) => {
476 let type_alias = from_assoc_type_id(*assoc_type_id);
469 let trait_ = match type_alias.lookup(f.db.upcast()).container { 477 let trait_ = match type_alias.lookup(f.db.upcast()).container {
470 AssocContainerId::TraitId(it) => it, 478 AssocContainerId::TraitId(it) => it,
471 _ => panic!("not an associated type"), 479 _ => panic!("not an associated type"),
472 }; 480 };
473 let trait_ = f.db.trait_data(trait_); 481 let trait_ = f.db.trait_data(trait_);
474 let type_alias_data = f.db.type_alias_data(*type_alias); 482 let type_alias_data = f.db.type_alias_data(type_alias);
475 483
476 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 484 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
477 if f.display_target.is_test() { 485 if f.display_target.is_test() {
@@ -482,19 +490,22 @@ impl HirDisplay for Ty {
482 write!(f, ">")?; 490 write!(f, ">")?;
483 } 491 }
484 } else { 492 } else {
485 let projection_ty = 493 let projection_ty = ProjectionTy {
486 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; 494 associated_ty_id: to_assoc_type_id(type_alias),
495 substitution: parameters.clone(),
496 };
487 497
488 projection_ty.hir_fmt(f)?; 498 projection_ty.hir_fmt(f)?;
489 } 499 }
490 } 500 }
491 Ty::ForeignType(type_alias) => { 501 TyKind::ForeignType(type_alias) => {
492 let type_alias = f.db.type_alias_data(*type_alias); 502 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias));
493 write!(f, "{}", type_alias.name)?; 503 write!(f, "{}", type_alias.name)?;
494 } 504 }
495 Ty::OpaqueType(opaque_ty_id, parameters) => { 505 TyKind::OpaqueType(opaque_ty_id, parameters) => {
496 match opaque_ty_id { 506 let impl_trait_id = f.db.lookup_intern_impl_trait_id((*opaque_ty_id).into());
497 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 507 match impl_trait_id {
508 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
498 let datas = 509 let datas =
499 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 510 f.db.return_type_impl_traits(func).expect("impl trait id without data");
500 let data = (*datas) 511 let data = (*datas)
@@ -504,14 +515,14 @@ impl HirDisplay for Ty {
504 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 515 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
505 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 516 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
506 } 517 }
507 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 518 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
508 write!(f, "impl Future<Output = ")?; 519 write!(f, "impl Future<Output = ")?;
509 parameters[0].hir_fmt(f)?; 520 parameters[0].hir_fmt(f)?;
510 write!(f, ">")?; 521 write!(f, ">")?;
511 } 522 }
512 } 523 }
513 } 524 }
514 Ty::Closure(.., substs) => { 525 TyKind::Closure(.., substs) => {
515 let sig = substs[0].callable_sig(f.db); 526 let sig = substs[0].callable_sig(f.db);
516 if let Some(sig) = sig { 527 if let Some(sig) = sig {
517 if sig.params().is_empty() { 528 if sig.params().is_empty() {
@@ -535,7 +546,8 @@ impl HirDisplay for Ty {
535 write!(f, "{{closure}}")?; 546 write!(f, "{{closure}}")?;
536 } 547 }
537 } 548 }
538 Ty::Placeholder(id) => { 549 TyKind::Placeholder(idx) => {
550 let id = from_placeholder_idx(f.db, *idx);
539 let generics = generics(f.db.upcast(), id.parent); 551 let generics = generics(f.db.upcast(), id.parent);
540 let param_data = &generics.params.types[id.local_id]; 552 let param_data = &generics.params.types[id.local_id];
541 match param_data.provenance { 553 match param_data.provenance {
@@ -543,8 +555,8 @@ impl HirDisplay for Ty {
543 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 555 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
544 } 556 }
545 TypeParamProvenance::ArgumentImplTrait => { 557 TypeParamProvenance::ArgumentImplTrait => {
546 let bounds = f.db.generic_predicates_for_param(*id); 558 let bounds = f.db.generic_predicates_for_param(id);
547 let substs = Substs::type_params_for_generics(&generics); 559 let substs = Substs::type_params_for_generics(f.db, &generics);
548 write_bounds_like_dyn_trait_with_prefix( 560 write_bounds_like_dyn_trait_with_prefix(
549 "impl", 561 "impl",
550 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 562 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
@@ -553,28 +565,29 @@ impl HirDisplay for Ty {
553 } 565 }
554 } 566 }
555 } 567 }
556 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 568 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
557 Ty::Dyn(predicates) => { 569 TyKind::Dyn(predicates) => {
558 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 570 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
559 } 571 }
560 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 572 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
561 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 573 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
562 match opaque_ty.opaque_ty_id { 574 let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into());
563 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 575 match impl_trait_id {
576 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
564 let datas = 577 let datas =
565 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 578 f.db.return_type_impl_traits(func).expect("impl trait id without data");
566 let data = (*datas) 579 let data = (*datas)
567 .as_ref() 580 .as_ref()
568 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 581 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
569 let bounds = data.subst(&opaque_ty.parameters); 582 let bounds = data.subst(&opaque_ty.substitution);
570 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 583 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
571 } 584 }
572 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 585 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
573 write!(f, "{{async block}}")?; 586 write!(f, "{{async block}}")?;
574 } 587 }
575 }; 588 };
576 } 589 }
577 Ty::Unknown => { 590 TyKind::Unknown => {
578 if f.display_target.is_source_code() { 591 if f.display_target.is_source_code() {
579 return Err(HirDisplayError::DisplaySourceCodeError( 592 return Err(HirDisplayError::DisplaySourceCodeError(
580 DisplaySourceCodeError::UnknownType, 593 DisplaySourceCodeError::UnknownType,
@@ -582,7 +595,7 @@ impl HirDisplay for Ty {
582 } 595 }
583 write!(f, "{{unknown}}")?; 596 write!(f, "{{unknown}}")?;
584 } 597 }
585 Ty::InferenceVar(..) => write!(f, "_")?, 598 TyKind::InferenceVar(..) => write!(f, "_")?,
586 } 599 }
587 Ok(()) 600 Ok(())
588 } 601 }
@@ -695,7 +708,9 @@ fn write_bounds_like_dyn_trait(
695 write!(f, "<")?; 708 write!(f, "<")?;
696 angle_open = true; 709 angle_open = true;
697 } 710 }
698 let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty); 711 let type_alias = f.db.type_alias_data(from_assoc_type_id(
712 projection_pred.projection_ty.associated_ty_id,
713 ));
699 write!(f, "{} = ", type_alias.name)?; 714 write!(f, "{} = ", type_alias.name)?;
700 projection_pred.ty.hir_fmt(f)?; 715 projection_pred.ty.hir_fmt(f)?;
701 } 716 }
@@ -766,7 +781,10 @@ impl HirDisplay for GenericPredicate {
766 write!( 781 write!(
767 f, 782 f,
768 ">::{} = ", 783 ">::{} = ",
769 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, 784 f.db.type_alias_data(from_assoc_type_id(
785 projection_pred.projection_ty.associated_ty_id
786 ))
787 .name,
770 )?; 788 )?;
771 projection_pred.ty.hir_fmt(f)?; 789 projection_pred.ty.hir_fmt(f)?;
772 } 790 }
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4d771a91e..9c385b845 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -41,7 +41,8 @@ use super::{
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45 to_assoc_type_id, AliasTy, Interner, TyKind,
45}; 46};
46 47
47pub(crate) use unify::unify; 48pub(crate) use unify::unify;
@@ -107,6 +108,17 @@ pub struct TypeMismatch {
107 pub actual: Ty, 108 pub actual: Ty,
108} 109}
109 110
111#[derive(Clone, PartialEq, Eq, Debug)]
112struct InternedStandardTypes {
113 unknown: Ty,
114}
115
116impl Default for InternedStandardTypes {
117 fn default() -> Self {
118 InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) }
119 }
120}
121
110/// The result of type inference: A mapping from expressions and patterns to types. 122/// The result of type inference: A mapping from expressions and patterns to types.
111#[derive(Clone, PartialEq, Eq, Debug, Default)] 123#[derive(Clone, PartialEq, Eq, Debug, Default)]
112pub struct InferenceResult { 124pub struct InferenceResult {
@@ -125,6 +137,8 @@ pub struct InferenceResult {
125 pub type_of_expr: ArenaMap<ExprId, Ty>, 137 pub type_of_expr: ArenaMap<ExprId, Ty>,
126 pub type_of_pat: ArenaMap<PatId, Ty>, 138 pub type_of_pat: ArenaMap<PatId, Ty>,
127 pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, 139 pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>,
140 /// Interned Unknown to return references to.
141 standard_types: InternedStandardTypes,
128} 142}
129 143
130impl InferenceResult { 144impl InferenceResult {
@@ -169,7 +183,7 @@ impl Index<ExprId> for InferenceResult {
169 type Output = Ty; 183 type Output = Ty;
170 184
171 fn index(&self, expr: ExprId) -> &Ty { 185 fn index(&self, expr: ExprId) -> &Ty {
172 self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) 186 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
173 } 187 }
174} 188}
175 189
@@ -177,7 +191,7 @@ impl Index<PatId> for InferenceResult {
177 type Output = Ty; 191 type Output = Ty;
178 192
179 fn index(&self, pat: PatId) -> &Ty { 193 fn index(&self, pat: PatId) -> &Ty {
180 self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) 194 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
181 } 195 }
182} 196}
183 197
@@ -226,8 +240,10 @@ impl<'a> InferenceContext<'a> {
226 result: InferenceResult::default(), 240 result: InferenceResult::default(),
227 table: unify::InferenceTable::new(), 241 table: unify::InferenceTable::new(),
228 obligations: Vec::default(), 242 obligations: Vec::default(),
229 return_ty: Ty::Unknown, // set in collect_fn_signature 243 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature
230 trait_env: TraitEnvironment::lower(db, &resolver), 244 trait_env: owner
245 .as_generic_def_id()
246 .map_or_else(Default::default, |d| db.trait_environment(d)),
231 db, 247 db,
232 owner, 248 owner,
233 body: db.body(owner), 249 body: db.body(owner),
@@ -237,15 +253,19 @@ impl<'a> InferenceContext<'a> {
237 } 253 }
238 } 254 }
239 255
256 fn err_ty(&self) -> Ty {
257 TyKind::Unknown.intern(&Interner)
258 }
259
240 fn resolve_all(mut self) -> InferenceResult { 260 fn resolve_all(mut self) -> InferenceResult {
241 // FIXME resolve obligations as well (use Guidance if necessary) 261 // FIXME resolve obligations as well (use Guidance if necessary)
242 let mut result = std::mem::take(&mut self.result); 262 let mut result = std::mem::take(&mut self.result);
243 for ty in result.type_of_expr.values_mut() { 263 for ty in result.type_of_expr.values_mut() {
244 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 264 let resolved = self.table.resolve_ty_completely(ty.clone());
245 *ty = resolved; 265 *ty = resolved;
246 } 266 }
247 for ty in result.type_of_pat.values_mut() { 267 for ty in result.type_of_pat.values_mut() {
248 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 268 let resolved = self.table.resolve_ty_completely(ty.clone());
249 *ty = resolved; 269 *ty = resolved;
250 } 270 }
251 result 271 result
@@ -287,7 +307,7 @@ impl<'a> InferenceContext<'a> {
287 // FIXME use right resolver for block 307 // FIXME use right resolver for block
288 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 308 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
289 .with_impl_trait_mode(impl_trait_mode); 309 .with_impl_trait_mode(impl_trait_mode);
290 let ty = Ty::from_hir(&ctx, type_ref); 310 let ty = ctx.lower_ty(type_ref);
291 let ty = self.insert_type_vars(ty); 311 let ty = self.insert_type_vars(ty);
292 self.normalize_associated_types_in(ty) 312 self.normalize_associated_types_in(ty)
293 } 313 }
@@ -298,8 +318,8 @@ impl<'a> InferenceContext<'a> {
298 318
299 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 319 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
300 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 320 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
301 match ty { 321 match ty.interned(&Interner) {
302 Ty::Unknown => self.table.new_type_var(), 322 TyKind::Unknown => self.table.new_type_var(),
303 _ => ty, 323 _ => ty,
304 } 324 }
305 } 325 }
@@ -377,13 +397,16 @@ impl<'a> InferenceContext<'a> {
377 let trait_ref = TraitRef { trait_, substs: substs.clone() }; 397 let trait_ref = TraitRef { trait_, substs: substs.clone() };
378 let projection = ProjectionPredicate { 398 let projection = ProjectionPredicate {
379 ty: ty.clone(), 399 ty: ty.clone(),
380 projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs }, 400 projection_ty: ProjectionTy {
401 associated_ty_id: to_assoc_type_id(res_assoc_ty),
402 substitution: substs,
403 },
381 }; 404 };
382 self.obligations.push(Obligation::Trait(trait_ref)); 405 self.obligations.push(Obligation::Trait(trait_ref));
383 self.obligations.push(Obligation::Projection(projection)); 406 self.obligations.push(Obligation::Projection(projection));
384 self.resolve_ty_as_possible(ty) 407 self.resolve_ty_as_possible(ty)
385 } 408 }
386 None => Ty::Unknown, 409 None => self.err_ty(),
387 } 410 }
388 } 411 }
389 412
@@ -395,8 +418,10 @@ impl<'a> InferenceContext<'a> {
395 /// to do it as well. 418 /// to do it as well.
396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 419 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
397 let ty = self.resolve_ty_as_possible(ty); 420 let ty = self.resolve_ty_as_possible(ty);
398 ty.fold(&mut |ty| match ty { 421 ty.fold(&mut |ty| match ty.interned(&Interner) {
399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), 422 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
423 self.normalize_projection_ty(proj_ty.clone())
424 }
400 _ => ty, 425 _ => ty,
401 }) 426 })
402 } 427 }
@@ -412,7 +437,7 @@ impl<'a> InferenceContext<'a> {
412 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 437 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
413 let path = match path { 438 let path = match path {
414 Some(path) => path, 439 Some(path) => path,
415 None => return (Ty::Unknown, None), 440 None => return (self.err_ty(), None),
416 }; 441 };
417 let resolver = &self.resolver; 442 let resolver = &self.resolver;
418 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 443 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
@@ -421,30 +446,30 @@ impl<'a> InferenceContext<'a> {
421 let (resolution, unresolved) = 446 let (resolution, unresolved) =
422 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { 447 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
423 Some(it) => it, 448 Some(it) => it,
424 None => return (Ty::Unknown, None), 449 None => return (self.err_ty(), None),
425 }; 450 };
426 return match resolution { 451 return match resolution {
427 TypeNs::AdtId(AdtId::StructId(strukt)) => { 452 TypeNs::AdtId(AdtId::StructId(strukt)) => {
428 let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true); 453 let substs = ctx.substs_from_path(path, strukt.into(), true);
429 let ty = self.db.ty(strukt.into()); 454 let ty = self.db.ty(strukt.into());
430 let ty = self.insert_type_vars(ty.subst(&substs)); 455 let ty = self.insert_type_vars(ty.subst(&substs));
431 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 456 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
432 } 457 }
433 TypeNs::AdtId(AdtId::UnionId(u)) => { 458 TypeNs::AdtId(AdtId::UnionId(u)) => {
434 let substs = Ty::substs_from_path(&ctx, path, u.into(), true); 459 let substs = ctx.substs_from_path(path, u.into(), true);
435 let ty = self.db.ty(u.into()); 460 let ty = self.db.ty(u.into());
436 let ty = self.insert_type_vars(ty.subst(&substs)); 461 let ty = self.insert_type_vars(ty.subst(&substs));
437 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 462 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
438 } 463 }
439 TypeNs::EnumVariantId(var) => { 464 TypeNs::EnumVariantId(var) => {
440 let substs = Ty::substs_from_path(&ctx, path, var.into(), true); 465 let substs = ctx.substs_from_path(path, var.into(), true);
441 let ty = self.db.ty(var.parent.into()); 466 let ty = self.db.ty(var.parent.into());
442 let ty = self.insert_type_vars(ty.subst(&substs)); 467 let ty = self.insert_type_vars(ty.subst(&substs));
443 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 468 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
444 } 469 }
445 TypeNs::SelfType(impl_id) => { 470 TypeNs::SelfType(impl_id) => {
446 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 471 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
447 let substs = Substs::type_params_for_generics(&generics); 472 let substs = Substs::type_params_for_generics(self.db, &generics);
448 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 473 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
449 match unresolved { 474 match unresolved {
450 None => { 475 None => {
@@ -462,11 +487,11 @@ impl<'a> InferenceContext<'a> {
462 } 487 }
463 } 488 }
464 // FIXME potentially resolve assoc type 489 // FIXME potentially resolve assoc type
465 (Ty::Unknown, None) 490 (self.err_ty(), None)
466 } 491 }
467 Some(_) => { 492 Some(_) => {
468 // FIXME diagnostic 493 // FIXME diagnostic
469 (Ty::Unknown, None) 494 (self.err_ty(), None)
470 } 495 }
471 } 496 }
472 } 497 }
@@ -480,15 +505,15 @@ impl<'a> InferenceContext<'a> {
480 } 505 }
481 TypeNs::AdtSelfType(_) => { 506 TypeNs::AdtSelfType(_) => {
482 // FIXME this could happen in array size expressions, once we're checking them 507 // FIXME this could happen in array size expressions, once we're checking them
483 (Ty::Unknown, None) 508 (self.err_ty(), None)
484 } 509 }
485 TypeNs::GenericParam(_) => { 510 TypeNs::GenericParam(_) => {
486 // FIXME potentially resolve assoc type 511 // FIXME potentially resolve assoc type
487 (Ty::Unknown, None) 512 (self.err_ty(), None)
488 } 513 }
489 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { 514 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => {
490 // FIXME diagnostic 515 // FIXME diagnostic
491 (Ty::Unknown, None) 516 (self.err_ty(), None)
492 } 517 }
493 }; 518 };
494 519
@@ -500,7 +525,7 @@ impl<'a> InferenceContext<'a> {
500 result 525 result
501 } else { 526 } else {
502 // FIXME diagnostic 527 // FIXME diagnostic
503 (Ty::Unknown, None) 528 (TyKind::Unknown.intern(&Interner), None)
504 } 529 }
505 } 530 }
506 531
@@ -529,7 +554,7 @@ impl<'a> InferenceContext<'a> {
529 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 554 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
530 .with_impl_trait_mode(ImplTraitLoweringMode::Param); 555 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
531 let param_tys = 556 let param_tys =
532 data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>(); 557 data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
533 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { 558 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
534 let ty = self.insert_type_vars(ty); 559 let ty = self.insert_type_vars(ty);
535 let ty = self.normalize_associated_types_in(ty); 560 let ty = self.normalize_associated_types_in(ty);
@@ -711,14 +736,19 @@ impl Expectation {
711 736
712 /// This expresses no expectation on the type. 737 /// This expresses no expectation on the type.
713 fn none() -> Self { 738 fn none() -> Self {
714 Expectation { ty: Ty::Unknown, rvalue_hint: false } 739 Expectation {
740 // FIXME
741 ty: TyKind::Unknown.intern(&Interner),
742 rvalue_hint: false,
743 }
715 } 744 }
716 745
717 fn coercion_target(&self) -> &Ty { 746 fn coercion_target(&self) -> Ty {
718 if self.rvalue_hint { 747 if self.rvalue_hint {
719 &Ty::Unknown 748 // FIXME
749 TyKind::Unknown.intern(&Interner)
720 } else { 750 } else {
721 &self.ty 751 self.ty.clone()
722 } 752 }
723 } 753 }
724} 754}
@@ -772,7 +802,7 @@ mod diagnostics {
772 802
773 #[derive(Debug, PartialEq, Eq, Clone)] 803 #[derive(Debug, PartialEq, Eq, Clone)]
774 pub(super) enum InferenceDiagnostic { 804 pub(super) enum InferenceDiagnostic {
775 NoSuchField { expr: ExprId, field: usize }, 805 NoSuchField { expr: ExprId },
776 BreakOutsideOfLoop { expr: ExprId }, 806 BreakOutsideOfLoop { expr: ExprId },
777 } 807 }
778 808
@@ -784,9 +814,9 @@ mod diagnostics {
784 sink: &mut DiagnosticSink, 814 sink: &mut DiagnosticSink,
785 ) { 815 ) {
786 match self { 816 match self {
787 InferenceDiagnostic::NoSuchField { expr, field } => { 817 InferenceDiagnostic::NoSuchField { expr } => {
788 let (_, source_map) = db.body_with_source_map(owner); 818 let (_, source_map) = db.body_with_source_map(owner);
789 let field = source_map.field_syntax(*expr, *field); 819 let field = source_map.field_syntax(*expr);
790 sink.push(NoSuchField { file: field.file_id, field: field.value }) 820 sink.push(NoSuchField { file: field.file_id, field: field.value })
791 } 821 }
792 InferenceDiagnostic::BreakOutsideOfLoop { expr } => { 822 InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 7e8846f27..137419264 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +7,7 @@
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, Obligation, Substs, TraitRef, Ty}; 10use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind};
11 11
12use super::{InEnvironment, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
13 13
@@ -33,7 +33,9 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 33 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 34 ty1.clone()
35 } else { 35 } else {
36 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { 36 if let (TyKind::FnDef(..), TyKind::FnDef(..)) =
37 (ty1.interned(&Interner), ty2.interned(&Interner))
38 {
37 cov_mark::hit!(coerce_fn_reification); 39 cov_mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 40 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 41 // pointers to have a chance at getting a match. See
@@ -51,13 +53,13 @@ impl<'a> InferenceContext<'a> {
51 } 53 }
52 54
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 55 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 56 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 57 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { 58 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => {
57 self.table.type_variable_table.set_diverging(*tv, true); 59 self.table.type_variable_table.set_diverging(*tv, true);
58 return true; 60 return true;
59 } 61 }
60 (Ty::Never, _) => return true, 62 (TyKind::Never, _) => return true,
61 63
62 // Trivial cases, this should go after `never` check to 64 // Trivial cases, this should go after `never` check to
63 // avoid infer result type to be never 65 // avoid infer result type to be never
@@ -69,33 +71,33 @@ impl<'a> InferenceContext<'a> {
69 } 71 }
70 72
71 // Pointer weakening and function to pointer 73 // Pointer weakening and function to pointer
72 match (&mut from_ty, to_ty) { 74 match (from_ty.interned_mut(), to_ty.interned(&Interner)) {
73 // `*mut T` -> `*const T` 75 // `*mut T` -> `*const T`
74 // `&mut T` -> `&T` 76 // `&mut T` -> `&T`
75 (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) 77 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..))
76 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { 78 | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => {
77 *m1 = *m2; 79 *m1 = *m2;
78 } 80 }
79 // `&T` -> `*const T` 81 // `&T` -> `*const T`
80 // `&mut T` -> `*mut T`/`*const T` 82 // `&mut T` -> `*mut T`/`*const T`
81 (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) 83 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..))
82 | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { 84 | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => {
83 from_ty = Ty::Raw(m2, substs.clone()); 85 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner);
84 } 86 }
85 87
86 // Illegal mutability conversion 88 // Illegal mutability conversion
87 (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) 89 (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..))
88 | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, 90 | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false,
89 91
90 // `{function_type}` -> `fn()` 92 // `{function_type}` -> `fn()`
91 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { 93 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) {
92 None => return false, 94 None => return false,
93 Some(sig) => { 95 Some(sig) => {
94 from_ty = Ty::fn_ptr(sig); 96 from_ty = Ty::fn_ptr(sig);
95 } 97 }
96 }, 98 },
97 99
98 (Ty::Closure(.., substs), Ty::Function { .. }) => { 100 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
99 from_ty = substs[0].clone(); 101 from_ty = substs[0].clone();
100 } 102 }
101 103
@@ -107,9 +109,9 @@ impl<'a> InferenceContext<'a> {
107 } 109 }
108 110
109 // Auto Deref if cannot coerce 111 // Auto Deref if cannot coerce
110 match (&from_ty, to_ty) { 112 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) {
111 // FIXME: DerefMut 113 // FIXME: DerefMut
112 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), 114 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2),
113 115
114 // Otherwise, normal unify 116 // Otherwise, normal unify
115 _ => self.unify(&from_ty, to_ty), 117 _ => self.unify(&from_ty, to_ty),
@@ -174,11 +176,7 @@ impl<'a> InferenceContext<'a> {
174 // Stop when constructor matches. 176 // Stop when constructor matches.
175 if from_ty.equals_ctor(&to_ty) { 177 if from_ty.equals_ctor(&to_ty) {
176 // It will not recurse to `coerce`. 178 // It will not recurse to `coerce`.
177 return match (from_ty.substs(), to_ty.substs()) { 179 return self.table.unify(&from_ty, &to_ty);
178 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
179 (None, None) => true,
180 _ => false,
181 };
182 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 180 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
183 return true; 181 return true;
184 } 182 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 262177ffb..f40dec17f 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,10 +18,11 @@ use crate::{
18 lower::lower_to_chalk_mutability, 18 lower::lower_to_chalk_mutability,
19 method_resolution, op, 19 method_resolution, op,
20 primitive::{self, UintTy}, 20 primitive::{self, UintTy},
21 traits::{FnTrait, InEnvironment}, 21 to_assoc_type_id,
22 traits::{chalk::from_chalk, FnTrait, InEnvironment},
22 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
23 AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, 24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs,
24 Substs, TraitRef, Ty, 25 TraitRef, Ty, TyKind,
25}; 26};
26 27
27use super::{ 28use super::{
@@ -57,7 +58,7 @@ impl<'a> InferenceContext<'a> {
57 // Return actual type when type mismatch. 58 // Return actual type when type mismatch.
58 // This is needed for diagnostic when return type mismatch. 59 // This is needed for diagnostic when return type mismatch.
59 ty 60 ty
60 } else if expected.coercion_target() == &Ty::Unknown { 61 } else if expected.coercion_target().is_unknown() {
61 ty 62 ty
62 } else { 63 } else {
63 expected.ty.clone() 64 expected.ty.clone()
@@ -84,7 +85,7 @@ impl<'a> InferenceContext<'a> {
84 arg_tys.push(arg); 85 arg_tys.push(arg);
85 } 86 }
86 let parameters = param_builder.build(); 87 let parameters = param_builder.build();
87 let arg_ty = Ty::Tuple(num_args, parameters); 88 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner);
88 let substs = 89 let substs =
89 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
90 91
@@ -97,8 +98,10 @@ impl<'a> InferenceContext<'a> {
97 }); 98 });
98 if self.db.trait_solve(krate, goal.value).is_some() { 99 if self.db.trait_solve(krate, goal.value).is_some() {
99 self.obligations.push(implements_fn_trait); 100 self.obligations.push(implements_fn_trait);
100 let output_proj_ty = 101 let output_proj_ty = crate::ProjectionTy {
101 crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; 102 associated_ty_id: to_assoc_type_id(output_assoc_type),
103 substitution: substs,
104 };
102 let return_ty = self.normalize_projection_ty(output_proj_ty); 105 let return_ty = self.normalize_projection_ty(output_proj_ty);
103 Some((arg_tys, return_ty)) 106 Some((arg_tys, return_ty))
104 } else { 107 } else {
@@ -116,10 +119,13 @@ impl<'a> InferenceContext<'a> {
116 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 119 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
117 let body = Arc::clone(&self.body); // avoid borrow checker problem 120 let body = Arc::clone(&self.body); // avoid borrow checker problem
118 let ty = match &body[tgt_expr] { 121 let ty = match &body[tgt_expr] {
119 Expr::Missing => Ty::Unknown, 122 Expr::Missing => self.err_ty(),
120 Expr::If { condition, then_branch, else_branch } => { 123 Expr::If { condition, then_branch, else_branch } => {
121 // if let is desugared to match, so this is always simple if 124 // if let is desugared to match, so this is always simple if
122 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); 125 self.infer_expr(
126 *condition,
127 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
128 );
123 129
124 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 130 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
125 let mut both_arms_diverge = Diverges::Always; 131 let mut both_arms_diverge = Diverges::Always;
@@ -167,14 +173,15 @@ impl<'a> InferenceContext<'a> {
167 Expr::TryBlock { body } => { 173 Expr::TryBlock { body } => {
168 let _inner = self.infer_expr(*body, expected); 174 let _inner = self.infer_expr(*body, expected);
169 // FIXME should be std::result::Result<{inner}, _> 175 // FIXME should be std::result::Result<{inner}, _>
170 Ty::Unknown 176 self.err_ty()
171 } 177 }
172 Expr::Async { body } => { 178 Expr::Async { body } => {
173 // Use the first type parameter as the output type of future. 179 // Use the first type parameter as the output type of future.
174 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 180 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
175 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
176 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
177 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) 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)
178 } 185 }
179 Expr::Loop { body, label } => { 186 Expr::Loop { body, label } => {
180 self.breakables.push(BreakableContext { 187 self.breakables.push(BreakableContext {
@@ -192,17 +199,20 @@ impl<'a> InferenceContext<'a> {
192 if ctxt.may_break { 199 if ctxt.may_break {
193 ctxt.break_ty 200 ctxt.break_ty
194 } else { 201 } else {
195 Ty::Never 202 TyKind::Never.intern(&Interner)
196 } 203 }
197 } 204 }
198 Expr::While { condition, body, label } => { 205 Expr::While { condition, body, label } => {
199 self.breakables.push(BreakableContext { 206 self.breakables.push(BreakableContext {
200 may_break: false, 207 may_break: false,
201 break_ty: Ty::Unknown, 208 break_ty: self.err_ty(),
202 label: label.map(|label| self.body[label].name.clone()), 209 label: label.map(|label| self.body[label].name.clone()),
203 }); 210 });
204 // while let is desugared to a match loop, so this is always simple while 211 // while let is desugared to a match loop, so this is always simple while
205 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); 212 self.infer_expr(
213 *condition,
214 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
215 );
206 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 216 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
207 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 217 let _ctxt = self.breakables.pop().expect("breakable stack broken");
208 // the body may not run, so it diverging doesn't mean we diverge 218 // the body may not run, so it diverging doesn't mean we diverge
@@ -214,7 +224,7 @@ impl<'a> InferenceContext<'a> {
214 224
215 self.breakables.push(BreakableContext { 225 self.breakables.push(BreakableContext {
216 may_break: false, 226 may_break: false,
217 break_ty: Ty::Unknown, 227 break_ty: self.err_ty(),
218 label: label.map(|label| self.body[label].name.clone()), 228 label: label.map(|label| self.body[label].name.clone()),
219 }); 229 });
220 let pat_ty = 230 let pat_ty =
@@ -249,12 +259,15 @@ impl<'a> InferenceContext<'a> {
249 None => self.table.new_type_var(), 259 None => self.table.new_type_var(),
250 }; 260 };
251 sig_tys.push(ret_ty.clone()); 261 sig_tys.push(ret_ty.clone());
252 let sig_ty = Ty::Function(FnPointer { 262 let sig_ty = TyKind::Function(FnPointer {
253 num_args: sig_tys.len() - 1, 263 num_args: sig_tys.len() - 1,
254 sig: FnSig { variadic: false }, 264 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
255 substs: Substs(sig_tys.clone().into()), 265 substs: Substs(sig_tys.clone().into()),
256 }); 266 })
257 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); 267 .intern(&Interner);
268 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
269 let closure_ty =
270 TyKind::Closure(closure_id, Substs::single(sig_ty)).intern(&Interner);
258 271
259 // Eagerly try to relate the closure type with the expected 272 // Eagerly try to relate the closure type with the expected
260 // type, otherwise we often won't have enough information to 273 // type, otherwise we often won't have enough information to
@@ -295,7 +308,7 @@ impl<'a> InferenceContext<'a> {
295 args.len(), 308 args.len(),
296 ) 309 )
297 }) 310 })
298 .unwrap_or((Vec::new(), Ty::Unknown)); 311 .unwrap_or((Vec::new(), self.err_ty()));
299 self.register_obligations_for_call(&callee_ty); 312 self.register_obligations_for_call(&callee_ty);
300 self.check_call_arguments(args, &param_tys); 313 self.check_call_arguments(args, &param_tys);
301 self.normalize_associated_types_in(ret_ty) 314 self.normalize_associated_types_in(ret_ty)
@@ -305,8 +318,11 @@ impl<'a> InferenceContext<'a> {
305 Expr::Match { expr, arms } => { 318 Expr::Match { expr, arms } => {
306 let input_ty = self.infer_expr(*expr, &Expectation::none()); 319 let input_ty = self.infer_expr(*expr, &Expectation::none());
307 320
308 let mut result_ty = 321 let mut result_ty = if arms.is_empty() {
309 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; 322 TyKind::Never.intern(&Interner)
323 } else {
324 self.table.new_type_var()
325 };
310 326
311 let matchee_diverges = self.diverges; 327 let matchee_diverges = self.diverges;
312 let mut all_arms_diverge = Diverges::Always; 328 let mut all_arms_diverge = Diverges::Always;
@@ -317,7 +333,7 @@ impl<'a> InferenceContext<'a> {
317 if let Some(guard_expr) = arm.guard { 333 if let Some(guard_expr) = arm.guard {
318 self.infer_expr( 334 self.infer_expr(
319 guard_expr, 335 guard_expr,
320 &Expectation::has_type(Ty::Scalar(Scalar::Bool)), 336 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
321 ); 337 );
322 } 338 }
323 339
@@ -333,9 +349,9 @@ impl<'a> InferenceContext<'a> {
333 Expr::Path(p) => { 349 Expr::Path(p) => {
334 // FIXME this could be more efficient... 350 // FIXME this could be more efficient...
335 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 351 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
336 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 352 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty())
337 } 353 }
338 Expr::Continue { .. } => Ty::Never, 354 Expr::Continue { .. } => TyKind::Never.intern(&Interner),
339 Expr::Break { expr, label } => { 355 Expr::Break { expr, label } => {
340 let val_ty = if let Some(expr) = expr { 356 let val_ty = if let Some(expr) = expr {
341 self.infer_expr(*expr, &Expectation::none()) 357 self.infer_expr(*expr, &Expectation::none())
@@ -347,7 +363,7 @@ impl<'a> InferenceContext<'a> {
347 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { 363 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
348 ctxt.break_ty.clone() 364 ctxt.break_ty.clone()
349 } else { 365 } else {
350 Ty::Unknown 366 self.err_ty()
351 }; 367 };
352 368
353 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); 369 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty);
@@ -360,7 +376,7 @@ impl<'a> InferenceContext<'a> {
360 expr: tgt_expr, 376 expr: tgt_expr,
361 }); 377 });
362 } 378 }
363 Ty::Never 379 TyKind::Never.intern(&Interner)
364 } 380 }
365 Expr::Return { expr } => { 381 Expr::Return { expr } => {
366 if let Some(expr) = expr { 382 if let Some(expr) = expr {
@@ -369,14 +385,14 @@ impl<'a> InferenceContext<'a> {
369 let unit = Ty::unit(); 385 let unit = Ty::unit();
370 self.coerce(&unit, &self.return_ty.clone()); 386 self.coerce(&unit, &self.return_ty.clone());
371 } 387 }
372 Ty::Never 388 TyKind::Never.intern(&Interner)
373 } 389 }
374 Expr::Yield { expr } => { 390 Expr::Yield { expr } => {
375 // FIXME: track yield type for coercion 391 // FIXME: track yield type for coercion
376 if let Some(expr) = expr { 392 if let Some(expr) = expr {
377 self.infer_expr(*expr, &Expectation::none()); 393 self.infer_expr(*expr, &Expectation::none());
378 } 394 }
379 Ty::Never 395 TyKind::Never.intern(&Interner)
380 } 396 }
381 Expr::RecordLit { path, fields, spread } => { 397 Expr::RecordLit { path, fields, spread } => {
382 let (ty, def_id) = self.resolve_variant(path.as_ref()); 398 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -389,14 +405,13 @@ impl<'a> InferenceContext<'a> {
389 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); 405 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
390 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();
391 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));
392 for (field_idx, field) in fields.iter().enumerate() { 408 for field in fields.iter() {
393 let field_def = 409 let field_def =
394 variant_data.as_ref().and_then(|it| match it.field(&field.name) { 410 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
395 Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), 411 Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }),
396 None => { 412 None => {
397 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 413 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
398 expr: tgt_expr, 414 expr: field.expr,
399 field: field_idx,
400 }); 415 });
401 None 416 None
402 } 417 }
@@ -404,8 +419,9 @@ impl<'a> InferenceContext<'a> {
404 if let Some(field_def) = field_def { 419 if let Some(field_def) = field_def {
405 self.result.record_field_resolutions.insert(field.expr, field_def); 420 self.result.record_field_resolutions.insert(field.expr, field_def);
406 } 421 }
407 let field_ty = field_def 422 let field_ty = field_def.map_or(self.err_ty(), |it| {
408 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); 423 field_types[it.local_id].clone().subst(&substs)
424 });
409 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 425 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
410 } 426 }
411 if let Some(expr) = spread { 427 if let Some(expr) = spread {
@@ -424,27 +440,33 @@ impl<'a> InferenceContext<'a> {
424 environment: self.trait_env.clone(), 440 environment: self.trait_env.clone(),
425 }, 441 },
426 ) 442 )
427 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 443 .find_map(|derefed_ty| {
428 Ty::Tuple(_, substs) => { 444 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
429 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 445 TyKind::Tuple(_, substs) => {
430 } 446 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
431 Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 447 }
432 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 448 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
433 let field = FieldId { parent: s.into(), local_id }; 449 self.db.struct_data(*s).variant_data.field(name).map(|local_id| {
434 self.write_field_resolution(tgt_expr, field); 450 let field = FieldId { parent: (*s).into(), local_id };
435 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters) 451 self.write_field_resolution(tgt_expr, field);
436 }) 452 self.db.field_types((*s).into())[field.local_id]
437 } 453 .clone()
438 Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { 454 .subst(&parameters)
439 self.db.union_data(u).variant_data.field(name).map(|local_id| { 455 })
440 let field = FieldId { parent: u.into(), local_id }; 456 }
441 self.write_field_resolution(tgt_expr, field); 457 TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
442 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters) 458 self.db.union_data(*u).variant_data.field(name).map(|local_id| {
443 }) 459 let field = FieldId { parent: (*u).into(), local_id };
460 self.write_field_resolution(tgt_expr, field);
461 self.db.field_types((*u).into())[field.local_id]
462 .clone()
463 .subst(&parameters)
464 })
465 }
466 _ => None,
444 } 467 }
445 _ => None,
446 }) 468 })
447 .unwrap_or(Ty::Unknown); 469 .unwrap_or(self.err_ty());
448 let ty = self.insert_type_vars(ty); 470 let ty = self.insert_type_vars(ty);
449 self.normalize_associated_types_in(ty) 471 self.normalize_associated_types_in(ty)
450 } 472 }
@@ -481,9 +503,10 @@ impl<'a> InferenceContext<'a> {
481 }; 503 };
482 let inner_ty = self.infer_expr_inner(*expr, &expectation); 504 let inner_ty = self.infer_expr_inner(*expr, &expectation);
483 match rawness { 505 match rawness {
484 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), 506 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
485 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), 507 Rawness::Ref => TyKind::Ref(mutability, inner_ty),
486 } 508 }
509 .intern(&Interner)
487 } 510 }
488 Expr::Box { expr } => { 511 Expr::Box { expr } => {
489 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 512 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
@@ -499,7 +522,7 @@ impl<'a> InferenceContext<'a> {
499 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 522 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
500 Ty::adt_ty(box_, sb.build()) 523 Ty::adt_ty(box_, sb.build())
501 } else { 524 } else {
502 Ty::Unknown 525 self.err_ty()
503 } 526 }
504 } 527 }
505 Expr::UnaryOp { expr, op } => { 528 Expr::UnaryOp { expr, op } => {
@@ -519,31 +542,31 @@ impl<'a> InferenceContext<'a> {
519 Some(derefed_ty) => { 542 Some(derefed_ty) => {
520 canonicalized.decanonicalize_ty(derefed_ty.value) 543 canonicalized.decanonicalize_ty(derefed_ty.value)
521 } 544 }
522 None => Ty::Unknown, 545 None => self.err_ty(),
523 } 546 }
524 } 547 }
525 None => Ty::Unknown, 548 None => self.err_ty(),
526 }, 549 },
527 UnaryOp::Neg => { 550 UnaryOp::Neg => {
528 match &inner_ty { 551 match inner_ty.interned(&Interner) {
529 // Fast path for builtins 552 // Fast path for builtins
530 Ty::Scalar(Scalar::Int(_)) 553 TyKind::Scalar(Scalar::Int(_))
531 | Ty::Scalar(Scalar::Uint(_)) 554 | TyKind::Scalar(Scalar::Uint(_))
532 | Ty::Scalar(Scalar::Float(_)) 555 | TyKind::Scalar(Scalar::Float(_))
533 | Ty::InferenceVar(_, TyVariableKind::Integer) 556 | TyKind::InferenceVar(_, TyVariableKind::Integer)
534 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, 557 | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty,
535 // Otherwise we resolve via the std::ops::Neg trait 558 // Otherwise we resolve via the std::ops::Neg trait
536 _ => self 559 _ => self
537 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 560 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
538 } 561 }
539 } 562 }
540 UnaryOp::Not => { 563 UnaryOp::Not => {
541 match &inner_ty { 564 match inner_ty.interned(&Interner) {
542 // Fast path for builtins 565 // Fast path for builtins
543 Ty::Scalar(Scalar::Bool) 566 TyKind::Scalar(Scalar::Bool)
544 | Ty::Scalar(Scalar::Int(_)) 567 | TyKind::Scalar(Scalar::Int(_))
545 | Ty::Scalar(Scalar::Uint(_)) 568 | TyKind::Scalar(Scalar::Uint(_))
546 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, 569 | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
547 // Otherwise we resolve via the std::ops::Not trait 570 // Otherwise we resolve via the std::ops::Not trait
548 _ => self 571 _ => self
549 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 572 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -554,7 +577,9 @@ impl<'a> InferenceContext<'a> {
554 Expr::BinaryOp { lhs, rhs, op } => match op { 577 Expr::BinaryOp { lhs, rhs, op } => match op {
555 Some(op) => { 578 Some(op) => {
556 let lhs_expectation = match op { 579 let lhs_expectation = match op {
557 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), 580 BinaryOp::LogicOp(..) => {
581 Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner))
582 }
558 _ => Expectation::none(), 583 _ => Expectation::none(),
559 }; 584 };
560 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 585 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -563,7 +588,7 @@ impl<'a> InferenceContext<'a> {
563 588
564 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); 589 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone());
565 590
566 if ret == Ty::Unknown { 591 if ret.is_unknown() {
567 cov_mark::hit!(infer_expr_inner_binary_operator_overload); 592 cov_mark::hit!(infer_expr_inner_binary_operator_overload);
568 593
569 self.resolve_associated_type_with_params( 594 self.resolve_associated_type_with_params(
@@ -575,7 +600,7 @@ impl<'a> InferenceContext<'a> {
575 ret 600 ret
576 } 601 }
577 } 602 }
578 _ => Ty::Unknown, 603 _ => self.err_ty(),
579 }, 604 },
580 Expr::Range { lhs, rhs, range_type } => { 605 Expr::Range { lhs, rhs, range_type } => {
581 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); 606 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none()));
@@ -586,33 +611,33 @@ impl<'a> InferenceContext<'a> {
586 match (range_type, lhs_ty, rhs_ty) { 611 match (range_type, lhs_ty, rhs_ty) {
587 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 612 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
588 Some(adt) => Ty::adt_ty(adt, Substs::empty()), 613 Some(adt) => Ty::adt_ty(adt, Substs::empty()),
589 None => Ty::Unknown, 614 None => self.err_ty(),
590 }, 615 },
591 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 616 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
592 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 617 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
593 None => Ty::Unknown, 618 None => self.err_ty(),
594 }, 619 },
595 (RangeOp::Inclusive, None, Some(ty)) => { 620 (RangeOp::Inclusive, None, Some(ty)) => {
596 match self.resolve_range_to_inclusive() { 621 match self.resolve_range_to_inclusive() {
597 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 622 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
598 None => Ty::Unknown, 623 None => self.err_ty(),
599 } 624 }
600 } 625 }
601 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 626 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
602 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 627 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
603 None => Ty::Unknown, 628 None => self.err_ty(),
604 }, 629 },
605 (RangeOp::Inclusive, Some(_), Some(ty)) => { 630 (RangeOp::Inclusive, Some(_), Some(ty)) => {
606 match self.resolve_range_inclusive() { 631 match self.resolve_range_inclusive() {
607 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 632 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
608 None => Ty::Unknown, 633 None => self.err_ty(),
609 } 634 }
610 } 635 }
611 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 636 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
612 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 637 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
613 None => Ty::Unknown, 638 None => self.err_ty(),
614 }, 639 },
615 (RangeOp::Inclusive, _, None) => Ty::Unknown, 640 (RangeOp::Inclusive, _, None) => self.err_ty(),
616 } 641 }
617 } 642 }
618 Expr::Index { base, index } => { 643 Expr::Index { base, index } => {
@@ -631,19 +656,19 @@ impl<'a> InferenceContext<'a> {
631 index_trait, 656 index_trait,
632 ); 657 );
633 let self_ty = 658 let self_ty =
634 self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); 659 self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value));
635 self.resolve_associated_type_with_params( 660 self.resolve_associated_type_with_params(
636 self_ty, 661 self_ty,
637 self.resolve_ops_index_output(), 662 self.resolve_ops_index_output(),
638 &[index_ty], 663 &[index_ty],
639 ) 664 )
640 } else { 665 } else {
641 Ty::Unknown 666 self.err_ty()
642 } 667 }
643 } 668 }
644 Expr::Tuple { exprs } => { 669 Expr::Tuple { exprs } => {
645 let mut tys = match &expected.ty { 670 let mut tys = match expected.ty.interned(&Interner) {
646 Ty::Tuple(_, substs) => substs 671 TyKind::Tuple(_, substs) => substs
647 .iter() 672 .iter()
648 .cloned() 673 .cloned()
649 .chain(repeat_with(|| self.table.new_type_var())) 674 .chain(repeat_with(|| self.table.new_type_var()))
@@ -656,11 +681,11 @@ impl<'a> InferenceContext<'a> {
656 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 681 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
657 } 682 }
658 683
659 Ty::Tuple(tys.len(), Substs(tys.into())) 684 TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner)
660 } 685 }
661 Expr::Array(array) => { 686 Expr::Array(array) => {
662 let elem_ty = match &expected.ty { 687 let elem_ty = match expected.ty.interned(&Interner) {
663 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), 688 TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
664 _ => self.table.new_type_var(), 689 _ => self.table.new_type_var(),
665 }; 690 };
666 691
@@ -677,43 +702,50 @@ impl<'a> InferenceContext<'a> {
677 ); 702 );
678 self.infer_expr( 703 self.infer_expr(
679 *repeat, 704 *repeat,
680 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), 705 &Expectation::has_type(
706 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
707 ),
681 ); 708 );
682 } 709 }
683 } 710 }
684 711
685 Ty::Array(Substs::single(elem_ty)) 712 TyKind::Array(elem_ty).intern(&Interner)
686 } 713 }
687 Expr::Literal(lit) => match lit { 714 Expr::Literal(lit) => match lit {
688 Literal::Bool(..) => Ty::Scalar(Scalar::Bool), 715 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
689 Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), 716 Literal::String(..) => {
717 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner)
718 }
690 Literal::ByteString(..) => { 719 Literal::ByteString(..) => {
691 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); 720 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
692 let array_type = Ty::Array(Substs::single(byte_type)); 721 let array_type = TyKind::Array(byte_type).intern(&Interner);
693 Ty::Ref(Mutability::Not, Substs::single(array_type)) 722 TyKind::Ref(Mutability::Not, array_type).intern(&Interner)
694 } 723 }
695 Literal::Char(..) => Ty::Scalar(Scalar::Char), 724 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
696 Literal::Int(_v, ty) => match ty { 725 Literal::Int(_v, ty) => match ty {
697 Some(int_ty) => { 726 Some(int_ty) => {
698 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) 727 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
728 .intern(&Interner)
699 } 729 }
700 None => self.table.new_integer_var(), 730 None => self.table.new_integer_var(),
701 }, 731 },
702 Literal::Uint(_v, ty) => match ty { 732 Literal::Uint(_v, ty) => match ty {
703 Some(int_ty) => { 733 Some(int_ty) => {
704 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) 734 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
735 .intern(&Interner)
705 } 736 }
706 None => self.table.new_integer_var(), 737 None => self.table.new_integer_var(),
707 }, 738 },
708 Literal::Float(_v, ty) => match ty { 739 Literal::Float(_v, ty) => match ty {
709 Some(float_ty) => { 740 Some(float_ty) => {
710 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) 741 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
742 .intern(&Interner)
711 } 743 }
712 None => self.table.new_float_var(), 744 None => self.table.new_float_var(),
713 }, 745 },
714 }, 746 },
715 }; 747 };
716 // use a new type variable if we got Ty::Unknown here 748 // use a new type variable if we got unknown here
717 let ty = self.insert_type_vars_shallow(ty); 749 let ty = self.insert_type_vars_shallow(ty);
718 let ty = self.resolve_ty_as_possible(ty); 750 let ty = self.resolve_ty_as_possible(ty);
719 self.write_expr_ty(tgt_expr, ty.clone()); 751 self.write_expr_ty(tgt_expr, ty.clone());
@@ -730,7 +762,7 @@ impl<'a> InferenceContext<'a> {
730 match stmt { 762 match stmt {
731 Statement::Let { pat, type_ref, initializer } => { 763 Statement::Let { pat, type_ref, initializer } => {
732 let decl_ty = 764 let decl_ty =
733 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); 765 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty());
734 766
735 // Always use the declared type when specified 767 // Always use the declared type when specified
736 let mut ty = decl_ty.clone(); 768 let mut ty = decl_ty.clone();
@@ -738,7 +770,7 @@ impl<'a> InferenceContext<'a> {
738 if let Some(expr) = initializer { 770 if let Some(expr) = initializer {
739 let actual_ty = 771 let actual_ty =
740 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); 772 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone()));
741 if decl_ty == Ty::Unknown { 773 if decl_ty.is_unknown() {
742 ty = actual_ty; 774 ty = actual_ty;
743 } 775 }
744 } 776 }
@@ -766,7 +798,7 @@ impl<'a> InferenceContext<'a> {
766 // we don't even make an attempt at coercion 798 // we don't even make an attempt at coercion
767 self.table.new_maybe_never_var() 799 self.table.new_maybe_never_var()
768 } else { 800 } else {
769 self.coerce(&Ty::unit(), expected.coercion_target()); 801 self.coerce(&Ty::unit(), &expected.coercion_target());
770 Ty::unit() 802 Ty::unit()
771 } 803 }
772 }; 804 };
@@ -802,7 +834,7 @@ impl<'a> InferenceContext<'a> {
802 self.write_method_resolution(tgt_expr, func); 834 self.write_method_resolution(tgt_expr, func);
803 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 835 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
804 } 836 }
805 None => (receiver_ty, Binders::new(0, Ty::Unknown), None), 837 None => (receiver_ty, Binders::new(0, self.err_ty()), None),
806 }; 838 };
807 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 839 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
808 let method_ty = method_ty.subst(&substs); 840 let method_ty = method_ty.subst(&substs);
@@ -813,15 +845,15 @@ impl<'a> InferenceContext<'a> {
813 if !sig.params().is_empty() { 845 if !sig.params().is_empty() {
814 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) 846 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone())
815 } else { 847 } else {
816 (Ty::Unknown, Vec::new(), sig.ret().clone()) 848 (self.err_ty(), Vec::new(), sig.ret().clone())
817 } 849 }
818 } 850 }
819 None => (Ty::Unknown, Vec::new(), Ty::Unknown), 851 None => (self.err_ty(), Vec::new(), self.err_ty()),
820 }; 852 };
821 // Apply autoref so the below unification works correctly 853 // Apply autoref so the below unification works correctly
822 // FIXME: return correct autorefs from lookup_method 854 // FIXME: return correct autorefs from lookup_method
823 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 855 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
824 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), 856 Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner),
825 _ => derefed_receiver_ty, 857 _ => derefed_receiver_ty,
826 }; 858 };
827 self.unify(&expected_receiver_ty, &actual_receiver_ty); 859 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -837,7 +869,7 @@ impl<'a> InferenceContext<'a> {
837 // that we have more information about the types of arguments when we 869 // that we have more information about the types of arguments when we
838 // type-check the functions. This isn't really the right way to do this. 870 // type-check the functions. This isn't really the right way to do this.
839 for &check_closures in &[false, true] { 871 for &check_closures in &[false, true] {
840 let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); 872 let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty()));
841 for (&arg, param_ty) in args.iter().zip(param_iter) { 873 for (&arg, param_ty) in args.iter().zip(param_iter) {
842 let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); 874 let is_closure = matches!(&self.body[arg], Expr::Lambda { .. });
843 if is_closure != check_closures { 875 if is_closure != check_closures {
@@ -867,7 +899,7 @@ impl<'a> InferenceContext<'a> {
867 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { 899 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
868 substs.push(receiver_ty.clone()); 900 substs.push(receiver_ty.clone());
869 } else { 901 } else {
870 substs.push(Ty::Unknown); 902 substs.push(self.err_ty());
871 } 903 }
872 } 904 }
873 } 905 }
@@ -891,14 +923,15 @@ impl<'a> InferenceContext<'a> {
891 }; 923 };
892 let supplied_params = substs.len();