aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs203
-rw-r--r--crates/hir_ty/src/infer/unify.rs2
-rw-r--r--crates/hir_ty/src/lib.rs27
-rw-r--r--crates/hir_ty/src/lower.rs9
-rw-r--r--crates/hir_ty/src/tests/macros.rs16
-rw-r--r--crates/hir_ty/src/tests/traits.rs216
-rw-r--r--crates/hir_ty/src/traits/chalk.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs7
10 files changed, 362 insertions, 128 deletions
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 3605ca581..982ad5b9e 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -91,7 +91,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
91 91
92 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
94 if data.is_extern { 94 if data.is_in_extern_block {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 96 return;
97 } 97 }
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 20bb64827..44a7e5506 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -32,7 +32,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
32 let def = self.owner.into(); 32 let def = self.owner.into();
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 34 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe,
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 37 };
38 if is_unsafe 38 if is_unsafe
@@ -86,7 +86,7 @@ fn walk_unsafe(
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def(db) { 88 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).is_unsafe { 89 if db.function_data(func).qualifier.is_unsafe {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
92 } 92 }
@@ -103,7 +103,7 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 103 Expr::MethodCall { .. } => {
104 if infer 104 if infer
105 .method_resolution(current) 105 .method_resolution(current)
106 .map(|func| db.function_data(func).is_unsafe) 106 .map(|func| db.function_data(func).qualifier.is_unsafe)
107 .unwrap_or(false) 107 .unwrap_or(false)
108 { 108 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index c1062387e..c572bb114 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -5,7 +5,13 @@ use std::{borrow::Cow, fmt};
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
7use hir_def::{ 7use hir_def::{
8 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, 8 db::DefDatabase,
9 find_path,
10 generics::TypeParamProvenance,
11 item_scope::ItemInNs,
12 path::{GenericArg, Path, PathKind},
13 type_ref::{TypeBound, TypeRef},
14 visibility::Visibility,
9 AssocContainerId, Lookup, ModuleId, TraitId, 15 AssocContainerId, Lookup, ModuleId, TraitId,
10}; 16};
11use hir_expand::name::Name; 17use hir_expand::name::Name;
@@ -232,7 +238,7 @@ where
232 238
233const TYPE_HINT_TRUNCATION: &str = "…"; 239const TYPE_HINT_TRUNCATION: &str = "…";
234 240
235impl HirDisplay for &Ty { 241impl<T: HirDisplay> HirDisplay for &'_ T {
236 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 242 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
237 HirDisplay::hir_fmt(*self, f) 243 HirDisplay::hir_fmt(*self, f)
238 } 244 }
@@ -761,12 +767,6 @@ impl HirDisplay for TraitRef {
761 } 767 }
762} 768}
763 769
764impl HirDisplay for &GenericPredicate {
765 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
766 HirDisplay::hir_fmt(*self, f)
767 }
768}
769
770impl HirDisplay for GenericPredicate { 770impl HirDisplay for GenericPredicate {
771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
772 if f.should_truncate() { 772 if f.should_truncate() {
@@ -825,3 +825,190 @@ impl HirDisplay for Obligation {
825 } 825 }
826 } 826 }
827} 827}
828
829pub fn write_visibility(
830 module_id: ModuleId,
831 vis: Visibility,
832 f: &mut HirFormatter,
833) -> Result<(), HirDisplayError> {
834 match vis {
835 Visibility::Public => write!(f, "pub "),
836 Visibility::Module(vis_id) => {
837 let def_map = module_id.def_map(f.db.upcast());
838 let root_module_id = def_map.module_id(def_map.root());
839 if vis_id == module_id {
840 // pub(self) or omitted
841 Ok(())
842 } else if root_module_id == vis_id {
843 write!(f, "pub(crate) ")
844 } else if module_id.containing_module(f.db.upcast()) == Some(vis_id) {
845 write!(f, "pub(super) ")
846 } else {
847 write!(f, "pub(in ...) ")
848 }
849 }
850 }
851}
852
853impl HirDisplay for TypeRef {
854 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
855 match self {
856 TypeRef::Never => write!(f, "!")?,
857 TypeRef::Placeholder => write!(f, "_")?,
858 TypeRef::Tuple(elems) => {
859 write!(f, "(")?;
860 f.write_joined(elems, ", ")?;
861 if elems.len() == 1 {
862 write!(f, ",")?;
863 }
864 write!(f, ")")?;
865 }
866 TypeRef::Path(path) => path.hir_fmt(f)?,
867 TypeRef::RawPtr(inner, mutability) => {
868 let mutability = match mutability {
869 hir_def::type_ref::Mutability::Shared => "*const ",
870 hir_def::type_ref::Mutability::Mut => "*mut ",
871 };
872 write!(f, "{}", mutability)?;
873 inner.hir_fmt(f)?;
874 }
875 TypeRef::Reference(inner, lifetime, mutability) => {
876 let mutability = match mutability {
877 hir_def::type_ref::Mutability::Shared => "",
878 hir_def::type_ref::Mutability::Mut => "mut ",
879 };
880 write!(f, "&")?;
881 if let Some(lifetime) = lifetime {
882 write!(f, "{} ", lifetime.name)?;
883 }
884 write!(f, "{}", mutability)?;
885 inner.hir_fmt(f)?;
886 }
887 TypeRef::Array(inner) => {
888 write!(f, "[")?;
889 inner.hir_fmt(f)?;
890 // FIXME: Array length?
891 write!(f, "; _]")?;
892 }
893 TypeRef::Slice(inner) => {
894 write!(f, "[")?;
895 inner.hir_fmt(f)?;
896 write!(f, "]")?;
897 }
898 TypeRef::Fn(tys, is_varargs) => {
899 // FIXME: Function pointer qualifiers.
900 write!(f, "fn(")?;
901 f.write_joined(&tys[..tys.len() - 1], ", ")?;
902 if *is_varargs {
903 write!(f, "{}...", if tys.len() == 1 { "" } else { ", " })?;
904 }
905 write!(f, ")")?;
906 let ret_ty = tys.last().unwrap();
907 match ret_ty {
908 TypeRef::Tuple(tup) if tup.is_empty() => {}
909 _ => {
910 write!(f, " -> ")?;
911 ret_ty.hir_fmt(f)?;
912 }
913 }
914 }
915 TypeRef::ImplTrait(bounds) => {
916 write!(f, "impl ")?;
917 f.write_joined(bounds, " + ")?;
918 }
919 TypeRef::DynTrait(bounds) => {
920 write!(f, "dyn ")?;
921 f.write_joined(bounds, " + ")?;
922 }
923 TypeRef::Error => write!(f, "{{error}}")?,
924 }
925 Ok(())
926 }
927}
928
929impl HirDisplay for TypeBound {
930 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
931 match self {
932 TypeBound::Path(path) => path.hir_fmt(f),
933 TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
934 TypeBound::Error => write!(f, "{{error}}"),
935 }
936 }
937}
938
939impl HirDisplay for Path {
940 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
941 match (self.type_anchor(), self.kind()) {
942 (Some(anchor), _) => {
943 write!(f, "<")?;
944 anchor.hir_fmt(f)?;
945 write!(f, ">")?;
946 }
947 (_, PathKind::Plain) => {}
948 (_, PathKind::Abs) => write!(f, "::")?,
949 (_, PathKind::Crate) => write!(f, "crate")?,
950 (_, PathKind::Super(0)) => write!(f, "self")?,
951 (_, PathKind::Super(n)) => {
952 write!(f, "super")?;
953 for _ in 0..*n {
954 write!(f, "::super")?;
955 }
956 }
957 (_, PathKind::DollarCrate(_)) => write!(f, "{{extern_crate}}")?,
958 }
959
960 for (seg_idx, segment) in self.segments().iter().enumerate() {
961 if seg_idx != 0 {
962 write!(f, "::")?;
963 }
964 write!(f, "{}", segment.name)?;
965 if let Some(generic_args) = segment.args_and_bindings {
966 // We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
967 // Do we actually format expressions?
968 write!(f, "<")?;
969 let mut first = true;
970 for arg in &generic_args.args {
971 if first {
972 first = false;
973 if generic_args.has_self_type {
974 // FIXME: Convert to `<Ty as Trait>` form.
975 write!(f, "Self = ")?;
976 }
977 } else {
978 write!(f, ", ")?;
979 }
980 arg.hir_fmt(f)?;
981 }
982 for binding in &generic_args.bindings {
983 if first {
984 first = false;
985 } else {
986 write!(f, ", ")?;
987 }
988 write!(f, "{}", binding.name)?;
989 match &binding.type_ref {
990 Some(ty) => {
991 write!(f, " = ")?;
992 ty.hir_fmt(f)?
993 }
994 None => {
995 write!(f, ": ")?;
996 f.write_joined(&binding.bounds, " + ")?;
997 }
998 }
999 }
1000 write!(f, ">")?;
1001 }
1002 }
1003 Ok(())
1004 }
1005}
1006
1007impl HirDisplay for GenericArg {
1008 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1009 match self {
1010 GenericArg::Type(ty) => ty.hir_fmt(f),
1011 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1012 }
1013 }
1014}
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 66f8fe8a3..7795f446f 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -300,7 +300,7 @@ impl InferenceTable {
300 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) 300 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
301 | (TyKind::Array(ty1), TyKind::Array(ty2)) 301 | (TyKind::Array(ty1), TyKind::Array(ty2))
302 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), 302 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
303 _ => false, 303 _ => true, /* we checked equals_ctor already */
304 } 304 }
305 } else { 305 } else {
306 self.unify_inner_trivial(&ty1, &ty2, depth) 306 self.unify_inner_trivial(&ty1, &ty2, depth)
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 503910dde..850385280 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -31,6 +31,7 @@ use hir_def::{
31 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 31 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
32}; 32};
33use itertools::Itertools; 33use itertools::Itertools;
34use smallvec::SmallVec;
34 35
35use crate::{ 36use crate::{
36 db::HirDatabase, 37 db::HirDatabase,
@@ -272,7 +273,7 @@ impl Ty {
272 273
273/// A list of substitutions for generic parameters. 274/// A list of substitutions for generic parameters.
274#[derive(Clone, PartialEq, Eq, Debug, Hash)] 275#[derive(Clone, PartialEq, Eq, Debug, Hash)]
275pub struct Substs(Arc<[Ty]>); 276pub struct Substs(SmallVec<[Ty; 2]>);
276 277
277impl TypeWalk for Substs { 278impl TypeWalk for Substs {
278 fn walk(&self, f: &mut impl FnMut(&Ty)) { 279 fn walk(&self, f: &mut impl FnMut(&Ty)) {
@@ -286,19 +287,27 @@ impl TypeWalk for Substs {
286 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 287 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
287 binders: DebruijnIndex, 288 binders: DebruijnIndex,
288 ) { 289 ) {
289 for t in make_mut_slice(&mut self.0) { 290 for t in &mut self.0 {
290 t.walk_mut_binders(f, binders); 291 t.walk_mut_binders(f, binders);
291 } 292 }
292 } 293 }
293} 294}
294 295
295impl Substs { 296impl Substs {
297 pub fn interned(&self, _: &Interner) -> &[Ty] {
298 &self.0
299 }
300
296 pub fn empty() -> Substs { 301 pub fn empty() -> Substs {
297 Substs(Arc::new([])) 302 Substs(SmallVec::new())
298 } 303 }
299 304
300 pub fn single(ty: Ty) -> Substs { 305 pub fn single(ty: Ty) -> Substs {
301 Substs(Arc::new([ty])) 306 Substs({
307 let mut v = SmallVec::new();
308 v.push(ty);
309 v
310 })
302 } 311 }
303 312
304 pub fn prefix(&self, n: usize) -> Substs { 313 pub fn prefix(&self, n: usize) -> Substs {
@@ -316,6 +325,10 @@ impl Substs {
316 &self.0[0] 325 &self.0[0]
317 } 326 }
318 327
328 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
329 Substs(elements.into_iter().collect())
330 }
331
319 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 332 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
320 pub(crate) fn type_params_for_generics( 333 pub(crate) fn type_params_for_generics(
321 db: &dyn HirDatabase, 334 db: &dyn HirDatabase,
@@ -600,13 +613,13 @@ impl CallableSig {
600 613
601 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { 614 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
602 CallableSig { 615 CallableSig {
603 params_and_return: Arc::clone(&fn_ptr.substs.0), 616 params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(),
604 is_varargs: fn_ptr.sig.variadic, 617 is_varargs: fn_ptr.sig.variadic,
605 } 618 }
606 } 619 }
607 620
608 pub fn from_substs(substs: &Substs) -> CallableSig { 621 pub fn from_substs(substs: &Substs) -> CallableSig {
609 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } 622 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false }
610 } 623 }
611 624
612 pub fn params(&self) -> &[Ty] { 625 pub fn params(&self) -> &[Ty] {
@@ -649,7 +662,7 @@ impl Ty {
649 TyKind::Function(FnPointer { 662 TyKind::Function(FnPointer {
650 num_args: sig.params().len(), 663 num_args: sig.params().len(),
651 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, 664 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
652 substs: Substs(sig.params_and_return), 665 substs: Substs::from_iter(&Interner, sig.params_and_return.iter().cloned()),
653 }) 666 })
654 .intern(&Interner) 667 .intern(&Interner)
655 } 668 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index b4c650fa1..6ab757bfc 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -31,7 +31,7 @@ use crate::{
31 traits::chalk::{Interner, ToChalk}, 31 traits::chalk::{Interner, ToChalk},
32 utils::{ 32 utils::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
34 make_mut_slice, variant_data, 34 variant_data,
35 }, 35 },
36 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, 36 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
@@ -150,8 +150,9 @@ impl<'a> TyLoweringContext<'a> {
150 let ty = match type_ref { 150 let ty = match type_ref {
151 TypeRef::Never => TyKind::Never.intern(&Interner), 151 TypeRef::Never => TyKind::Never.intern(&Interner),
152 TypeRef::Tuple(inner) => { 152 TypeRef::Tuple(inner) => {
153 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| self.lower_ty(tr)).collect(); 153 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
154 TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner) 154 TyKind::Tuple(inner_tys.len(), Substs::from_iter(&Interner, inner_tys))
155 .intern(&Interner)
155 } 156 }
156 TypeRef::Path(path) => { 157 TypeRef::Path(path) => {
157 let (ty, res_) = self.lower_path(path); 158 let (ty, res_) = self.lower_path(path);
@@ -638,7 +639,7 @@ impl<'a> TyLoweringContext<'a> {
638 ) -> TraitRef { 639 ) -> TraitRef {
639 let mut substs = self.trait_ref_substs_from_path(segment, resolved); 640 let mut substs = self.trait_ref_substs_from_path(segment, resolved);
640 if let Some(self_ty) = explicit_self_ty { 641 if let Some(self_ty) = explicit_self_ty {
641 make_mut_slice(&mut substs.0)[0] = self_ty; 642 substs.0[0] = self_ty;
642 } 643 }
643 TraitRef { trait_: resolved, substs } 644 TraitRef { trait_: resolved, substs }
644 } 645 }
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index fb3afaedc..af4f8bb11 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -216,6 +216,22 @@ fn expr_macro_expanded_in_various_places() {
216} 216}
217 217
218#[test] 218#[test]
219fn expr_macro_expanded_in_stmts() {
220 check_infer(
221 r#"
222 macro_rules! id { ($($es:tt)*) => { $($es)* } }
223 fn foo() {
224 id! { let a = (); }
225 }
226 "#,
227 expect![[r#"
228 !0..8 'leta=();': ()
229 57..84 '{ ...); } }': ()
230 "#]],
231 );
232}
233
234#[test]
219fn infer_type_value_macro_having_same_name() { 235fn infer_type_value_macro_having_same_name() {
220 check_infer( 236 check_infer(
221 r#" 237 r#"
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index e185b1c0a..93d3ad020 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1699,7 +1699,7 @@ fn super_trait_assoc_type_bounds() {
1699 1699
1700#[test] 1700#[test]
1701fn fn_trait() { 1701fn fn_trait() {
1702 check_infer( 1702 check_infer_with_mismatches(
1703 r#" 1703 r#"
1704 trait FnOnce<Args> { 1704 trait FnOnce<Args> {
1705 type Output; 1705 type Output;
@@ -1727,7 +1727,7 @@ fn fn_trait() {
1727 1727
1728#[test] 1728#[test]
1729fn fn_ptr_and_item() { 1729fn fn_ptr_and_item() {
1730 check_infer( 1730 check_infer_with_mismatches(
1731 r#" 1731 r#"
1732 #[lang="fn_once"] 1732 #[lang="fn_once"]
1733 trait FnOnce<Args> { 1733 trait FnOnce<Args> {
@@ -1743,12 +1743,12 @@ fn fn_ptr_and_item() {
1743 struct Bar<T>(T); 1743 struct Bar<T>(T);
1744 1744
1745 impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { 1745 impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
1746 fn foo(&self) -> (A1, R) {} 1746 fn foo(&self) -> (A1, R) { loop {} }
1747 } 1747 }
1748 1748
1749 enum Opt<T> { None, Some(T) } 1749 enum Opt<T> { None, Some(T) }
1750 impl<T> Opt<T> { 1750 impl<T> Opt<T> {
1751 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} 1751 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} }
1752 } 1752 }
1753 1753
1754 fn test() { 1754 fn test() {
@@ -1765,19 +1765,23 @@ fn fn_ptr_and_item() {
1765 80..84 'args': Args 1765 80..84 'args': Args
1766 139..143 'self': &Self 1766 139..143 'self': &Self
1767 243..247 'self': &Bar<F> 1767 243..247 'self': &Bar<F>
1768 260..262 '{}': () 1768 260..271 '{ loop {} }': (A1, R)
1769 346..350 'self': Opt<T> 1769 262..269 'loop {}': !
1770 352..353 'f': F 1770 267..269 '{}': ()
1771 368..370 '{}': () 1771 355..359 'self': Opt<T>
1772 384..500 '{ ...(f); }': () 1772 361..362 'f': F
1773 394..397 'bar': Bar<fn(u8) -> u32> 1773 377..388 '{ loop {} }': Opt<U>
1774 423..426 'bar': Bar<fn(u8) -> u32> 1774 379..386 'loop {}': !
1775 423..432 'bar.foo()': (u8, u32) 1775 384..386 '{}': ()
1776 443..446 'opt': Opt<u8> 1776 402..518 '{ ...(f); }': ()
1777 465..466 'f': fn(u8) -> u32 1777 412..415 'bar': Bar<fn(u8) -> u32>
1778 487..490 'opt': Opt<u8> 1778 441..444 'bar': Bar<fn(u8) -> u32>
1779 487..497 'opt.map(f)': Opt<u32> 1779 441..450 'bar.foo()': (u8, u32)
1780 495..496 'f': fn(u8) -> u32 1780 461..464 'opt': Opt<u8>
1781 483..484 'f': fn(u8) -> u32
1782 505..508 'opt': Opt<u8>
1783 505..515 'opt.map(f)': Opt<u32>
1784 513..514 'f': fn(u8) -> u32
1781 "#]], 1785 "#]],
1782 ); 1786 );
1783} 1787}
@@ -1859,7 +1863,7 @@ fn fn_trait_deref_with_ty_default() {
1859 1863
1860#[test] 1864#[test]
1861fn closure_1() { 1865fn closure_1() {
1862 check_infer( 1866 check_infer_with_mismatches(
1863 r#" 1867 r#"
1864 #[lang = "fn_once"] 1868 #[lang = "fn_once"]
1865 trait FnOnce<Args> { 1869 trait FnOnce<Args> {
@@ -1868,7 +1872,7 @@ fn closure_1() {
1868 1872
1869 enum Option<T> { Some(T), None } 1873 enum Option<T> { Some(T), None }
1870 impl<T> Option<T> { 1874 impl<T> Option<T> {
1871 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} 1875 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
1872 } 1876 }
1873 1877
1874 fn test() { 1878 fn test() {
@@ -1881,37 +1885,39 @@ fn closure_1() {
1881 expect![[r#" 1885 expect![[r#"
1882 147..151 'self': Option<T> 1886 147..151 'self': Option<T>
1883 153..154 'f': F 1887 153..154 'f': F
1884 172..174 '{}': () 1888 172..183 '{ loop {} }': Option<U>
1885 188..307 '{ ... 1); }': () 1889 174..181 'loop {}': !
1886 198..199 'x': Option<u32> 1890 179..181 '{}': ()
1887 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> 1891 197..316 '{ ... 1); }': ()
1888 202..220 'Option...(1u32)': Option<u32> 1892 207..208 'x': Option<u32>
1889 215..219 '1u32': u32 1893 211..223 'Option::Some': Some<u32>(u32) -> Option<u32>
1890 226..227 'x': Option<u32> 1894 211..229 'Option...(1u32)': Option<u32>
1891 226..242 'x.map(...v + 1)': Option<u32> 1895 224..228 '1u32': u32
1892 232..241 '|v| v + 1': |u32| -> u32 1896 235..236 'x': Option<u32>
1893 233..234 'v': u32 1897 235..251 'x.map(...v + 1)': Option<u32>
1894 236..237 'v': u32 1898 241..250 '|v| v + 1': |u32| -> u32
1895 236..241 'v + 1': u32 1899 242..243 'v': u32
1896 240..241 '1': u32 1900 245..246 'v': u32
1897 248..249 'x': Option<u32> 1901 245..250 'v + 1': u32
1898 248..264 'x.map(... 1u64)': Option<u64> 1902 249..250 '1': u32
1899 254..263 '|_v| 1u64': |u32| -> u64 1903 257..258 'x': Option<u32>
1900 255..257 '_v': u32 1904 257..273 'x.map(... 1u64)': Option<u64>
1901 259..263 '1u64': u64 1905 263..272 '|_v| 1u64': |u32| -> u64
1902 274..275 'y': Option<i64> 1906 264..266 '_v': u32
1903 291..292 'x': Option<u32> 1907 268..272 '1u64': u64
1904 291..304 'x.map(|_v| 1)': Option<i64> 1908 283..284 'y': Option<i64>
1905 297..303 '|_v| 1': |u32| -> i64 1909 300..301 'x': Option<u32>
1906 298..300 '_v': u32 1910 300..313 'x.map(|_v| 1)': Option<i64>
1907 302..303 '1': i64 1911 306..312 '|_v| 1': |u32| -> i64
1912 307..309 '_v': u32
1913 311..312 '1': i64
1908 "#]], 1914 "#]],
1909 ); 1915 );
1910} 1916}
1911 1917
1912#[test] 1918#[test]
1913fn closure_2() { 1919fn closure_2() {
1914 check_infer( 1920 check_infer_with_mismatches(
1915 r#" 1921 r#"
1916 trait FnOnce<Args> { 1922 trait FnOnce<Args> {
1917 type Output; 1923 type Output;
@@ -1951,22 +1957,22 @@ fn closure_2() {
1951 1957
1952#[test] 1958#[test]
1953fn closure_as_argument_inference_order() { 1959fn closure_as_argument_inference_order() {
1954 check_infer( 1960 check_infer_with_mismatches(
1955 r#" 1961 r#"
1956 #[lang = "fn_once"] 1962 #[lang = "fn_once"]
1957 trait FnOnce<Args> { 1963 trait FnOnce<Args> {
1958 type Output; 1964 type Output;
1959 } 1965 }
1960 1966
1961 fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} 1967 fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
1962 fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} 1968 fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
1963 1969
1964 struct S; 1970 struct S;
1965 impl S { 1971 impl S {
1966 fn method(self) -> u64; 1972 fn method(self) -> u64;
1967 1973
1968 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} 1974 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} }
1969 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} 1975 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} }
1970 } 1976 }
1971 1977
1972 fn test() { 1978 fn test() {
@@ -1979,52 +1985,60 @@ fn closure_as_argument_inference_order() {
1979 expect![[r#" 1985 expect![[r#"
1980 94..95 'x': T 1986 94..95 'x': T
1981 100..101 'f': F 1987 100..101 'f': F
1982 111..113 '{}': () 1988 111..122 '{ loop {} }': U
1983 147..148 'f': F 1989 113..120 'loop {}': !
1984 153..154 'x': T 1990 118..120 '{}': ()
1985 164..166 '{}': () 1991 156..157 'f': F
1986 201..205 'self': S 1992 162..163 'x': T
1987 253..257 'self': S 1993 173..184 '{ loop {} }': U
1988 259..260 'x': T 1994 175..182 'loop {}': !
1989 265..266 'f': F 1995 180..182 '{}': ()
1990 276..278 '{}': () 1996 219..223 'self': S
1991 316..320 'self': S 1997 271..275 'self': S
1992 322..323 'f': F 1998 277..278 'x': T
1993 328..329 'x': T 1999 283..284 'f': F
1994 339..341 '{}': () 2000 294..305 '{ loop {} }': U
1995 355..514 '{ ... S); }': () 2001 296..303 'loop {}': !
1996 365..367 'x1': u64 2002 301..303 '{}': ()
1997 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 2003 343..347 'self': S
1998 370..393 'foo1(S...hod())': u64 2004 349..350 'f': F
1999 375..376 'S': S 2005 355..356 'x': T
2000 378..392 '|s| s.method()': |S| -> u64 2006 366..377 '{ loop {} }': U
2001 379..380 's': S 2007 368..375 'loop {}': !
2002 382..383 's': S 2008 373..375 '{}': ()
2003 382..392 's.method()': u64 2009 391..550 '{ ... S); }': ()
2004 403..405 'x2': u64 2010 401..403 'x1': u64
2005 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 2011 406..410 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
2006 408..431 'foo2(|...(), S)': u64 2012 406..429 'foo1(S...hod())': u64
2007 413..427 '|s| s.method()': |S| -> u64 2013 411..412 'S': S
2008 414..415 's': S 2014 414..428 '|s| s.method()': |S| -> u64
2009 417..418 's': S 2015 415..416 's': S
2010 417..427 's.method()': u64 2016 418..419 's': S
2011 429..430 'S': S 2017 418..428 's.method()': u64
2012 441..443 'x3': u64 2018 439..441 'x2': u64
2013 446..447 'S': S 2019 444..448 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
2014 446..471 'S.foo1...hod())': u64 2020 444..467 'foo2(|...(), S)': u64
2015 453..454 'S': S 2021 449..463 '|s| s.method()': |S| -> u64
2016 456..470 '|s| s.method()': |S| -> u64 2022 450..451 's': S
2017 457..458 's': S 2023 453..454 's': S
2018 460..461 's': S 2024 453..463 's.method()': u64
2019 460..470 's.method()': u64 2025 465..466 'S': S
2020 481..483 'x4': u64 2026 477..479 'x3': u64
2021 486..487 'S': S 2027 482..483 'S': S
2022 486..511 'S.foo2...(), S)': u64 2028 482..507 'S.foo1...hod())': u64
2023 493..507 '|s| s.method()': |S| -> u64 2029 489..490 'S': S
2024 494..495 's': S 2030 492..506 '|s| s.method()': |S| -> u64
2025 497..498 's': S 2031 493..494 's': S
2026 497..507 's.method()': u64 2032 496..497 's': S
2027 509..510 'S': S 2033 496..506 's.method()': u64
2034 517..519 'x4': u64
2035 522..523 'S': S
2036 522..547 'S.foo2...(), S)': u64
2037 529..543 '|s| s.method()': |S| -> u64
2038 530..531 's': S
2039 533..534 's': S
2040 533..543 's.method()': u64
2041 545..546 'S': S
2028 "#]], 2042 "#]],
2029 ); 2043 );
2030} 2044}
@@ -2536,7 +2550,7 @@ fn test() {
2536 2550
2537#[test] 2551#[test]
2538fn iterator_chain() { 2552fn iterator_chain() {
2539 check_infer( 2553 check_infer_with_mismatches(
2540 r#" 2554 r#"
2541 //- /main.rs 2555 //- /main.rs
2542 #[lang = "fn_once"] 2556 #[lang = "fn_once"]
@@ -2939,7 +2953,7 @@ fn infer_closure_arg() {
2939 2953
2940#[test] 2954#[test]
2941fn infer_fn_trait_arg() { 2955fn infer_fn_trait_arg() {
2942 check_infer( 2956 check_infer_with_mismatches(
2943 r#" 2957 r#"
2944 //- /lib.rs deps:std 2958 //- /lib.rs deps:std
2945 2959
@@ -2986,7 +3000,8 @@ fn infer_fn_trait_arg() {
2986 3000
2987#[test] 3001#[test]
2988fn infer_box_fn_arg() { 3002fn infer_box_fn_arg() {
2989 check_infer( 3003 // The type mismatch is a bug
3004 check_infer_with_mismatches(
2990 r#" 3005 r#"
2991 //- /lib.rs deps:std 3006 //- /lib.rs deps:std
2992 3007
@@ -3025,7 +3040,7 @@ fn infer_box_fn_arg() {
3025 fn foo() { 3040 fn foo() {
3026 let s = Option::None; 3041 let s = Option::None;
3027 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); 3042 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3028 f(&s) 3043 f(&s);
3029 } 3044 }
3030 "#, 3045 "#,
3031 expect![[r#" 3046 expect![[r#"
@@ -3037,7 +3052,7 @@ fn infer_box_fn_arg() {
3037 406..417 '&self.inner': &*mut T 3052 406..417 '&self.inner': &*mut T
3038 407..411 'self': &Box<T> 3053 407..411 'self': &Box<T>
3039 407..417 'self.inner': *mut T 3054 407..417 'self.inner': *mut T
3040 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> 3055 478..576 '{ ...&s); }': ()
3041 488..489 's': Option<i32> 3056 488..489 's': Option<i32>
3042 492..504 'Option::None': Option<i32> 3057 492..504 'Option::None': Option<i32>
3043 514..515 'f': Box<dyn FnOnce(&Option<i32>)> 3058 514..515 'f': Box<dyn FnOnce(&Option<i32>)>
@@ -3049,6 +3064,7 @@ fn infer_box_fn_arg() {
3049 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> 3064 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
3050 570..572 '&s': &Option<i32> 3065 570..572 '&s': &Option<i32>
3051 571..572 's': Option<i32> 3066 571..572 's': Option<i32>
3067 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|_| -> ()>
3052 "#]], 3068 "#]],
3053 ); 3069 );
3054} 3070}
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 232cf9cd0..4bd8ba303 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -429,7 +429,7 @@ pub(crate) fn trait_datum_query(
429 let generic_params = generics(db.upcast(), trait_.into()); 429 let generic_params = generics(db.upcast(), trait_.into());
430 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 430 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
431 let flags = rust_ir::TraitFlags { 431 let flags = rust_ir::TraitFlags {
432 auto: trait_data.auto, 432 auto: trait_data.is_auto,
433 upstream: trait_.lookup(db.upcast()).container.krate() != krate, 433 upstream: trait_.lookup(db.upcast()).container.krate() != krate,
434 non_enumerable: true, 434 non_enumerable: true,
435 coinductive: false, // only relevant for Chalk testing 435 coinductive: false, // only relevant for Chalk testing
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index 1dc3f497d..94e94a26d 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -5,6 +5,7 @@ use super::tls;
5use base_db::salsa::InternId; 5use base_db::salsa::InternId;
6use chalk_ir::{GenericArg, Goal, GoalData}; 6use chalk_ir::{GenericArg, Goal, GoalData};
7use hir_def::TypeAliasId; 7use hir_def::TypeAliasId;
8use smallvec::SmallVec;
8use std::{fmt, sync::Arc}; 9use std::{fmt, sync::Arc};
9 10
10#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 11#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
@@ -33,7 +34,7 @@ impl chalk_ir::interner::Interner for Interner {
33 type InternedGenericArg = chalk_ir::GenericArgData<Self>; 34 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
34 type InternedGoal = Arc<GoalData<Self>>; 35 type InternedGoal = Arc<GoalData<Self>>;
35 type InternedGoals = Vec<Goal<Self>>; 36 type InternedGoals = Vec<Goal<Self>>;
36 type InternedSubstitution = Vec<GenericArg<Self>>; 37 type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>;
37 type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; 38 type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>;
38 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; 39 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 40 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
@@ -265,13 +266,13 @@ impl chalk_ir::interner::Interner for Interner {
265 fn intern_substitution<E>( 266 fn intern_substitution<E>(
266 &self, 267 &self,
267 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, 268 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
268 ) -> Result<Vec<GenericArg<Self>>, E> { 269 ) -> Result<Self::InternedSubstitution, E> {
269 data.into_iter().collect() 270 data.into_iter().collect()
270 } 271 }
271 272
272 fn substitution_data<'a>( 273 fn substitution_data<'a>(
273 &self, 274 &self,
274 substitution: &'a Vec<GenericArg<Self>>, 275 substitution: &'a Self::InternedSubstitution,
275 ) -> &'a [GenericArg<Self>] { 276 ) -> &'a [GenericArg<Self>] {
276 substitution 277 substitution
277 } 278 }