mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +00:00
wip implement lowering mode
This commit is contained in:
parent
7ea4bce1b2
commit
9dec65d3b1
@ -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,
|
||||
}
|
||||
|
@ -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) '{ }': ()
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user