diff options
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 32 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 28 |
2 files changed, 34 insertions, 26 deletions
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> { | |||
40 | 40 | ||
41 | #[derive(Clone, Debug)] | 41 | #[derive(Clone, Debug)] |
42 | pub enum ImplTraitLoweringMode { | 42 | pub enum ImplTraitLoweringMode { |
43 | /// `impl Trait` gets lowered into an opaque type that doesn't unify with | ||
44 | /// anything except itself. This is used in places where values flow 'out', | ||
45 | /// i.e. for arguments of the function we're currently checking, and return | ||
46 | /// types of functions we're calling. | ||
43 | Opaque, | 47 | Opaque, |
48 | /// `impl Trait` gets lowered into a placeholder that can unify with some | ||
49 | /// type. This is used in places where values flow 'in', i.e. for arguments | ||
50 | /// of functions we're calling, and the return type of the function we're | ||
51 | /// currently checking. | ||
44 | Placeholder, | 52 | Placeholder, |
53 | /// `impl Trait` is disallowed and will be an error. | ||
45 | Disallowed, | 54 | Disallowed, |
46 | } | 55 | } |
47 | 56 | ||
@@ -87,12 +96,23 @@ impl Ty { | |||
87 | Ty::Dyn(predicates) | 96 | Ty::Dyn(predicates) |
88 | } | 97 | } |
89 | TypeRef::ImplTrait(bounds) => { | 98 | TypeRef::ImplTrait(bounds) => { |
90 | let self_ty = Ty::Bound(0); | 99 | match ctx.impl_trait_mode { |
91 | let predicates = bounds | 100 | ImplTraitLoweringMode::Opaque => { |
92 | .iter() | 101 | let self_ty = Ty::Bound(0); |
93 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) | 102 | let predicates = bounds |
94 | .collect(); | 103 | .iter() |
95 | Ty::Opaque(predicates) | 104 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) |
105 | .collect(); | ||
106 | Ty::Opaque(predicates) | ||
107 | }, | ||
108 | ImplTraitLoweringMode::Placeholder => { | ||
109 | todo!() | ||
110 | }, | ||
111 | ImplTraitLoweringMode::Disallowed => { | ||
112 | // FIXME: report error | ||
113 | Ty::Unknown | ||
114 | }, | ||
115 | } | ||
96 | } | 116 | } |
97 | TypeRef::Error => Ty::Unknown, | 117 | TypeRef::Error => Ty::Unknown, |
98 | } | 118 | } |
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() { | |||
994 | assert_snapshot!( | 994 | assert_snapshot!( |
995 | infer(r#" | 995 | infer(r#" |
996 | trait Trait {} | 996 | trait Trait {} |
997 | fn test() { | 997 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { |
998 | let a: impl Trait + 'lifetime = foo; | ||
999 | let b: impl 'lifetime = foo; | ||
1000 | let b: impl (Trait) = foo; | ||
1001 | let b: impl ('lifetime) = foo; | ||
1002 | let d: impl ?Sized = foo; | ||
1003 | let e: impl Trait + ?Sized = foo; | ||
1004 | } | 998 | } |
1005 | "#), | 999 | "#), |
1006 | @r###" | 1000 | @r###" |
1007 | [26; 237) '{ ...foo; }': () | 1001 | [24; 25) 'a': impl Trait + {error} |
1008 | [36; 37) 'a': impl Trait + {error} | 1002 | [51; 52) 'b': impl {error} |
1009 | [64; 67) 'foo': impl Trait + {error} | 1003 | [70; 71) 'c': impl Trait |
1010 | [77; 78) 'b': impl {error} | 1004 | [87; 88) 'd': impl {error} |
1011 | [97; 100) 'foo': impl {error} | 1005 | [108; 109) 'e': impl {error} |
1012 | [110; 111) 'b': impl Trait | 1006 | [124; 125) 'f': impl Trait + {error} |
1013 | [128; 131) 'foo': impl Trait | 1007 | [148; 151) '{ }': () |
1014 | [141; 142) 'b': impl {error} | ||
1015 | [163; 166) 'foo': impl {error} | ||
1016 | [176; 177) 'd': impl {error} | ||
1017 | [193; 196) 'foo': impl {error} | ||
1018 | [206; 207) 'e': impl Trait + {error} | ||
1019 | [231; 234) 'foo': impl Trait + {error} | ||
1020 | "### | 1008 | "### |
1021 | ); | 1009 | ); |
1022 | } | 1010 | } |