mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +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")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
pub(in super::super) fn select_all_obligations_or_error(&self) {
|
pub(in super::super) fn report_ambiguity_errors(&self) {
|
||||||
let mut errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self);
|
let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors();
|
||||||
|
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
|
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.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() {
|
if let None = fcx.infcx.tainted_by_errors() {
|
||||||
fcx.check_transmutes();
|
fcx.check_transmutes();
|
||||||
|
@ -17,7 +17,7 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
|||||||
use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
|
use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
|
||||||
use crate::traits::query::{Fallible, NoSolution};
|
use crate::traits::query::{Fallible, NoSolution};
|
||||||
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
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_data_structures::captures::Captures;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
@ -36,10 +36,10 @@ pub trait TraitEngine<'tcx>: 'tcx {
|
|||||||
obligation: PredicateObligation<'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 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>>;
|
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +49,8 @@ pub trait TraitEngineExt<'tcx> {
|
|||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
obligations: impl IntoIterator<Item = PredicateObligation<'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 {
|
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);
|
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);
|
self.obligations.push(obligation);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> {
|
||||||
let errors = self.select_where_possible(infcx);
|
|
||||||
if !errors.is_empty() {
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.obligations
|
self.obligations
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.map(|obligation| FulfillmentError {
|
.map(|obligation| FulfillmentError {
|
||||||
|
@ -40,15 +40,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||||||
self.obligations.insert(obligation);
|
self.obligations.insert(obligation);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> {
|
||||||
{
|
|
||||||
let errors = self.select_where_possible(infcx);
|
|
||||||
|
|
||||||
if !errors.is_empty() {
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// any remaining obligations are errors
|
// any remaining obligations are errors
|
||||||
self.obligations
|
self.obligations
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -132,14 +132,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||||||
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
|
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> {
|
||||||
{
|
|
||||||
let errors = self.select_where_possible(infcx);
|
|
||||||
if !errors.is_empty() {
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
|
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// general routines.
|
// general routines.
|
||||||
|
|
||||||
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
|
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::traits::CodegenObligationError;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
|
Loading…
Reference in New Issue
Block a user