From f8b7b64bce772f21124b4790538ca97418cc23ca Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 16:05:58 +0100 Subject: WIP use params for APIT --- crates/ra_hir_ty/src/infer.rs | 2 +- crates/ra_hir_ty/src/lower.rs | 10 +++++++ crates/ra_hir_ty/src/tests/traits.rs | 53 ++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) 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> { fn collect_fn(&mut self, data: &FunctionData) { let body = Arc::clone(&self.body); // avoid borrow checker problem for (type_ref, pat) in data.params.iter().zip(body.params.iter()) { - let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Opaque); + let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Param); self.infer_pat(*pat, &ty, BindingMode::default()); } 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::{ Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, }; +use hir_expand::name::Name; #[derive(Debug)] pub struct TyLoweringContext<'a, DB: HirDatabase> { @@ -69,6 +70,10 @@ pub enum ImplTraitLoweringMode { /// i.e. for arguments of the function we're currently checking, and return /// types of functions we're calling. Opaque, + /// `impl Trait` gets lowered into a type variable. Used for argument + /// position impl Trait currently, since it allows us to support that + /// without Chalk. + Param, /// `impl Trait` gets lowered into a variable that can unify with some /// type. This is used in places where values flow 'in', i.e. for arguments /// of functions we're calling, and the return type of the function we're @@ -137,6 +142,11 @@ impl Ty { .collect(); Ty::Opaque(predicates) } + ImplTraitLoweringMode::Param => { + let idx = ctx.impl_trait_counter.get(); + ctx.impl_trait_counter.set(idx + 1); + Ty::Param { idx: idx as u32, name: Name::missing() } + } ImplTraitLoweringMode::Variable => { let idx = ctx.impl_trait_counter.get(); 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 @@ -849,6 +849,59 @@ fn test(t: T) { assert_eq!(t, "{unknown}"); } +#[test] +fn argument_impl_trait() { + assert_snapshot!( + infer_with_mismatches(r#" +trait Trait { + fn foo(&self) -> T; + fn foo2(&self) -> i64; +} +fn bar(impl Trait) {} +struct S(T); +impl Trait for S {} + +fn test(x: impl Trait, y: &impl Trait) { + x; + y; + let z = S(1); + bar(z); + x.foo(); + y.foo(); + z.foo(); + x.foo2(); + y.foo2(); + z.foo2(); +} +"#, true), + @r###" + [30; 34) 'self': &Self + [55; 59) 'self': &Self + [99; 101) '{}': () + [111; 112) 'x': impl Trait + [131; 132) 'y': &impl Trait + [152; 269) '{ ...2(); }': () + [158; 159) 'x': impl Trait + [165; 166) 'y': &impl Trait + [176; 177) 'z': impl Trait + [180; 183) 'bar': fn bar() -> impl Trait + [180; 185) 'bar()': impl Trait + [191; 192) 'x': impl Trait + [191; 198) 'x.foo()': u64 + [204; 205) 'y': &impl Trait + [204; 211) 'y.foo()': u64 + [217; 218) 'z': impl Trait + [217; 224) 'z.foo()': u64 + [230; 231) 'x': impl Trait + [230; 238) 'x.foo2()': i64 + [244; 245) 'y': &impl Trait + [244; 252) 'y.foo2()': i64 + [258; 259) 'z': impl Trait + [258; 266) 'z.foo2()': i64 + "### + ); +} + #[test] #[ignore] fn impl_trait() { -- cgit v1.2.3