aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_ty/src/infer.rs2
-rw-r--r--crates/ra_hir_ty/src/lower.rs10
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs53
3 files changed, 64 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index f7ef09f0e..0d65984ee 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -480,7 +480,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
480 fn collect_fn(&mut self, data: &FunctionData) { 480 fn collect_fn(&mut self, data: &FunctionData) {
481 let body = Arc::clone(&self.body); // avoid borrow checker problem 481 let body = Arc::clone(&self.body); // avoid borrow checker problem
482 for (type_ref, pat) in data.params.iter().zip(body.params.iter()) { 482 for (type_ref, pat) in data.params.iter().zip(body.params.iter()) {
483 let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Opaque); 483 let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Param);
484 484
485 self.infer_pat(*pat, &ty, BindingMode::default()); 485 self.infer_pat(*pat, &ty, BindingMode::default());
486 } 486 }
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 5138019c7..88d962b47 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -30,6 +30,7 @@ use crate::{
30 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, 30 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs,
31 TraitEnvironment, TraitRef, Ty, TypeCtor, 31 TraitEnvironment, TraitRef, Ty, TypeCtor,
32}; 32};
33use hir_expand::name::Name;
33 34
34#[derive(Debug)] 35#[derive(Debug)]
35pub struct TyLoweringContext<'a, DB: HirDatabase> { 36pub struct TyLoweringContext<'a, DB: HirDatabase> {
@@ -69,6 +70,10 @@ pub enum ImplTraitLoweringMode {
69 /// i.e. for arguments of the function we're currently checking, and return 70 /// i.e. for arguments of the function we're currently checking, and return
70 /// types of functions we're calling. 71 /// types of functions we're calling.
71 Opaque, 72 Opaque,
73 /// `impl Trait` gets lowered into a type variable. Used for argument
74 /// position impl Trait currently, since it allows us to support that
75 /// without Chalk.
76 Param,
72 /// `impl Trait` gets lowered into a variable that can unify with some 77 /// `impl Trait` gets lowered into a variable that can unify with some
73 /// type. This is used in places where values flow 'in', i.e. for arguments 78 /// type. This is used in places where values flow 'in', i.e. for arguments
74 /// of functions we're calling, and the return type of the function we're 79 /// of functions we're calling, and the return type of the function we're
@@ -137,6 +142,11 @@ impl Ty {
137 .collect(); 142 .collect();
138 Ty::Opaque(predicates) 143 Ty::Opaque(predicates)
139 } 144 }
145 ImplTraitLoweringMode::Param => {
146 let idx = ctx.impl_trait_counter.get();
147 ctx.impl_trait_counter.set(idx + 1);
148 Ty::Param { idx: idx as u32, name: Name::missing() }
149 }
140 ImplTraitLoweringMode::Variable => { 150 ImplTraitLoweringMode::Variable => {
141 let idx = ctx.impl_trait_counter.get(); 151 let idx = ctx.impl_trait_counter.get();
142 ctx.impl_trait_counter.set(idx + 1); 152 ctx.impl_trait_counter.set(idx + 1);
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index e2351ca98..dc78e83cd 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -850,6 +850,59 @@ fn test<T: ApplyL>(t: T) {
850} 850}
851 851
852#[test] 852#[test]
853fn argument_impl_trait() {
854 assert_snapshot!(
855 infer_with_mismatches(r#"
856trait Trait<T> {
857 fn foo(&self) -> T;
858 fn foo2(&self) -> i64;
859}
860fn bar(impl Trait<u64>) {}
861struct S<T>(T);
862impl<T> Trait<T> for S<T> {}
863
864fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
865 x;
866 y;
867 let z = S(1);
868 bar(z);
869 x.foo();
870 y.foo();
871 z.foo();
872 x.foo2();
873 y.foo2();
874 z.foo2();
875}
876"#, true),
877 @r###"
878 [30; 34) 'self': &Self
879 [55; 59) 'self': &Self
880 [99; 101) '{}': ()
881 [111; 112) 'x': impl Trait<u64>
882 [131; 132) 'y': &impl Trait<u64>
883 [152; 269) '{ ...2(); }': ()
884 [158; 159) 'x': impl Trait<u64>
885 [165; 166) 'y': &impl Trait<u64>
886 [176; 177) 'z': impl Trait<u64>
887 [180; 183) 'bar': fn bar() -> impl Trait<u64>
888 [180; 185) 'bar()': impl Trait<u64>
889 [191; 192) 'x': impl Trait<u64>
890 [191; 198) 'x.foo()': u64
891 [204; 205) 'y': &impl Trait<u64>
892 [204; 211) 'y.foo()': u64
893 [217; 218) 'z': impl Trait<u64>
894 [217; 224) 'z.foo()': u64
895 [230; 231) 'x': impl Trait<u64>
896 [230; 238) 'x.foo2()': i64
897 [244; 245) 'y': &impl Trait<u64>
898 [244; 252) 'y.foo2()': i64
899 [258; 259) 'z': impl Trait<u64>
900 [258; 266) 'z.foo2()': i64
901 "###
902 );
903}
904
905#[test]
853#[ignore] 906#[ignore]
854fn impl_trait() { 907fn impl_trait() {
855 assert_snapshot!( 908 assert_snapshot!(