Skip to content

Commit

Permalink
Opt-in diagnostics reporting to avoid doing extra work in the new solver
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jun 1, 2024
1 parent 84d5118 commit 05d17ac
Show file tree
Hide file tree
Showing 31 changed files with 199 additions and 106 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,7 +1347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return;
};
// Try to find predicates on *generic params* that would allow copying `ty`
let ocx = ObligationCtxt::new(self.infcx);
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
let cause = ObligationCause::misc(span, self.mir_def_id());

ocx.register_bound(cause, self.param_env, ty, def_id);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ fn check_opaque_type_well_formed<'tcx>(
.with_next_trait_solver(next_trait_solver)
.with_opaque_type_inference(parent_def_id)
.build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let identity_args = GenericArgs::identity_for_item(tcx, def_id);

// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// which path expressions are getting called on and which path expressions are only used
// as function pointers. This is required for correctness.
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
let cause = ObligationCause::new(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ fn check_opaque_meets_bounds<'tcx>(
let param_env = tcx.param_env(defining_use_anchor);

let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

let args = match *origin {
hir::OpaqueTyOrigin::FnReturn(parent)
Expand Down Expand Up @@ -1727,7 +1727,7 @@ pub(super) fn check_coroutine_obligations(
.with_opaque_type_inference(def_id)
.build();

let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
for (predicate, cause) in &typeck_results.coroutine_stalled_predicates {
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate));
}
Expand Down
31 changes: 20 additions & 11 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_hir::intravisit;
use rustc_hir::{GenericParamKind, ImplItemKind};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_infer::traits::{util, FulfillmentErrorLike};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::util::ExplicitSelf;
Expand Down Expand Up @@ -225,7 +225,7 @@ fn compare_method_predicate_entailment<'tcx>(
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);

let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);

debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());

Expand Down Expand Up @@ -493,7 +493,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
);

let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);

// Normalize the impl signature with fresh variables for lifetime inference.
let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
Expand Down Expand Up @@ -764,17 +764,23 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
Ok(&*tcx.arena.alloc(remapped_types))
}

struct ImplTraitInTraitCollector<'a, 'tcx> {
ocx: &'a ObligationCtxt<'a, 'tcx>,
struct ImplTraitInTraitCollector<'a, 'tcx, E>
where
E: FulfillmentErrorLike<'tcx>,
{
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
types: FxIndexMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
span: Span,
param_env: ty::ParamEnv<'tcx>,
body_id: LocalDefId,
}

impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> {
impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E>
where
E: FulfillmentErrorLike<'tcx>,
{
fn new(
ocx: &'a ObligationCtxt<'a, 'tcx>,
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
span: Span,
param_env: ty::ParamEnv<'tcx>,
body_id: LocalDefId,
Expand All @@ -783,7 +789,10 @@ impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> {
}
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E>
where
E: FulfillmentErrorLike<'tcx>,
{
fn interner(&self) -> TyCtxt<'tcx> {
self.ocx.infcx.tcx
}
Expand Down Expand Up @@ -1777,7 +1786,7 @@ fn compare_const_predicate_entailment<'tcx>(
);

let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

let impl_ct_own_bounds = impl_ct_predicates.instantiate_own(tcx, impl_args);
for (predicate, span) in impl_ct_own_bounds {
Expand Down Expand Up @@ -1910,7 +1919,7 @@ fn compare_type_predicate_entailment<'tcx>(
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());

Expand Down Expand Up @@ -1977,7 +1986,7 @@ pub(super) fn check_type_bounds<'tcx>(
let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);

let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
adt_to_impl_args: GenericArgsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

// Take the param-env of the adt and instantiate the args that show up in
// the implementation's self type. This gives us the assumptions that the
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
main_diagnostics_def_id,
ObligationCauseCode::MainFunctionType,
);
let ocx = traits::ObligationCtxt::new(&infcx);
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty);
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
let errors = ocx.select_all_or_error();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ pub fn check_function_signature<'tcx>(
let param_env = ty::ParamEnv::empty();

let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);

let actual_sig = tcx.fn_sig(fn_id).instantiate_identity();

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@ use rustc_trait_selection::traits::misc::{
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
};
use rustc_type_ir::TypeFlags;

use std::cell::LazyCell;
use std::ops::{ControlFlow, Deref};

pub(super) struct WfCheckingCtxt<'a, 'tcx> {
pub(super) ocx: ObligationCtxt<'a, 'tcx>,
pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>,
span: Span,
body_def_id: LocalDefId,
param_env: ty::ParamEnv<'tcx>,
}
impl<'a, 'tcx> Deref for WfCheckingCtxt<'a, 'tcx> {
type Target = ObligationCtxt<'a, 'tcx>;
type Target = ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>;
fn deref(&self) -> &Self::Target {
&self.ocx
}
Expand Down Expand Up @@ -106,7 +106,7 @@ where
{
let param_env = tcx.param_env(body_def_id);
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);

let mut wfcx = WfCheckingCtxt { ocx, span, body_def_id, param_env };

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
.join(", "),
}));
} else {
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
for field in coerced_fields {
ocx.register_obligation(Obligation::new(
tcx,
Expand Down Expand Up @@ -480,7 +480,7 @@ pub fn coerce_unsized_info<'tcx>(
};

// Register an obligation for `A: Trait<B>`.
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let cause = traits::ObligationCause::misc(span, impl_did);
let obligation = Obligation::new(
tcx,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.copied()
.filter(|&(impl_, _)| {
infcx.probe(|_| {
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);

let impl_args = infcx.fresh_args_for_item(span, impl_);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn diagnostic_hir_wf_check<'tcx>(
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
let infcx = self.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

let tcx_ty = self.icx.lower_ty(ty);
// This visitor can walk into binders, resulting in the `tcx_ty` to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ fn get_impl_args(
impl2_node: Node,
) -> Result<(GenericArgsRef<'_>, GenericArgsRef<'_>), ErrorGuaranteed> {
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
let param_env = tcx.param_env(impl1_def_id);
let impl1_span = tcx.def_span(impl1_def_id);
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3048,7 +3048,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.commit_if_ok(|snapshot| {
let outer_universe = self.universe();

let ocx = ObligationCtxt::new(self);
let ocx = ObligationCtxt::new_with_diagnostics(self);
let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id);
let impl_trait_ref =
self.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(self.tcx, impl_args);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {

let mut result = ProbeResult::Match;
let cause = &self.misc(self.span);
let ocx = ObligationCtxt::new(self);
let ocx = ObligationCtxt::new_with_diagnostics(self);

let mut trait_predicate = None;
let (mut xform_self_ty, mut xform_ret_ty);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (obligation, _) =
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
// FIXME: This should potentially just add the obligation to the `FnCtxt`
let ocx = ObligationCtxt::new(&self.infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx);
ocx.register_obligation(obligation);
Err(ocx.select_all_or_error())
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,7 @@ fn check_field_tys_sized<'tcx>(
let infcx = tcx.infer_ctxt().ignoring_regions().build();
let param_env = tcx.param_env(def_id);

let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
for field_ty in &coroutine_layout.field_tys {
ocx.register_bound(
ObligationCause::new(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2321,7 +2321,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
let param_env = ty::ParamEnv::empty();

let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

let span = tcx.def_span(def_id);
let fresh_args = infcx.fresh_args_for_item(span, def_id.to_def_id());
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/layout_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub fn ensure_wf<'tcx>(
pred,
);
let infcx = tcx.infer_ctxt().build();
let ocx = traits::ObligationCtxt::new(&infcx);
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
ocx.register_obligation(obligation);
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
Expand Down
18 changes: 11 additions & 7 deletions compiler/rustc_trait_selection/src/infer.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use crate::solve::NextSolverError;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::{self, ObligationCtxt, SelectionContext};
use crate::traits::{
self, FromSolverError, Obligation, ObligationCause, ObligationCtxt, OldSolverError,
SelectionContext,
};

use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_infer::traits::Obligation;
use rustc_macros::extension;
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_middle::ty::{GenericArg, Upcast};
use rustc_span::DUMMY_SP;
Expand Down Expand Up @@ -94,7 +96,7 @@ impl<'tcx> InferCtxt<'tcx> {
ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
)) {
Ok(Some(selection)) => {
let ocx = ObligationCtxt::new(self);
let ocx = ObligationCtxt::new_with_diagnostics(self);
ocx.register_obligations(selection.nested_obligations());
Some(ocx.select_all_or_error())
}
Expand Down Expand Up @@ -122,19 +124,21 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// bound for the closure and in part because it is convenient to
/// have `'tcx` be free on this function so that we can talk about
/// `K: TypeFoldable<TyCtxt<'tcx>>`.)
fn enter_canonical_trait_query<K, R>(
fn enter_canonical_trait_query<K, R, E>(
self,
canonical_key: &Canonical<'tcx, K>,
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx, E>, K) -> Result<R, NoSolution>,
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
where
K: TypeFoldable<TyCtxt<'tcx>>,
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
E: FromSolverError<'tcx, NextSolverError<'tcx>>
+ FromSolverError<'tcx, OldSolverError<'tcx>>,
{
let (infcx, key, canonical_inference_vars) =
self.build_with_canonical(DUMMY_SP, canonical_key);
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new_generic(&infcx);
let value = operation(&ocx, key)?;
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
}
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_trait_selection/src/solve/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::symbol::sym;

use crate::traits::FulfillmentError;
use crate::traits::{FulfillmentError, ScrubbedTraitError};

use super::eval_ctxt::GenerateProofTree;
use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
Expand Down Expand Up @@ -226,6 +226,17 @@ impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for FulfillmentError<'tc
}
}

impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError {
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: NextSolverError<'tcx>) -> Self {
match error {
NextSolverError::TrueError(_) => ScrubbedTraitError::TrueError,
NextSolverError::Ambiguity(_) | NextSolverError::Overflow(_) => {
ScrubbedTraitError::Ambiguity
}
}
}
}

fn fulfillment_error_for_no_solution<'tcx>(
infcx: &InferCtxt<'tcx>,
root_obligation: PredicateObligation<'tcx>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use rustc_ast_ir::try_visit;
use rustc_ast_ir::visit::VisitorResult;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_infer::traits::FulfillmentErrorLike as _;
use rustc_macros::extension;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::solve::{inspect, QueryResult};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
let infcx = selcx.infcx;

if infcx.next_trait_solver() {
let ocx = ObligationCtxt::new(infcx);
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
ocx.register_obligations(obligations.iter().cloned());
let errors_and_ambiguities = ocx.select_all_or_error();
// We only care about the obligations that are *definitely* true errors.
Expand Down
Loading

0 comments on commit 05d17ac

Please sign in to comment.