Skip to content

Commit fa10f9b

Browse files
committed
Add FnMut and Fn traits
1 parent 1b862b1 commit fa10f9b

File tree

8 files changed

+39
-7
lines changed

8 files changed

+39
-7
lines changed

chalk-integration/src/lowering.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,8 @@ impl LowerWellKnownTrait for WellKnownTrait {
18251825
Self::CloneTrait => rust_ir::WellKnownTrait::CloneTrait,
18261826
Self::DropTrait => rust_ir::WellKnownTrait::DropTrait,
18271827
Self::FnOnceTrait => rust_ir::WellKnownTrait::FnOnceTrait,
1828+
Self::FnMutTrait => rust_ir::WellKnownTrait::FnMutTrait,
1829+
Self::FnTrait => rust_ir::WellKnownTrait::FnTrait
18281830
}
18291831
}
18301832
}

chalk-parse/src/ast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ pub enum WellKnownTrait {
6969
CloneTrait,
7070
DropTrait,
7171
FnOnceTrait,
72+
FnMutTrait,
73+
FnTrait
7274
}
7375

7476
#[derive(Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ WellKnownTrait: WellKnownTrait = {
5252
"#" "[" "lang" "(" "clone" ")" "]" => WellKnownTrait::CloneTrait,
5353
"#" "[" "lang" "(" "drop" ")" "]" => WellKnownTrait::DropTrait,
5454
"#" "[" "lang" "(" "fn_once" ")" "]" => WellKnownTrait::FnOnceTrait,
55+
"#" "[" "lang" "(" "fn_mut" ")" "]" => WellKnownTrait::FnMutTrait,
56+
"#" "[" "lang" "(" "fn" ")" "]" => WellKnownTrait::FnTrait,
5557
};
5658

5759
StructDefn: StructDefn = {

chalk-solve/src/clauses/builtin_traits.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ pub fn add_builtin_program_clauses<I: Interner>(
3939
WellKnownTrait::CloneTrait => {
4040
clone::add_clone_program_clauses(db, builder, &trait_ref, ty)
4141
}
42-
WellKnownTrait::FnOnceTrait => {
43-
fn_::add_fn_once_program_clauses(db, builder, &trait_ref, ty)
42+
WellKnownTrait::FnOnceTrait | WellKnownTrait::FnMutTrait | WellKnownTrait::FnTrait => {
43+
fn_::add_fn_trait_program_clauses(db, builder, &trait_ref, ty)
4444
}
4545
// Drop impls are provided explicitly
4646
WellKnownTrait::DropTrait => (),

chalk-solve/src/clauses/builtin_traits/fn_.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use crate::infer::instantiate::IntoBindersAndValue;
33
use crate::{Interner, RustIrDatabase, TraitRef};
44
use chalk_ir::{ApplicationTy, Binders, Substitution, Ty, TyData, TypeName, VariableKinds};
55

6-
pub fn add_fn_once_program_clauses<I: Interner>(
6+
// Handles clauses for FnOnce/FnMut/Fn
7+
pub fn add_fn_trait_program_clauses<I: Interner>(
78
db: &dyn RustIrDatabase<I>,
89
builder: &mut ClauseBuilder<'_, I>,
910
trait_ref: &TraitRef<I>,

chalk-solve/src/rust_ir.rs

+2
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ pub enum WellKnownTrait {
220220
/// corresponding to the arguments of a function implementing this trait.
221221
/// E.g. `fn(u8, bool): FnOnce<(u8, bool)>`
222222
FnOnceTrait,
223+
FnMutTrait,
224+
FnTrait
223225
}
224226

225227
impl<I: Interner> TraitDatum<I> {

chalk-solve/src/wf.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,9 @@ impl WfWellKnownGoals {
474474
WellKnownTrait::DropTrait
475475
| WellKnownTrait::CloneTrait
476476
| WellKnownTrait::SizedTrait
477-
| WellKnownTrait::FnOnceTrait => None,
477+
| WellKnownTrait::FnOnceTrait
478+
| WellKnownTrait::FnMutTrait
479+
| WellKnownTrait::FnTrait => None,
478480
}
479481
}
480482

@@ -488,9 +490,12 @@ impl WfWellKnownGoals {
488490
let interner = db.interner();
489491

490492
match db.trait_datum(impl_datum.trait_id()).well_known? {
491-
// You can't add a manual implementation of Sized or FnOnce
492-
WellKnownTrait::SizedTrait | WellKnownTrait::FnOnceTrait => {
493-
Some(GoalData::CannotProve(()).intern(interner))
493+
// You can't add a manual implementation of Sized or FnOnce/FnMut/Fn
494+
WellKnownTrait::SizedTrait
495+
| WellKnownTrait::FnOnceTrait
496+
| WellKnownTrait::FnMutTrait
497+
| WellKnownTrait::FnTrait => {
498+
Some(GoalData::CannotProve(()).intern(interner))
494499
}
495500
WellKnownTrait::DropTrait => Self::drop_impl_constraint(db, impl_datum),
496501
WellKnownTrait::CopyTrait | WellKnownTrait::CloneTrait => None,

tests/test/functions.rs

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ fn function_implement_fn_once() {
66
program {
77
#[lang(fn_once)]
88
trait FnOnce<Args> { }
9+
10+
#[lang(fn_mut)]
11+
trait FnMut<Args> where Self: FnOnce<Args> { }
12+
13+
#[lang(fn)]
14+
trait Fn<Args> where Self: FnMut<Args> { }
915
}
1016

1117
goal {
@@ -14,6 +20,18 @@ fn function_implement_fn_once() {
1420
"Unique; substitution [], lifetime constraints []"
1521
}
1622

23+
goal {
24+
fn(u8): FnMut<(u8,)>
25+
} yields {
26+
"Unique; substitution [], lifetime constraints []"
27+
}
28+
29+
goal {
30+
fn(u8): Fn<(u8,)>
31+
} yields {
32+
"Unique; substitution [], lifetime constraints []"
33+
}
34+
1735
goal {
1836
fn(u8, u32): FnOnce<(u8,u32)>
1937
} yields {

0 commit comments

Comments
 (0)