Skip to content

Commit 194dd9e

Browse files
committed
Use Chalk's Ty::Function for function pointer types
Function pointers can be 'higher-ranked' over lifetimes, which is why they're not an application type in Chalk, but since we don't model lifetimes it doesn't matter for us yet.
1 parent bfbc210 commit 194dd9e

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

crates/ra_hir_ty/src/tests/traits.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,38 @@ fn test() {
26852685
);
26862686
}
26872687

2688+
#[test]
2689+
fn builtin_fn_ptr_copy() {
2690+
assert_snapshot!(
2691+
infer_with_mismatches(r#"
2692+
#[lang = "copy"]
2693+
trait Copy {}
2694+
2695+
trait Test { fn test(&self) -> bool; }
2696+
impl<T: Copy> Test for T {}
2697+
2698+
fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2699+
f1.test();
2700+
f2.test();
2701+
f3.test();
2702+
}
2703+
"#, true),
2704+
@r###"
2705+
55..59 'self': &Self
2706+
109..111 'f1': fn()
2707+
119..121 'f2': fn(usize) -> u8
2708+
140..142 'f3': fn(u8, u8) -> &u8
2709+
163..211 '{ ...t(); }': ()
2710+
169..171 'f1': fn()
2711+
169..178 'f1.test()': bool
2712+
184..186 'f2': fn(usize) -> u8
2713+
184..193 'f2.test()': bool
2714+
199..201 'f3': fn(u8, u8) -> &u8
2715+
199..208 'f3.test()': bool
2716+
"###
2717+
);
2718+
}
2719+
26882720
#[test]
26892721
fn builtin_sized() {
26902722
assert_snapshot!(

crates/ra_hir_ty/src/traits/chalk/mapping.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,19 @@ impl ToChalk for Ty {
2626
type Chalk = chalk_ir::Ty<Interner>;
2727
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
2828
match self {
29-
Ty::Apply(apply_ty) => {
30-
if let TypeCtor::Ref(m) = apply_ty.ctor {
31-
return ref_to_chalk(db, m, apply_ty.parameters);
29+
Ty::Apply(apply_ty) => match apply_ty.ctor {
30+
TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters),
31+
TypeCtor::FnPtr { num_args: _ } => {
32+
let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
33+
chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
34+
.intern(&Interner)
3235
}
33-
let name = apply_ty.ctor.to_chalk(db);
34-
let substitution = apply_ty.parameters.to_chalk(db);
35-
chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
36-
}
36+
_ => {
37+
let name = apply_ty.ctor.to_chalk(db);
38+
let substitution = apply_ty.parameters.to_chalk(db);
39+
chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
40+
}
41+
},
3742
Ty::Projection(proj_ty) => {
3843
let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
3944
let substitution = proj_ty.parameters.to_chalk(db);
@@ -93,7 +98,13 @@ impl ToChalk for Ty {
9398
Ty::Projection(ProjectionTy { associated_ty, parameters })
9499
}
95100
chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(),
96-
chalk_ir::TyData::Function(_) => unimplemented!(),
101+
chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => {
102+
let parameters: Substs = from_chalk(db, substitution);
103+
Ty::Apply(ApplicationTy {
104+
ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 },
105+
parameters,
106+
})
107+
}
97108
chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
98109
chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
99110
chalk_ir::TyData::Dyn(where_clauses) => {

0 commit comments

Comments
 (0)