Skip to content

Commit fc59d01

Browse files
committed
Add FnMut and Fn traits
1 parent 708288a commit fc59d01

File tree

8 files changed

+40
-5
lines changed

8 files changed

+40
-5
lines changed

chalk-integration/src/lowering.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,8 @@ impl LowerWellKnownTrait for WellKnownTrait {
18251825
Self::Clone => rust_ir::WellKnownTrait::Clone,
18261826
Self::Drop => rust_ir::WellKnownTrait::Drop,
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ pub enum WellKnownTrait {
6969
Clone,
7070
Drop,
7171
FnOnceTrait,
72+
FnMutTrait,
73+
FnTrait,
7274
}
7375

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

chalk-parse/src/parser.lalrpop

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ WellKnownTrait: WellKnownTrait = {
5252
"#" "[" "lang" "(" "clone" ")" "]" => WellKnownTrait::Clone,
5353
"#" "[" "lang" "(" "drop" ")" "]" => WellKnownTrait::Drop,
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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ pub fn add_builtin_program_clauses<I: Interner>(
3333
WellKnownTrait::Sized => sized::add_sized_program_clauses(db, builder, &trait_ref, ty),
3434
WellKnownTrait::Copy => copy::add_copy_program_clauses(db, builder, &trait_ref, ty),
3535
WellKnownTrait::Clone => clone::add_clone_program_clauses(db, builder, &trait_ref, ty),
36-
WellKnownTrait::FnOnceTrait => {
37-
fn_::add_fn_once_program_clauses(db, builder, &trait_ref, ty)
36+
WellKnownTrait::FnOnceTrait | WellKnownTrait::FnMutTrait | WellKnownTrait::FnTrait => {
37+
fn_::add_fn_trait_program_clauses(db, builder, &trait_ref, ty)
3838
}
3939
// Drop impls are provided explicitly
4040
WellKnownTrait::Drop => (),

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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,12 @@ impl WfWellKnownGoals {
471471
) -> Option<Goal<I>> {
472472
match db.trait_datum(trait_ref.trait_id).well_known? {
473473
WellKnownTrait::Copy => Self::copy_impl_constraint(db, trait_ref),
474-
WellKnownTrait::Drop | WellKnownTrait::Clone | WellKnownTrait::Sized | WellKnownTrait::FnOnceTrait => None,
474+
WellKnownTrait::Drop
475+
| WellKnownTrait::Clone
476+
| WellKnownTrait::Sized
477+
| WellKnownTrait::FnOnceTrait
478+
| WellKnownTrait::FnMutTrait
479+
| WellKnownTrait::FnTrait => None,
475480
}
476481
}
477482

@@ -486,7 +491,10 @@ impl WfWellKnownGoals {
486491

487492
match db.trait_datum(impl_datum.trait_id()).well_known? {
488493
// You can't add a manual implementation of Sized
489-
WellKnownTrait::Sized | WellKnownTrait::FnOnceTrait => Some(GoalData::CannotProve(()).intern(interner)),
494+
WellKnownTrait::Sized
495+
| WellKnownTrait::FnOnceTrait
496+
| WellKnownTrait::FnMutTrait
497+
| WellKnownTrait::FnTrait => Some(GoalData::CannotProve(()).intern(interner)),
490498
WellKnownTrait::Drop => Self::drop_impl_constraint(db, impl_datum),
491499
WellKnownTrait::Copy | WellKnownTrait::Clone => None,
492500
}

tests/test/functions.rs

Lines changed: 18 additions & 0 deletions
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)