diff --git a/crates/argus/src/analysis/entry.rs b/crates/argus/src/analysis/entry.rs index a824c38..7a410aa 100644 --- a/crates/argus/src/analysis/entry.rs +++ b/crates/argus/src/analysis/entry.rs @@ -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>, @@ -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:?}"); + } } - } + }) }); } diff --git a/crates/argus/src/analysis/mod.rs b/crates/argus/src/analysis/mod.rs index 088f0c0..e6f5c03 100644 --- a/crates/argus/src/analysis/mod.rs +++ b/crates/argus/src/analysis/mod.rs @@ -61,8 +61,8 @@ pub fn tree(tcx: TyCtxt, body_id: BodyId) -> Result { 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) } diff --git a/crates/argus/src/tls.rs b/crates/argus/src/tls.rs index a4ed6f8..6a340a6 100644 --- a/crates/argus/src/tls.rs +++ b/crates/argus/src/tls.rs @@ -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();