mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Separate trait selection from ambiguity reporting.
This commit is contained in:
parent
2870ce01b8
commit
cb873b2d93
@ -525,8 +525,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(in super::super) fn select_all_obligations_or_error(&self) {
|
||||
let mut errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self);
|
||||
pub(in super::super) fn report_ambiguity_errors(&self) {
|
||||
let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors();
|
||||
|
||||
if !errors.is_empty() {
|
||||
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
|
||||
|
@ -301,7 +301,11 @@ fn typeck_with_fallback<'tcx>(
|
||||
fcx.require_type_is_sized(ty, span, code);
|
||||
}
|
||||
|
||||
fcx.select_all_obligations_or_error();
|
||||
fcx.select_obligations_where_possible(|_| {});
|
||||
|
||||
if let None = fcx.infcx.tainted_by_errors() {
|
||||
fcx.report_ambiguity_errors();
|
||||
}
|
||||
|
||||
if let None = fcx.infcx.tainted_by_errors() {
|
||||
fcx.check_transmutes();
|
||||
|
@ -17,7 +17,7 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
|
||||
use crate::traits::query::{Fallible, NoSolution};
|
||||
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
||||
use crate::traits::{PredicateObligations, TraitEngine};
|
||||
use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_index::vec::IndexVec;
|
||||
|
@ -36,10 +36,10 @@ pub trait TraitEngine<'tcx>: 'tcx {
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
);
|
||||
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
|
||||
|
||||
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
|
||||
|
||||
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>>;
|
||||
|
||||
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
|
||||
}
|
||||
|
||||
@ -49,6 +49,8 @@ pub trait TraitEngineExt<'tcx> {
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
|
||||
);
|
||||
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
|
||||
@ -61,4 +63,13 @@ impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
|
||||
self.register_predicate_obligation(infcx, obligation);
|
||||
}
|
||||
}
|
||||
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
||||
let errors = self.select_where_possible(infcx);
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
self.collect_remaining_errors()
|
||||
}
|
||||
}
|
||||
|
@ -40,12 +40,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
||||
self.obligations.push(obligation);
|
||||
}
|
||||
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
||||
let errors = self.select_where_possible(infcx);
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> {
|
||||
self.obligations
|
||||
.drain(..)
|
||||
.map(|obligation| FulfillmentError {
|
||||
|
@ -40,15 +40,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||
self.obligations.insert(obligation);
|
||||
}
|
||||
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
||||
{
|
||||
let errors = self.select_where_possible(infcx);
|
||||
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> {
|
||||
// any remaining obligations are errors
|
||||
self.obligations
|
||||
.iter()
|
||||
|
@ -132,14 +132,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
|
||||
}
|
||||
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
||||
{
|
||||
let errors = self.select_where_possible(infcx);
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> {
|
||||
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// general routines.
|
||||
|
||||
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
|
||||
use rustc_infer::traits::FulfillmentErrorCode;
|
||||
use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
|
||||
use rustc_middle::traits::CodegenObligationError;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
|
Loading…
Reference in New Issue
Block a user