Skip to content

Commit

Permalink
Clean up propagate error handling
Browse files Browse the repository at this point in the history
This commit also fixes a logic bug, where we returned after finding the
first end of deferrals, rather than searching for more
  • Loading branch information
dburgener committed May 2, 2023
1 parent 3bdfa38 commit e53c0ab
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
7 changes: 5 additions & 2 deletions src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ fn postvalidate_functions(
types: &TypeMap,
) -> Result<(), CascadeErrors> {
let mut deferrals = BTreeSet::new();
let mut errors = CascadeErrors::new();

for (name, fi) in functions.iter() {
for statement in fi.body.as_ref().unwrap_or(&BTreeSet::new()) {
Expand All @@ -645,10 +646,12 @@ fn postvalidate_functions(
}

for deferral in deferrals {
propagate(deferral.0, deferral.1, functions, types);
if let Err(e) = propagate(deferral.0, deferral.1, functions, types) {
errors.append(e);
}
}

Ok(())
errors.into_result(())
}

fn derive_functions<'a>(
Expand Down
45 changes: 32 additions & 13 deletions src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2576,25 +2576,30 @@ impl From<&DeferredCall> for ValidatedCall {
}
}

// TODO: Clean up unwraps.
// They should all be safe, since everything is validated at this point, but we should error
// instead of panicing if we got something wrong
pub fn propagate(
func_name: String,
deferral: DeferredStatement,
functions: &mut FunctionMap,
types: &TypeMap,
) {
let this_fi = functions.get(&func_name).unwrap();
) -> Result<(), CascadeErrors> {
let this_fi = functions
.get(&func_name)
.ok_or_else(|| CascadeErrors::from(ErrorItem::Internal(InternalError::new())))?;
// Clone so that we can keep the callers without keeping a reference to functions
let callers = this_fi.callers.clone();

for c in callers {
// We have to shadow this in the loop so that we won't hold the immutable borrow over the
// mutation below
let this_fi = functions.get(&func_name).unwrap();
let caller_dc_copy =
deferral.parent_copy(&c.passed_args, functions.get(&func_name).unwrap());
let this_fi = functions
.get(&func_name)
.ok_or_else(|| CascadeErrors::from(ErrorItem::Internal(InternalError::new())))?;
let caller_dc_copy = deferral.parent_copy(
&c.passed_args,
functions
.get(&func_name)
.ok_or_else(|| CascadeErrors::from(ErrorItem::Internal(InternalError::new())))?,
);
match &caller_dc_copy {
DeferredStatement::Call(dc) => {
let mut done = false;
Expand All @@ -2603,10 +2608,18 @@ pub fn propagate(
done = true;
}
{
let caller_fi = functions.get_mut(c.caller_name.as_ref()).unwrap();
caller_fi.body.as_mut().unwrap().insert(to_insert);
let caller_fi = functions.get_mut(c.caller_name.as_ref()).ok_or_else(|| {
CascadeErrors::from(ErrorItem::Internal(InternalError::new()))
})?;
caller_fi
.body
.as_mut()
.ok_or_else(|| {
CascadeErrors::from(ErrorItem::Internal(InternalError::new()))
})?
.insert(to_insert);
if done {
return;
continue;
}
}
}
Expand All @@ -2616,11 +2629,17 @@ pub fn propagate(
}
propagate(
c.caller_name.to_string(),
deferral.parent_copy(&c.passed_args, functions.get(&func_name).unwrap()),
deferral.parent_copy(
&c.passed_args,
functions.get(&func_name).ok_or_else(|| {
CascadeErrors::from(ErrorItem::Internal(InternalError::new()))
})?,
),
functions,
types,
);
)?;
}
Ok(())
}

// There are two cases we pass through to CIL:
Expand Down

0 comments on commit e53c0ab

Please sign in to comment.