Skip to content

Commit

Permalink
Disable ambiguity implication draining...it's tainting typeck
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinleroy committed Aug 13, 2024
1 parent fd18599 commit 2f0ee82
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 45 deletions.
89 changes: 46 additions & 43 deletions crates/argus/src/analysis/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,43 +55,44 @@ pub fn process_obligation<'tcx>(

log::trace!("RECV OBLIGATION {result:?} {obl:?}");

// Use this to get rid of any resolved inference variables,
// these could have been resolved while trying to solve the obligation
// and we want to present it as such to the user.
let obl = &infcx.resolve_vars_if_possible(obl.clone());

// HACK: Remove ambiguous obligations if a "stronger" result was found and
// the predicate implies the previous. This is necessary because we
// can't (currently) distinguish between a subsequent solving attempt
// of a previous obligation.
if result.is_yes() || result.is_no() {
tls::drain_implied_ambiguities(infcx, obl);
}
// Anything we accidentally do in here should not affect type checking
infcx.probe(|_| {
// Use this to get rid of any resolved inference variables,
// these could have been resolved while trying to solve the obligation
// and we want to present it as such to the user.
let obl = &infcx.resolve_vars_if_possible(obl.clone());

if !INCLUDE_SUCCESSES.copied().unwrap_or(false) && result.is_yes() {
log::debug!("Skipping successful obligation {obl:?}");
return;
}
// HACK: Remove ambiguous obligations if a "stronger" result was found and
// the predicate implies the previous. This is necessary because we
// can't (currently) distinguish between a subsequent solving attempt
// of a previous obligation.
if result.is_yes() || result.is_no() {
tls::drain_implied_ambiguities(infcx, obl);
}

let necessity = infcx.obligation_necessity(obl);
let dataid = if matches!(necessity, ObligationNecessity::Yes)
|| (matches!(necessity, ObligationNecessity::OnError) && result.is_no())
{
Some(tls::unsafe_store_data(infcx, obl, result))
} else {
None
};
if !INCLUDE_SUCCESSES.copied().unwrap_or(false) && result.is_yes() {
log::debug!("Skipping successful obligation {obl:?}");
return;
}

let obligation =
transform::compute_provenance(body_id, infcx, obl, result, dataid);
let necessity = infcx.obligation_necessity(obl);
let dataid = if matches!(necessity, ObligationNecessity::Yes)
|| (matches!(necessity, ObligationNecessity::OnError) && result.is_no())
{
Some(tls::unsafe_store_data(infcx, obl, result))
} else {
None
};

tls::store_obligation(obligation);
let obligation =
transform::compute_provenance(body_id, infcx, obl, result, dataid);

tls::replace_reported_errors(infcx);
tls::store_obligation(obligation);

tls::replace_reported_errors(infcx);
});
}

// FIXME: this *should* do less work than processing obligations normally would, but
// it seems to change(?) the typeck results, which is not good.
pub fn process_obligation_for_tree<'tcx>(
infcx: &InferCtxt<'tcx>,
obl: &PredicateObligation<'tcx>,
Expand All @@ -103,23 +104,25 @@ pub fn process_obligation_for_tree<'tcx>(
// Must go after the synthetic check.
guard_inspection! {}

// Use this to get rid of any resolved inference variables,
// these could have been resolved while trying to solve the obligation
// and we want to present it as such to the user.
let obl = &infcx.resolve_vars_if_possible(obl.clone());
infcx.probe(|_| {
// Use this to get rid of any resolved inference variables,
// these could have been resolved while trying to solve the obligation
// and we want to present it as such to the user.
let obl = &infcx.resolve_vars_if_possible(obl.clone());

let fdata = infcx.bless_fulfilled(obl, result);
let fdata = infcx.bless_fulfilled(obl, result);

if fdata.hash != target.hash {
return;
}
if fdata.hash != target.hash {
return;
}

match generate_tree(infcx, obl, fdata.result) {
Ok(stree) => tls::store_tree(stree),
Err(e) => {
log::error!("matching target tree not generated {e:?}");
match generate_tree(infcx, obl, fdata.result) {
Ok(stree) => tls::store_tree(stree),
Err(e) => {
log::error!("matching target tree not generated {e:?}");
}
}
}
})
});
}

Expand Down
4 changes: 2 additions & 2 deletions crates/argus/src/analysis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ pub fn tree(tcx: TyCtxt, body_id: BodyId) -> Result<SerializedTree> {
log::trace!("tree {body_id:?}");

let typeck_results =
// tcx.inspect_typeck(body_id, entry::process_obligation_for_tree);
tcx.inspect_typeck(body_id, entry::process_obligation);
tcx.inspect_typeck(body_id, entry::process_obligation_for_tree);
// tcx.inspect_typeck(body_id, entry::process_obligation);

entry::build_tree_output(tcx, body_id, typeck_results)
}
Expand Down
4 changes: 4 additions & 0 deletions crates/argus/src/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ pub fn drain_implied_ambiguities<'tcx>(
_infcx: &InferCtxt<'tcx>,
obligation: &PredicateObligation<'tcx>,
) {
// FIXME: this causes an internal compiler error that *should not happen*, it's setting
// tainted by errors to be true when it shouldn't.
return;

OBLIGATIONS.with(|obls| {
let mut obls = obls.borrow_mut();

Expand Down

0 comments on commit 2f0ee82

Please sign in to comment.