WIP use params for APIT
This commit is contained in:
parent
33aa2f8e4f
commit
f8b7b64bce
@ -480,7 +480,7 @@ fn collect_const(&mut self, data: &ConstData) {
|
||||
fn collect_fn(&mut self, data: &FunctionData) {
|
||||
let body = Arc::clone(&self.body); // avoid borrow checker problem
|
||||
for (type_ref, pat) in data.params.iter().zip(body.params.iter()) {
|
||||
let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Opaque);
|
||||
let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Param);
|
||||
|
||||
self.infer_pat(*pat, &ty, BindingMode::default());
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs,
|
||||
TraitEnvironment, TraitRef, Ty, TypeCtor,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TyLoweringContext<'a, DB: HirDatabase> {
|
||||
@ -69,6 +70,10 @@ pub enum ImplTraitLoweringMode {
|
||||
/// 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 type variable. Used for argument
|
||||
/// position impl Trait currently, since it allows us to support that
|
||||
/// without Chalk.
|
||||
Param,
|
||||
/// `impl Trait` gets lowered into a variable 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
|
||||
@ -137,6 +142,11 @@ pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRe
|
||||
.collect();
|
||||
Ty::Opaque(predicates)
|
||||
}
|
||||
ImplTraitLoweringMode::Param => {
|
||||
let idx = ctx.impl_trait_counter.get();
|
||||
ctx.impl_trait_counter.set(idx + 1);
|
||||
Ty::Param { idx: idx as u32, name: Name::missing() }
|
||||
}
|
||||
ImplTraitLoweringMode::Variable => {
|
||||
let idx = ctx.impl_trait_counter.get();
|
||||
ctx.impl_trait_counter.set(idx + 1);
|
||||
|
@ -849,6 +849,59 @@ fn test<T: ApplyL>(t: T) {
|
||||
assert_eq!(t, "{unknown}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn argument_impl_trait() {
|
||||
assert_snapshot!(
|
||||
infer_with_mismatches(r#"
|
||||
trait Trait<T> {
|
||||
fn foo(&self) -> T;
|
||||
fn foo2(&self) -> i64;
|
||||
}
|
||||
fn bar(impl Trait<u64>) {}
|
||||
struct S<T>(T);
|
||||
impl<T> Trait<T> for S<T> {}
|
||||
|
||||
fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
|
||||
x;
|
||||
y;
|
||||
let z = S(1);
|
||||
bar(z);
|
||||
x.foo();
|
||||
y.foo();
|
||||
z.foo();
|
||||
x.foo2();
|
||||
y.foo2();
|
||||
z.foo2();
|
||||
}
|
||||
"#, true),
|
||||
@r###"
|
||||
[30; 34) 'self': &Self
|
||||
[55; 59) 'self': &Self
|
||||
[99; 101) '{}': ()
|
||||
[111; 112) 'x': impl Trait<u64>
|
||||
[131; 132) 'y': &impl Trait<u64>
|
||||
[152; 269) '{ ...2(); }': ()
|
||||
[158; 159) 'x': impl Trait<u64>
|
||||
[165; 166) 'y': &impl Trait<u64>
|
||||
[176; 177) 'z': impl Trait<u64>
|
||||
[180; 183) 'bar': fn bar() -> impl Trait<u64>
|
||||
[180; 185) 'bar()': impl Trait<u64>
|
||||
[191; 192) 'x': impl Trait<u64>
|
||||
[191; 198) 'x.foo()': u64
|
||||
[204; 205) 'y': &impl Trait<u64>
|
||||
[204; 211) 'y.foo()': u64
|
||||
[217; 218) 'z': impl Trait<u64>
|
||||
[217; 224) 'z.foo()': u64
|
||||
[230; 231) 'x': impl Trait<u64>
|
||||
[230; 238) 'x.foo2()': i64
|
||||
[244; 245) 'y': &impl Trait<u64>
|
||||
[244; 252) 'y.foo2()': i64
|
||||
[258; 259) 'z': impl Trait<u64>
|
||||
[258; 266) 'z.foo2()': i64
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn impl_trait() {
|
||||
|
Loading…
Reference in New Issue
Block a user