wip implement lowering mode

This commit is contained in:
Florian Diebold 2020-01-24 16:46:43 +01:00
parent 7ea4bce1b2
commit 9dec65d3b1
2 changed files with 34 additions and 26 deletions

View File

@ -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,
}

View File

@ -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) '{ }': ()
"###
);
}