From 9dec65d3b1aa703ceef993e46136f8949d7e0e48 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 24 Jan 2020 16:46:43 +0100 Subject: wip implement lowering mode --- crates/ra_hir_ty/src/lower.rs | 32 ++++++++++++++++++++++++++------ crates/ra_hir_ty/src/tests/traits.rs | 28 ++++++++-------------------- 2 files changed, 34 insertions(+), 26 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 3d2421223..39406d8ce 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -40,8 +40,17 @@ pub struct TyLoweringContext<'a, DB: HirDatabase> { #[derive(Clone, Debug)] pub enum ImplTraitLoweringMode { + /// `impl Trait` gets lowered into an opaque type that doesn't unify with + /// anything except itself. This is used in places where values flow 'out', + /// 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 placeholder 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 + /// currently checking. Placeholder, + /// `impl Trait` is disallowed and will be an error. Disallowed, } @@ -87,12 +96,23 @@ impl Ty { Ty::Dyn(predicates) } TypeRef::ImplTrait(bounds) => { - let self_ty = Ty::Bound(0); - let predicates = bounds - .iter() - .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) - .collect(); - Ty::Opaque(predicates) + match ctx.impl_trait_mode { + ImplTraitLoweringMode::Opaque => { + let self_ty = Ty::Bound(0); + let predicates = bounds + .iter() + .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) + .collect(); + Ty::Opaque(predicates) + }, + ImplTraitLoweringMode::Placeholder => { + todo!() + }, + ImplTraitLoweringMode::Disallowed => { + // FIXME: report error + Ty::Unknown + }, + } } TypeRef::Error => Ty::Unknown, } diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index a6ac18f86..764ab2800 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -994,29 +994,17 @@ fn weird_bounds() { assert_snapshot!( infer(r#" trait Trait {} -fn test() { - let a: impl Trait + 'lifetime = foo; - let b: impl 'lifetime = foo; - let b: impl (Trait) = foo; - let b: impl ('lifetime) = foo; - let d: impl ?Sized = foo; - let e: impl Trait + ?Sized = foo; +fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { } "#), @r###" - [26; 237) '{ ...foo; }': () - [36; 37) 'a': impl Trait + {error} - [64; 67) 'foo': impl Trait + {error} - [77; 78) 'b': impl {error} - [97; 100) 'foo': impl {error} - [110; 111) 'b': impl Trait - [128; 131) 'foo': impl Trait - [141; 142) 'b': impl {error} - [163; 166) 'foo': impl {error} - [176; 177) 'd': impl {error} - [193; 196) 'foo': impl {error} - [206; 207) 'e': impl Trait + {error} - [231; 234) 'foo': impl Trait + {error} + [24; 25) 'a': impl Trait + {error} + [51; 52) 'b': impl {error} + [70; 71) 'c': impl Trait + [87; 88) 'd': impl {error} + [108; 109) 'e': impl {error} + [124; 125) 'f': impl Trait + {error} + [148; 151) '{ }': () "### ); } -- cgit v1.2.3