Skip to content

Commit 5b64312

Browse files
authored
Merge pull request #130 from oli-obk/const_generics_without_inherent_types
Implement const generics take 2
2 parents 6297fdd + f869ed4 commit 5b64312

File tree

19 files changed

+497
-34
lines changed

19 files changed

+497
-34
lines changed

.github/workflows/ci.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ on:
99

1010
jobs:
1111
rust-test:
12-
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
os: [ubuntu-latest, macos-latest, windows-latest]
15+
runs-on: ${{ matrix.os }}
1316
steps:
1417
- uses: actions/checkout@v2
1518
- name: Run cargo test
1619
uses: actions-rs/cargo@v1
1720
with:
1821
command: test
19-
args: --all
22+
args: --all

crates/formality-check/src/lib.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(dead_code)]
22

3-
use std::collections::VecDeque;
3+
use std::{collections::VecDeque, fmt::Debug};
44

55
use anyhow::bail;
66
use formality_prove::{Decls, Env};
@@ -86,7 +86,12 @@ impl Check<'_> {
8686
}
8787
}
8888

89-
fn prove_goal(&self, env: &Env, assumptions: impl ToWcs, goal: impl ToWcs) -> Fallible<()> {
89+
fn prove_goal(
90+
&self,
91+
env: &Env,
92+
assumptions: impl ToWcs,
93+
goal: impl ToWcs + Debug,
94+
) -> Fallible<()> {
9095
let goal: Wcs = goal.to_wcs();
9196
let assumptions: Wcs = assumptions.to_wcs();
9297

@@ -101,7 +106,12 @@ impl Check<'_> {
101106
bail!("failed to prove {goal:?} given {assumptions:?}, got {cs:?}")
102107
}
103108

104-
fn prove_not_goal(&self, env: &Env, assumptions: impl ToWcs, goal: impl ToWcs) -> Fallible<()> {
109+
fn prove_not_goal(
110+
&self,
111+
env: &Env,
112+
assumptions: impl ToWcs,
113+
goal: impl ToWcs + Debug,
114+
) -> Fallible<()> {
105115
let goal: Wcs = goal.to_wcs();
106116
let assumptions: Wcs = assumptions.to_wcs();
107117

crates/formality-check/src/where_clauses.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
use fn_error_context::context;
12
use formality_prove::Env;
23
use formality_rust::{
34
grammar::{WhereClause, WhereClauseData},
45
prove::ToWcs,
56
};
67
use formality_types::{
78
cast::Upcast,
8-
grammar::{Fallible, Parameter, TraitRef},
9+
grammar::{ConstData, Fallible, Parameter, Relation, TraitRef},
910
};
1011

1112
impl super::Check<'_> {
@@ -21,6 +22,8 @@ impl super::Check<'_> {
2122
Ok(())
2223
}
2324

25+
#[context("prove_where_clause_well_formed({where_clause:?})")]
26+
// FIXME(oli-obk): figure out why is this a function and not a `judgment_fn`.
2427
fn prove_where_clause_well_formed(
2528
&self,
2629
in_env: &Env,
@@ -43,6 +46,17 @@ impl super::Check<'_> {
4346
let wc = e.instantiate_universally(binder);
4447
self.prove_where_clause_well_formed(&e, assumptions, &wc)
4548
}
49+
WhereClauseData::TypeOfConst(ct, ty) => {
50+
match ct.data() {
51+
ConstData::Value(_, t) => {
52+
self.prove_goal(in_env, &assumptions, Relation::eq(ty, t))?
53+
}
54+
ConstData::Variable(_) => {}
55+
}
56+
// FIXME(oli-obk): prove that there is no `TypeOfConst` bound for a different type.
57+
self.prove_parameter_well_formed(in_env, &assumptions, ct.clone())?;
58+
self.prove_parameter_well_formed(in_env, assumptions, ty.clone())
59+
}
4660
}
4761
}
4862

crates/formality-macros/src/test.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
use proc_macro::TokenStream;
2-
use quote::quote;
32

43
pub(crate) fn test(_args: TokenStream, mut item_fn: syn::ItemFn) -> syn::Result<syn::ItemFn> {
54
let original_fn_body = item_fn.block.clone();
6-
item_fn.block = syn::parse2(quote! {
7-
{
8-
formality_core::with_tracing_logs(move || {
9-
#original_fn_body
10-
})
11-
}
12-
})
13-
.unwrap();
5+
item_fn.block = syn::parse_quote!({
6+
formality_core::with_tracing_logs(move || {
7+
#original_fn_body
8+
})
9+
});
1410
Ok(item_fn)
1511
}

crates/formality-prove/src/prove/prove_wc.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,12 @@ judgment_fn! {
114114
----------------------------- ("trait ref is local")
115115
(prove_wc(decls, env, assumptions, Relation::WellFormed(p)) => c)
116116
)
117+
118+
(
119+
(if let Some((_, const_ty)) = ct.as_value())
120+
(prove(decls, env, assumptions, Wcs::all_eq(vec![const_ty], vec![ty])) => c)
121+
----------------------------- ("const has ty")
122+
(prove_wc(decls, env, assumptions, Predicate::ConstHasType(ct, ty)) => c)
123+
)
117124
}
118125
}

crates/formality-prove/src/prove/prove_wf.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use formality_types::{
2-
grammar::{Parameter, RigidName, RigidTy, UniversalVar, Wcs},
2+
grammar::{ConstData, Parameter, RigidName, RigidTy, UniversalVar, Wcs},
33
judgment_fn,
44
};
55

@@ -32,5 +32,17 @@ judgment_fn! {
3232
--- ("tuples")
3333
(prove_wf(decls, env, assumptions, RigidTy { name: RigidName::Tuple(_), parameters }) => c)
3434
)
35+
36+
(
37+
(for_all(&decls, &env, &assumptions, &parameters, &prove_wf) => c)
38+
--- ("integers and booleans")
39+
(prove_wf(decls, env, assumptions, RigidTy { name: RigidName::ScalarId(_), parameters }) => c)
40+
)
41+
42+
(
43+
(prove_wf(&decls, &env, &assumptions, ty) => c)
44+
--- ("rigid constants")
45+
(prove_wf(decls, env, assumptions, ConstData::Value(_, ty)) => c)
46+
)
3547
}
3648
}

crates/formality-rust/src/grammar.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use formality_macros::term;
44
use formality_types::{
55
cast::Upcast,
66
grammar::{
7-
AdtId, AssociatedItemId, Binder, CrateId, Fallible, FieldId, FnId, Lt, Parameter, TraitId,
8-
TraitRef, Ty, Wc,
7+
AdtId, AssociatedItemId, Binder, Const, CrateId, Fallible, FieldId, FnId, Lt, Parameter,
8+
TraitId, TraitRef, Ty, Wc,
99
},
1010
term::Term,
1111
};
@@ -331,6 +331,7 @@ impl WhereClause {
331331
let wc = where_clause.invert()?;
332332
Some(Wc::for_all(&vars, wc))
333333
}
334+
WhereClauseData::TypeOfConst(_, _) => None,
334335
}
335336
}
336337
}
@@ -345,6 +346,9 @@ pub enum WhereClauseData {
345346

346347
#[grammar(for $v0)]
347348
ForAll(Binder<WhereClause>),
349+
350+
#[grammar(type_of_const $v0 is $v1)]
351+
TypeOfConst(Const, Ty),
348352
}
349353

350354
#[term($data)]

crates/formality-rust/src/prove.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,9 @@ impl ToWcs for WhereClause {
386386
.map(|wc| Wc::for_all(&vars, wc))
387387
.collect()
388388
}
389+
WhereClauseData::TypeOfConst(ct, ty) => {
390+
Predicate::ConstHasType(ct.clone(), ty.clone()).upcast()
391+
}
389392
}
390393
}
391394
}

crates/formality-types/src/fold.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use crate::{
44
cast::Upcast,
55
collections::Set,
6-
grammar::{Lt, LtData, Parameter, Ty, TyData, Variable},
6+
grammar::{Const, ConstData, Lt, LtData, Parameter, Ty, TyData, ValTree, Variable},
77
visit::Visit,
88
};
99

@@ -73,6 +73,28 @@ impl Fold for Ty {
7373
}
7474
}
7575

76+
impl Fold for Const {
77+
fn substitute(&self, substitution_fn: SubstitutionFn<'_>) -> Self {
78+
match self.data() {
79+
ConstData::Value(v, ty) => Self::valtree(
80+
v.substitute(substitution_fn),
81+
ty.substitute(substitution_fn),
82+
),
83+
ConstData::Variable(v) => match substitution_fn(v.clone()) {
84+
None => self.clone(),
85+
Some(Parameter::Const(c)) => c,
86+
Some(param) => panic!("ill-kinded substitute: expected const, got {param:?}"),
87+
},
88+
}
89+
}
90+
}
91+
92+
impl Fold for ValTree {
93+
fn substitute(&self, _substitution_fn: SubstitutionFn<'_>) -> Self {
94+
self.clone()
95+
}
96+
}
97+
7698
impl Fold for Lt {
7799
fn substitute(&self, substitution_fn: SubstitutionFn<'_>) -> Self {
78100
match self.data() {

crates/formality-types/src/grammar.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
mod binder;
2+
mod consts;
23
mod formulas;
34
mod ids;
45
mod kinded;
56
mod ty;
67
mod wc;
78

89
pub use binder::*;
10+
pub use consts::*;
911
pub use formulas::*;
1012
pub use ids::*;
1113
pub use kinded::*;

0 commit comments

Comments
 (0)