aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_ty/src/lower.rs32
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs28
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)]
42pub enum ImplTraitLoweringMode { 42pub 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#"
996trait Trait {} 996trait Trait {}
997fn test() { 997fn 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}