Skip to content

Extend mir fn bodies #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 42 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
656e316
Make it build successfully
tiif Jul 2, 2025
829d15b
Add some comments
tiif Jul 2, 2025
8f6e5f5
Check if the place expression is well-formed
tiif Jul 2, 2025
93b4a79
Check if the value expression is well-formed
tiif Jul 2, 2025
e187afb
Check if the value type is the subtype of place type
tiif Jul 2, 2025
f6e80ec
Pass down the function information in a crate (try to improve this la…
tiif Jul 3, 2025
b3e15aa
Check if the function called is in current crate
tiif Jul 3, 2025
4593f35
Check argument expression
tiif Jul 3, 2025
d1b9363
Add some comments
tiif Jul 3, 2025
0ae046d
Typeck for basic blocks
tiif Jul 4, 2025
44d64e0
Check if the return place has been initialised
tiif Jul 4, 2025
bfa12db
Complete typeck for function arguments
tiif Jul 4, 2025
b22ac93
Remove unused code
tiif Jul 4, 2025
4a52158
Clean up some code
tiif Jul 7, 2025
11c8962
fmt
tiif Jul 7, 2025
eb81732
Use FnId for calling function
tiif Jul 7, 2025
0d2fd54
Fix some rules
tiif Jul 7, 2025
45df6fb
Add some tests
tiif Jul 7, 2025
fa5fef1
Some hack in the grammar to make grammar works
tiif Jul 7, 2025
758e046
Apply more hacks to make the syntax works
tiif Jul 7, 2025
ff34038
Remove comment
tiif Jul 7, 2025
3ac1659
Change keyword to statements
tiif Jul 10, 2025
3582f16
Change some syntax to make it work correctly
tiif Jul 10, 2025
1cb5d76
Add reflexive rules for type
tiif Jul 10, 2025
65d5c8f
Fix some tests to make them pass
tiif Jul 10, 2025
ffadeb0
Skip the function arg number check for now, it's wrong
tiif Jul 10, 2025
7ec2414
Make place mention test pass
tiif Jul 10, 2025
e4b2eff
Make the place_mention test syntax better
tiif Jul 10, 2025
ddf51a4
WIP: add some fail tests
tiif Jul 10, 2025
7c1de68
Fix function argument type checking
tiif Jul 14, 2025
42c017c
Clean up the trace
tiif Jul 14, 2025
2cb9d5d
Remove spurious change
tiif Jul 14, 2025
f9cf307
fmt
tiif Jul 14, 2025
649e671
Update on the rule
tiif Jul 14, 2025
b5f1e03
Check the number of function arguments
tiif Jul 14, 2025
1ff76c8
Add more comments
tiif Jul 14, 2025
ada0952
fmt
tiif Jul 14, 2025
d0e3678
Improve some syntax after meeting
tiif Jul 15, 2025
3907b29
Add checks for undeclared local_id at function argument and return po…
tiif Jul 15, 2025
f2c43e8
Improve error messages for unknown local name
tiif Jul 15, 2025
b95e184
fmt
tiif Jul 15, 2025
3e3b065
Improve the check Terminator::Call's next block
tiif Jul 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions crates/formality-check/src/fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ use formality_rust::{
};
use formality_types::grammar::{Fallible, Wcs};

use crate::{mini_rust_check, Check};
use crate::Check;
use crate::CrateItem;

impl Check<'_> {
/// A "free function" is a free-standing function that is not part of an impl.
pub(crate) fn check_free_fn(&self, f: &Fn) -> Fallible<()> {
self.check_fn(&Env::default(), Wcs::t(), f)
pub(crate) fn check_free_fn(&self, f: &Fn, all_fn: &Vec<CrateItem>) -> Fallible<()> {
self.check_fn(&Env::default(), Wcs::t(), f, all_fn)
}

/// Invoked for both free functions and methods.
///
///
/// # Parameters
///
///
/// * `in_env` -- the environment from the enclosing impl (if any)
/// * `in_assumptions` -- where-clauses from the enclosing impl (if any)
/// * `f` -- the function definition
Expand All @@ -25,6 +26,7 @@ impl Check<'_> {
in_env: &Env,
in_assumptions: impl ToWcs,
f: &Fn,
all_fn: &Vec<CrateItem>,
) -> Fallible<()> {
let in_assumptions = in_assumptions.to_wcs();

Expand Down Expand Up @@ -59,7 +61,7 @@ impl Check<'_> {
for input_ty in &input_tys {
self.prove_goal(&env, &fn_assumptions, input_ty.well_formed())?;
}
self.prove_goal(&env, &fn_assumptions, output_ty.well_formed())?;
self.prove_goal(&env, &fn_assumptions, &output_ty.well_formed())?;

// Type-check the function body, if present.
match body {
Expand All @@ -71,9 +73,9 @@ impl Check<'_> {
// A trusted function body is assumed to be valid, all set.
}
formality_rust::grammar::FnBody::MiniRust(body) => {
mini_rust_check::check_body(&env, &fn_assumptions, body)?;
self.check_body(&env, &output_ty, &fn_assumptions, body, all_fn, input_tys)?;
}
}
},
}

Ok(())
Expand Down
15 changes: 11 additions & 4 deletions crates/formality-check/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::bail;

use crate::CrateItem;
use fn_error_context::context;
use formality_core::Downcasted;
use formality_prove::{Env, Safety};
Expand All @@ -18,7 +19,11 @@ use formality_types::{

impl super::Check<'_> {
#[context("check_trait_impl({trait_impl:?})")]
pub(super) fn check_trait_impl(&self, trait_impl: &TraitImpl) -> Fallible<()> {
pub(super) fn check_trait_impl(
&self,
trait_impl: &TraitImpl,
all_fn: &Vec<CrateItem>,
) -> Fallible<()> {
let TraitImpl { binder, safety: _ } = trait_impl;

let mut env = Env::default();
Expand Down Expand Up @@ -48,7 +53,7 @@ impl super::Check<'_> {
self.check_safety_matches(trait_decl, trait_impl)?;

for impl_item in &impl_items {
self.check_trait_impl_item(&env, &where_clauses, &trait_items, impl_item)?;
self.check_trait_impl_item(&env, &where_clauses, &trait_items, impl_item, all_fn)?;
}

Ok(())
Expand Down Expand Up @@ -101,14 +106,15 @@ impl super::Check<'_> {
assumptions: impl ToWcs,
trait_items: &[TraitItem],
impl_item: &ImplItem,
all_fn: &Vec<CrateItem>,
) -> Fallible<()> {
let assumptions: Wcs = assumptions.to_wcs();
assert!(
env.only_universal_variables() && env.encloses((&assumptions, trait_items, impl_item))
);

match impl_item {
ImplItem::Fn(v) => self.check_fn_in_impl(env, &assumptions, trait_items, v),
ImplItem::Fn(v) => self.check_fn_in_impl(env, &assumptions, trait_items, v, all_fn),
ImplItem::AssociatedTyValue(v) => {
self.check_associated_ty_value(env, assumptions, trait_items, v)
}
Expand All @@ -121,6 +127,7 @@ impl super::Check<'_> {
impl_assumptions: impl ToWcs,
trait_items: &[TraitItem],
ii_fn: &Fn,
all_fn: &Vec<CrateItem>,
) -> Fallible<()> {
let impl_assumptions: Wcs = impl_assumptions.to_wcs();
assert!(
Expand All @@ -139,7 +146,7 @@ impl super::Check<'_> {

tracing::debug!(?ti_fn);

self.check_fn(env, &impl_assumptions, ii_fn)?;
self.check_fn(env, &impl_assumptions, ii_fn, all_fn)?;

let mut env = env.clone();
let (
Expand Down
21 changes: 13 additions & 8 deletions crates/formality-check/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#![allow(dead_code)]

use formality_types::rust::FormalityLang;

use std::{collections::VecDeque, fmt::Debug};

use anyhow::bail;
Expand All @@ -13,7 +11,7 @@ use formality_rust::{
};
use formality_types::grammar::{Fallible, Wcs};

mod mini_rust_check;;
mod mini_rust_check;

/// Check all crates in the program. The crates must be in dependency order
/// such that any prefix of the crates is a complete program.
Expand Down Expand Up @@ -63,11 +61,18 @@ impl Check<'_> {

fn check_current_crate(&self, c: &Crate) -> Fallible<()> {
let Crate { id: _, items } = c;
// Collect all fn informatiion from current crate.
let all_fn: Vec<CrateItem> = c
.items
.clone()
.into_iter()
.filter(|item| matches!(item, CrateItem::Fn(_)))
.collect();

self.check_for_duplicate_items()?;

for item in items {
self.check_crate_item(item)?;
self.check_crate_item(item, &all_fn)?;
}

self.check_coherence(c)?;
Expand Down Expand Up @@ -111,13 +116,13 @@ impl Check<'_> {
Ok(())
}

fn check_crate_item(&self, c: &CrateItem) -> Fallible<()> {
fn check_crate_item(&self, c: &CrateItem, all_fn: &Vec<CrateItem>) -> Fallible<()> {
match c {
CrateItem::Trait(v) => self.check_trait(v),
CrateItem::TraitImpl(v) => self.check_trait_impl(v),
CrateItem::Trait(v) => self.check_trait(v, all_fn),
CrateItem::TraitImpl(v) => self.check_trait_impl(v, all_fn),
CrateItem::Struct(s) => self.check_adt(&s.to_adt()),
CrateItem::Enum(e) => self.check_adt(&e.to_adt()),
CrateItem::Fn(f) => self.check_free_fn(f),
CrateItem::Fn(f) => self.check_free_fn(f, all_fn),
CrateItem::NegTraitImpl(i) => self.check_neg_trait_impl(i),
CrateItem::Test(t) => self.check_test(t),
}
Expand Down
Loading
Loading