mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Nits and formatting
This commit is contained in:
parent
1e72c7f536
commit
a41c44f21c
@ -10,7 +10,6 @@ use rustc_middle::traits::query::NoSolution;
|
|||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::solve::deeply_normalize;
|
|
||||||
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
||||||
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||||
use rustc_trait_selection::traits::ScrubbedTraitError;
|
use rustc_trait_selection::traits::ScrubbedTraitError;
|
||||||
@ -283,8 +282,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let result = CustomTypeOp::new(
|
let result = CustomTypeOp::new(
|
||||||
|ocx| {
|
|ocx| {
|
||||||
deeply_normalize(
|
ocx.deeply_normalize(
|
||||||
ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env),
|
&ObligationCause::dummy_with_span(self.span),
|
||||||
|
self.param_env,
|
||||||
ty,
|
ty,
|
||||||
)
|
)
|
||||||
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
|
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
|
||||||
|
@ -10,7 +10,7 @@ use rustc_hir::intravisit;
|
|||||||
use rustc_hir::{GenericParamKind, ImplItemKind};
|
use rustc_hir::{GenericParamKind, ImplItemKind};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::{util, FulfillmentErrorLike};
|
use rustc_infer::traits::util;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::BottomUpFolder;
|
||||||
use rustc_middle::ty::util::ExplicitSelf;
|
use rustc_middle::ty::util::ExplicitSelf;
|
||||||
@ -764,10 +764,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||||||
Ok(&*tcx.arena.alloc(remapped_types))
|
Ok(&*tcx.arena.alloc(remapped_types))
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImplTraitInTraitCollector<'a, 'tcx, E>
|
struct ImplTraitInTraitCollector<'a, 'tcx, E> {
|
||||||
where
|
|
||||||
E: FulfillmentErrorLike<'tcx>,
|
|
||||||
{
|
|
||||||
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
|
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
|
||||||
types: FxIndexMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
|
types: FxIndexMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -777,7 +774,7 @@ where
|
|||||||
|
|
||||||
impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E>
|
impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E>
|
||||||
where
|
where
|
||||||
E: FulfillmentErrorLike<'tcx>,
|
E: 'tcx,
|
||||||
{
|
{
|
||||||
fn new(
|
fn new(
|
||||||
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
|
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
|
||||||
@ -791,7 +788,7 @@ where
|
|||||||
|
|
||||||
impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E>
|
impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E>
|
||||||
where
|
where
|
||||||
E: FulfillmentErrorLike<'tcx>,
|
E: 'tcx,
|
||||||
{
|
{
|
||||||
fn interner(&self) -> TyCtxt<'tcx> {
|
fn interner(&self) -> TyCtxt<'tcx> {
|
||||||
self.ocx.infcx.tcx
|
self.ocx.infcx.tcx
|
||||||
|
@ -12,11 +12,8 @@ use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
|||||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams};
|
||||||
self, IsFirstInputType, ScrubbedTraitError, UncoveredTyParams,
|
|
||||||
};
|
|
||||||
use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode};
|
use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode};
|
||||||
use rustc_trait_selection::traits::{StructurallyNormalizeExt, TraitEngineExt};
|
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(tcx))]
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
pub(crate) fn orphan_check_impl(
|
pub(crate) fn orphan_check_impl(
|
||||||
@ -319,13 +316,12 @@ fn orphan_check<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ty = if infcx.next_trait_solver() {
|
let ty = if infcx.next_trait_solver() {
|
||||||
let mut fulfill_cx =
|
ocx.structurally_normalize(
|
||||||
<dyn traits::TraitEngine<'tcx, ScrubbedTraitError<'tcx>>>::new(&infcx);
|
&cause,
|
||||||
infcx
|
ty::ParamEnv::empty(),
|
||||||
.at(&cause, ty::ParamEnv::empty())
|
infcx.resolve_vars_if_possible(ty),
|
||||||
.structurally_normalize(ty, &mut *fulfill_cx)
|
)
|
||||||
.map(|ty| infcx.resolve_vars_if_possible(ty))
|
.unwrap_or(ty)
|
||||||
.unwrap_or(ty)
|
|
||||||
} else {
|
} else {
|
||||||
ty
|
ty
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,8 @@ use crate::infer::canonical::{
|
|||||||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult};
|
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult};
|
||||||
use crate::traits::query::NoSolution;
|
use crate::traits::query::NoSolution;
|
||||||
use crate::traits::{FulfillmentErrorLike, TraitEngine};
|
|
||||||
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
||||||
|
use crate::traits::{ScrubbedTraitError, TraitEngine};
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
@ -50,11 +50,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
/// - Finally, if any of the obligations result in a hard error,
|
/// - Finally, if any of the obligations result in a hard error,
|
||||||
/// then `Err(NoSolution)` is returned.
|
/// then `Err(NoSolution)` is returned.
|
||||||
#[instrument(skip(self, inference_vars, answer, fulfill_cx), level = "trace")]
|
#[instrument(skip(self, inference_vars, answer, fulfill_cx), level = "trace")]
|
||||||
pub fn make_canonicalized_query_response<T, E: FulfillmentErrorLike<'tcx>>(
|
pub fn make_canonicalized_query_response<T>(
|
||||||
&self,
|
&self,
|
||||||
inference_vars: CanonicalVarValues<'tcx>,
|
inference_vars: CanonicalVarValues<'tcx>,
|
||||||
answer: T,
|
answer: T,
|
||||||
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>,
|
||||||
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
|
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
|
||||||
where
|
where
|
||||||
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||||
@ -97,11 +97,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
/// Helper for `make_canonicalized_query_response` that does
|
/// Helper for `make_canonicalized_query_response` that does
|
||||||
/// everything up until the final canonicalization.
|
/// everything up until the final canonicalization.
|
||||||
#[instrument(skip(self, fulfill_cx), level = "debug")]
|
#[instrument(skip(self, fulfill_cx), level = "debug")]
|
||||||
fn make_query_response<T, E: FulfillmentErrorLike<'tcx>>(
|
fn make_query_response<T>(
|
||||||
&self,
|
&self,
|
||||||
inference_vars: CanonicalVarValues<'tcx>,
|
inference_vars: CanonicalVarValues<'tcx>,
|
||||||
answer: T,
|
answer: T,
|
||||||
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>,
|
||||||
) -> Result<QueryResponse<'tcx, T>, NoSolution>
|
) -> Result<QueryResponse<'tcx, T>, NoSolution>
|
||||||
where
|
where
|
||||||
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
@ -12,8 +12,7 @@ pub use SubregionOrigin::*;
|
|||||||
pub use ValuePairs::*;
|
pub use ValuePairs::*;
|
||||||
|
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
self, FulfillmentErrorLike, ObligationCause, ObligationInspector, PredicateObligations,
|
self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine,
|
||||||
TraitEngine,
|
|
||||||
};
|
};
|
||||||
use error_reporting::TypeErrCtxt;
|
use error_reporting::TypeErrCtxt;
|
||||||
use free_regions::RegionRelations;
|
use free_regions::RegionRelations;
|
||||||
@ -738,7 +737,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||||||
|
|
||||||
impl<'tcx, T> InferOk<'tcx, T> {
|
impl<'tcx, T> InferOk<'tcx, T> {
|
||||||
/// Extracts `value`, registering any obligations into `fulfill_cx`.
|
/// Extracts `value`, registering any obligations into `fulfill_cx`.
|
||||||
pub fn into_value_registering_obligations<E: FulfillmentErrorLike<'tcx>>(
|
pub fn into_value_registering_obligations<E: 'tcx>(
|
||||||
self,
|
self,
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
||||||
|
@ -7,7 +7,32 @@ use rustc_middle::ty::{self, Ty, Upcast};
|
|||||||
|
|
||||||
use super::{ObligationCause, PredicateObligation};
|
use super::{ObligationCause, PredicateObligation};
|
||||||
|
|
||||||
pub trait TraitEngine<'tcx, E: FulfillmentErrorLike<'tcx>>: 'tcx {
|
/// A trait error with most of its information removed. This is the error
|
||||||
|
/// returned by an `ObligationCtxt` by default, and suitable if you just
|
||||||
|
/// want to see if a predicate holds, and don't particularly care about the
|
||||||
|
/// error itself (except for if it's an ambiguity or true error).
|
||||||
|
///
|
||||||
|
/// use `ObligationCtxt::new_with_diagnostics` to get a `FulfillmentError`.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ScrubbedTraitError<'tcx> {
|
||||||
|
/// A real error. This goal definitely does not hold.
|
||||||
|
TrueError,
|
||||||
|
/// An ambiguity. This goal may hold if further inference is done.
|
||||||
|
Ambiguity,
|
||||||
|
/// An old-solver-style cycle error, which will fatal.
|
||||||
|
Cycle(Vec<PredicateObligation<'tcx>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ScrubbedTraitError<'tcx> {
|
||||||
|
pub fn is_true_error(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
ScrubbedTraitError::TrueError => true,
|
||||||
|
ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||||
/// Requires that `ty` must implement the trait with `def_id` in
|
/// Requires that `ty` must implement the trait with `def_id` in
|
||||||
/// the given environment. This trait must not have any type
|
/// the given environment. This trait must not have any type
|
||||||
/// parameters (except for `Self`).
|
/// parameters (except for `Self`).
|
||||||
@ -73,10 +98,6 @@ pub trait TraitEngine<'tcx, E: FulfillmentErrorLike<'tcx>>: 'tcx {
|
|||||||
) -> Vec<PredicateObligation<'tcx>>;
|
) -> Vec<PredicateObligation<'tcx>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FulfillmentErrorLike<'tcx>: Debug + 'tcx {
|
pub trait FromSolverError<'tcx, E>: Debug + 'tcx {
|
||||||
fn is_true_error(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FromSolverError<'tcx, E>: FulfillmentErrorLike<'tcx> {
|
|
||||||
fn from_solver_error(infcx: &InferCtxt<'tcx>, error: E) -> Self;
|
fn from_solver_error(infcx: &InferCtxt<'tcx>, error: E) -> Self;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ pub use self::ImplSource::*;
|
|||||||
pub use self::SelectionError::*;
|
pub use self::SelectionError::*;
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
|
|
||||||
pub use self::engine::{FromSolverError, FulfillmentErrorLike, TraitEngine};
|
pub use self::engine::{FromSolverError, ScrubbedTraitError, TraitEngine};
|
||||||
pub use self::project::MismatchedProjectionTypes;
|
pub use self::project::MismatchedProjectionTypes;
|
||||||
pub(crate) use self::project::UndoLog;
|
pub(crate) use self::project::UndoLog;
|
||||||
pub use self::project::{
|
pub use self::project::{
|
||||||
|
@ -6,6 +6,7 @@ use syn::spanned::Spanned;
|
|||||||
use syn::{
|
use syn::{
|
||||||
braced, parse_macro_input, Attribute, Generics, ImplItem, Pat, PatIdent, Path, Signature,
|
braced, parse_macro_input, Attribute, Generics, ImplItem, Pat, PatIdent, Path, Signature,
|
||||||
Token, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, Type, Visibility,
|
Token, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, Type, Visibility,
|
||||||
|
WhereClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn extension(
|
pub(crate) fn extension(
|
||||||
@ -13,7 +14,7 @@ pub(crate) fn extension(
|
|||||||
input: proc_macro::TokenStream,
|
input: proc_macro::TokenStream,
|
||||||
) -> proc_macro::TokenStream {
|
) -> proc_macro::TokenStream {
|
||||||
let ExtensionAttr { vis, trait_ } = parse_macro_input!(attr as ExtensionAttr);
|
let ExtensionAttr { vis, trait_ } = parse_macro_input!(attr as ExtensionAttr);
|
||||||
let Impl { attrs, generics, self_ty, items } = parse_macro_input!(input as Impl);
|
let Impl { attrs, generics, self_ty, items, wc } = parse_macro_input!(input as Impl);
|
||||||
let headers: Vec<_> = items
|
let headers: Vec<_> = items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| match item {
|
.map(|item| match item {
|
||||||
@ -59,7 +60,7 @@ pub(crate) fn extension(
|
|||||||
#(#headers)*
|
#(#headers)*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #generics #trait_ for #self_ty {
|
impl #generics #trait_ for #self_ty #wc {
|
||||||
#(#items)*
|
#(#items)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,6 +134,7 @@ struct Impl {
|
|||||||
generics: Generics,
|
generics: Generics,
|
||||||
self_ty: Type,
|
self_ty: Type,
|
||||||
items: Vec<ImplItem>,
|
items: Vec<ImplItem>,
|
||||||
|
wc: Option<WhereClause>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Impl {
|
impl Parse for Impl {
|
||||||
@ -141,6 +143,7 @@ impl Parse for Impl {
|
|||||||
let _: Token![impl] = input.parse()?;
|
let _: Token![impl] = input.parse()?;
|
||||||
let generics = input.parse()?;
|
let generics = input.parse()?;
|
||||||
let self_ty = input.parse()?;
|
let self_ty = input.parse()?;
|
||||||
|
let wc = input.parse()?;
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
let _brace_token = braced!(content in input);
|
let _brace_token = braced!(content in input);
|
||||||
@ -149,6 +152,6 @@ impl Parse for Impl {
|
|||||||
items.push(content.parse()?);
|
items.push(content.parse()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Impl { attrs, generics, self_ty, items })
|
Ok(Impl { attrs, generics, self_ty, items, wc })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ use rustc_infer::infer::InferCtxt;
|
|||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause};
|
use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause};
|
||||||
use rustc_infer::traits::{
|
use rustc_infer::traits::{
|
||||||
self, FromSolverError, FulfillmentErrorLike, MismatchedProjectionTypes, Obligation,
|
self, FromSolverError, MismatchedProjectionTypes, Obligation, ObligationCause,
|
||||||
ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine,
|
ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine,
|
||||||
};
|
};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
@ -31,7 +31,7 @@ use super::{Certainty, InferCtxtEvalExt};
|
|||||||
///
|
///
|
||||||
/// It is also likely that we want to use slightly different datastructures
|
/// It is also likely that we want to use slightly different datastructures
|
||||||
/// here as this will have to deal with far more root goals than `evaluate_all`.
|
/// here as this will have to deal with far more root goals than `evaluate_all`.
|
||||||
pub struct FulfillmentCtxt<'tcx, E: FulfillmentErrorLike<'tcx>> {
|
pub struct FulfillmentCtxt<'tcx, E: 'tcx> {
|
||||||
obligations: ObligationStorage<'tcx>,
|
obligations: ObligationStorage<'tcx>,
|
||||||
|
|
||||||
/// The snapshot in which this context was created. Using the context
|
/// The snapshot in which this context was created. Using the context
|
||||||
@ -93,7 +93,7 @@ impl<'tcx> ObligationStorage<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, E: FulfillmentErrorLike<'tcx>> FulfillmentCtxt<'tcx, E> {
|
impl<'tcx, E: 'tcx> FulfillmentCtxt<'tcx, E> {
|
||||||
pub fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentCtxt<'tcx, E> {
|
pub fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentCtxt<'tcx, E> {
|
||||||
assert!(
|
assert!(
|
||||||
infcx.next_trait_solver(),
|
infcx.next_trait_solver(),
|
||||||
@ -123,8 +123,9 @@ impl<'tcx, E: FulfillmentErrorLike<'tcx>> FulfillmentCtxt<'tcx, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, E: FromSolverError<'tcx, NextSolverError<'tcx>>> TraitEngine<'tcx, E>
|
impl<'tcx, E> TraitEngine<'tcx, E> for FulfillmentCtxt<'tcx, E>
|
||||||
for FulfillmentCtxt<'tcx, E>
|
where
|
||||||
|
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||||
{
|
{
|
||||||
#[instrument(level = "trace", skip(self, infcx))]
|
#[instrument(level = "trace", skip(self, infcx))]
|
||||||
fn register_predicate_obligation(
|
fn register_predicate_obligation(
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
use rustc_ast_ir::try_visit;
|
use rustc_ast_ir::try_visit;
|
||||||
use rustc_ast_ir::visit::VisitorResult;
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
||||||
use rustc_infer::traits::FulfillmentErrorLike as _;
|
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::traits::solve::{inspect, QueryResult};
|
use rustc_middle::traits::solve::{inspect, QueryResult};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
|
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
|
||||||
@ -6,7 +7,7 @@ use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError};
|
|||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_infer::infer::at::At;
|
use rustc_infer::infer::at::At;
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_infer::traits::{FromSolverError, FulfillmentErrorLike, Obligation, TraitEngine};
|
use rustc_infer::traits::{FromSolverError, Obligation, TraitEngine};
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex};
|
use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex};
|
||||||
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
||||||
@ -16,14 +17,11 @@ use super::{FulfillmentCtxt, NextSolverError};
|
|||||||
|
|
||||||
/// Deeply normalize all aliases in `value`. This does not handle inference and expects
|
/// Deeply normalize all aliases in `value`. This does not handle inference and expects
|
||||||
/// its input to be already fully resolved.
|
/// its input to be already fully resolved.
|
||||||
pub fn deeply_normalize<
|
pub fn deeply_normalize<'tcx, T, E>(at: At<'_, 'tcx>, value: T) -> Result<T, Vec<E>>
|
||||||
'tcx,
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||||
>(
|
{
|
||||||
at: At<'_, 'tcx>,
|
|
||||||
value: T,
|
|
||||||
) -> Result<T, Vec<E>> {
|
|
||||||
assert!(!value.has_escaping_bound_vars());
|
assert!(!value.has_escaping_bound_vars());
|
||||||
deeply_normalize_with_skipped_universes(at, value, vec![])
|
deeply_normalize_with_skipped_universes(at, value, vec![])
|
||||||
}
|
}
|
||||||
@ -34,15 +32,15 @@ pub fn deeply_normalize<
|
|||||||
/// Additionally takes a list of universes which represents the binders which have been
|
/// Additionally takes a list of universes which represents the binders which have been
|
||||||
/// entered before passing `value` to the function. This is currently needed for
|
/// entered before passing `value` to the function. This is currently needed for
|
||||||
/// `normalize_erasing_regions`, which skips binders as it walks through a type.
|
/// `normalize_erasing_regions`, which skips binders as it walks through a type.
|
||||||
pub fn deeply_normalize_with_skipped_universes<
|
pub fn deeply_normalize_with_skipped_universes<'tcx, T, E>(
|
||||||
'tcx,
|
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
|
||||||
>(
|
|
||||||
at: At<'_, 'tcx>,
|
at: At<'_, 'tcx>,
|
||||||
value: T,
|
value: T,
|
||||||
universes: Vec<Option<UniverseIndex>>,
|
universes: Vec<Option<UniverseIndex>>,
|
||||||
) -> Result<T, Vec<E>> {
|
) -> Result<T, Vec<E>>
|
||||||
|
where
|
||||||
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||||
|
{
|
||||||
let fulfill_cx = FulfillmentCtxt::new(at.infcx);
|
let fulfill_cx = FulfillmentCtxt::new(at.infcx);
|
||||||
let mut folder =
|
let mut folder =
|
||||||
NormalizationFolder { at, fulfill_cx, depth: 0, universes, _errors: PhantomData };
|
NormalizationFolder { at, fulfill_cx, depth: 0, universes, _errors: PhantomData };
|
||||||
@ -50,7 +48,7 @@ pub fn deeply_normalize_with_skipped_universes<
|
|||||||
value.try_fold_with(&mut folder)
|
value.try_fold_with(&mut folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NormalizationFolder<'me, 'tcx, E: FulfillmentErrorLike<'tcx>> {
|
struct NormalizationFolder<'me, 'tcx, E> {
|
||||||
at: At<'me, 'tcx>,
|
at: At<'me, 'tcx>,
|
||||||
fulfill_cx: FulfillmentCtxt<'tcx, E>,
|
fulfill_cx: FulfillmentCtxt<'tcx, E>,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
@ -58,7 +56,10 @@ struct NormalizationFolder<'me, 'tcx, E: FulfillmentErrorLike<'tcx>> {
|
|||||||
_errors: PhantomData<E>,
|
_errors: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, E: FromSolverError<'tcx, NextSolverError<'tcx>>> NormalizationFolder<'_, 'tcx, E> {
|
impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
|
||||||
|
where
|
||||||
|
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||||
|
{
|
||||||
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
|
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
|
||||||
assert!(matches!(alias_ty.kind(), ty::Alias(..)));
|
assert!(matches!(alias_ty.kind(), ty::Alias(..)));
|
||||||
|
|
||||||
@ -150,8 +151,9 @@ impl<'tcx, E: FromSolverError<'tcx, NextSolverError<'tcx>>> NormalizationFolder<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, E: FromSolverError<'tcx, NextSolverError<'tcx>>> FallibleTypeFolder<TyCtxt<'tcx>>
|
impl<'tcx, E> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx, E>
|
||||||
for NormalizationFolder<'_, 'tcx, E>
|
where
|
||||||
|
E: FromSolverError<'tcx, NextSolverError<'tcx>> + Debug,
|
||||||
{
|
{
|
||||||
type Error = Vec<E>;
|
type Error = Vec<E>;
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ use rustc_infer::infer::canonical::{
|
|||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::RegionResolutionError;
|
use rustc_infer::infer::RegionResolutionError;
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
||||||
use rustc_infer::traits::FulfillmentErrorLike;
|
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::arena::ArenaAllocatable;
|
use rustc_middle::arena::ArenaAllocatable;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
@ -32,10 +31,9 @@ use rustc_middle::ty::Variance;
|
|||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
|
||||||
#[extension(pub trait TraitEngineExt<'tcx, E>)]
|
#[extension(pub trait TraitEngineExt<'tcx, E>)]
|
||||||
impl<
|
impl<'tcx, E> dyn TraitEngine<'tcx, E>
|
||||||
'tcx,
|
where
|
||||||
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
|
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
|
||||||
> dyn TraitEngine<'tcx, E>
|
|
||||||
{
|
{
|
||||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
|
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
|
||||||
if infcx.next_trait_solver() {
|
if infcx.next_trait_solver() {
|
||||||
@ -73,7 +71,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError<'tcx>> {
|
|||||||
|
|
||||||
impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
|
impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
|
||||||
where
|
where
|
||||||
E: FulfillmentErrorLike<'tcx>,
|
E: 'tcx,
|
||||||
{
|
{
|
||||||
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {
|
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {
|
||||||
self.engine.borrow_mut().register_predicate_obligation(self.infcx, obligation);
|
self.engine.borrow_mut().register_predicate_obligation(self.infcx, obligation);
|
||||||
@ -231,7 +229,20 @@ where
|
|||||||
) -> Vec<RegionResolutionError<'tcx>> {
|
) -> Vec<RegionResolutionError<'tcx>> {
|
||||||
self.infcx.resolve_regions(outlives_env)
|
self.infcx.resolve_regions(outlives_env)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>> {
|
||||||
|
pub fn assumed_wf_types_and_report_errors(
|
||||||
|
&self,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> Result<FxIndexSet<Ty<'tcx>>, ErrorGuaranteed> {
|
||||||
|
self.assumed_wf_types(param_env, def_id)
|
||||||
|
.map_err(|errors| self.infcx.err_ctxt().report_fulfillment_errors(errors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ObligationCtxt<'_, 'tcx, ScrubbedTraitError<'tcx>> {
|
||||||
pub fn make_canonicalized_query_response<T>(
|
pub fn make_canonicalized_query_response<T>(
|
||||||
&self,
|
&self,
|
||||||
inference_vars: CanonicalVarValues<'tcx>,
|
inference_vars: CanonicalVarValues<'tcx>,
|
||||||
@ -249,17 +260,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>> {
|
|
||||||
pub fn assumed_wf_types_and_report_errors(
|
|
||||||
&self,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
def_id: LocalDefId,
|
|
||||||
) -> Result<FxIndexSet<Ty<'tcx>>, ErrorGuaranteed> {
|
|
||||||
self.assumed_wf_types(param_env, def_id)
|
|
||||||
.map_err(|errors| self.infcx.err_ctxt().report_fulfillment_errors(errors))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, E> ObligationCtxt<'_, 'tcx, E>
|
impl<'tcx, E> ObligationCtxt<'_, 'tcx, E>
|
||||||
where
|
where
|
||||||
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||||
|
@ -6,7 +6,7 @@ use rustc_data_structures::obligation_forest::ProcessResult;
|
|||||||
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
||||||
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
||||||
use rustc_infer::infer::DefineOpaqueTypes;
|
use rustc_infer::infer::DefineOpaqueTypes;
|
||||||
use rustc_infer::traits::{FromSolverError, FulfillmentErrorLike, ProjectionCacheKey};
|
use rustc_infer::traits::{FromSolverError, ProjectionCacheKey};
|
||||||
use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
|
use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
@ -50,7 +50,7 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
|
|||||||
/// along. Once all type inference constraints have been generated, the
|
/// along. Once all type inference constraints have been generated, the
|
||||||
/// method `select_all_or_error` can be used to report any remaining
|
/// method `select_all_or_error` can be used to report any remaining
|
||||||
/// ambiguous cases as errors.
|
/// ambiguous cases as errors.
|
||||||
pub struct FulfillmentContext<'tcx, E: FulfillmentErrorLike<'tcx>> {
|
pub struct FulfillmentContext<'tcx, E: 'tcx> {
|
||||||
/// A list of all obligations that have been registered with this
|
/// A list of all obligations that have been registered with this
|
||||||
/// fulfillment context.
|
/// fulfillment context.
|
||||||
predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
|
predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
|
||||||
@ -78,7 +78,10 @@ pub struct PendingPredicateObligation<'tcx> {
|
|||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
rustc_data_structures::static_assert_size!(PendingPredicateObligation<'_>, 72);
|
rustc_data_structures::static_assert_size!(PendingPredicateObligation<'_>, 72);
|
||||||
|
|
||||||
impl<'tcx, E: FromSolverError<'tcx, OldSolverError<'tcx>>> FulfillmentContext<'tcx, E> {
|
impl<'tcx, E> FulfillmentContext<'tcx, E>
|
||||||
|
where
|
||||||
|
E: FromSolverError<'tcx, OldSolverError<'tcx>>,
|
||||||
|
{
|
||||||
/// Creates a new fulfillment context.
|
/// Creates a new fulfillment context.
|
||||||
pub(super) fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentContext<'tcx, E> {
|
pub(super) fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentContext<'tcx, E> {
|
||||||
assert!(
|
assert!(
|
||||||
@ -106,8 +109,11 @@ impl<'tcx, E: FromSolverError<'tcx, OldSolverError<'tcx>>> FulfillmentContext<'t
|
|||||||
// FIXME: if we kept the original cache key, we could mark projection
|
// FIXME: if we kept the original cache key, we could mark projection
|
||||||
// obligations as complete for the projection cache here.
|
// obligations as complete for the projection cache here.
|
||||||
|
|
||||||
let errors: Vec<E> =
|
let errors: Vec<E> = outcome
|
||||||
outcome.errors.into_iter().map(|err| E::from_solver_error(infcx, err)).collect();
|
.errors
|
||||||
|
.into_iter()
|
||||||
|
.map(|err| E::from_solver_error(infcx, OldSolverError(err)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"select({} predicates remaining, {} errors) done",
|
"select({} predicates remaining, {} errors) done",
|
||||||
@ -119,8 +125,9 @@ impl<'tcx, E: FromSolverError<'tcx, OldSolverError<'tcx>>> FulfillmentContext<'t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, E: FromSolverError<'tcx, OldSolverError<'tcx>>> TraitEngine<'tcx, E>
|
impl<'tcx, E> TraitEngine<'tcx, E> for FulfillmentContext<'tcx, E>
|
||||||
for FulfillmentContext<'tcx, E>
|
where
|
||||||
|
E: FromSolverError<'tcx, OldSolverError<'tcx>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn register_predicate_obligation(
|
fn register_predicate_obligation(
|
||||||
@ -144,7 +151,7 @@ impl<'tcx, E: FromSolverError<'tcx, OldSolverError<'tcx>>> TraitEngine<'tcx, E>
|
|||||||
self.predicates
|
self.predicates
|
||||||
.to_errors(FulfillmentErrorCode::Ambiguity { overflow: None })
|
.to_errors(FulfillmentErrorCode::Ambiguity { overflow: None })
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|err| E::from_solver_error(infcx, err))
|
.map(|err| E::from_solver_error(infcx, OldSolverError(err)))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,22 +850,25 @@ fn args_infer_vars<'a, 'tcx>(
|
|||||||
.filter_map(TyOrConstInferVar::maybe_from_generic_arg)
|
.filter_map(TyOrConstInferVar::maybe_from_generic_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type OldSolverError<'tcx> = Error<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>>;
|
#[derive(Debug)]
|
||||||
|
pub struct OldSolverError<'tcx>(
|
||||||
|
Error<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>>,
|
||||||
|
);
|
||||||
|
|
||||||
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx> {
|
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx> {
|
||||||
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
|
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
|
||||||
let mut iter = error.backtrace.into_iter();
|
let mut iter = error.0.backtrace.into_iter();
|
||||||
let obligation = iter.next().unwrap().obligation;
|
let obligation = iter.next().unwrap().obligation;
|
||||||
// The root obligation is the last item in the backtrace - if there's only
|
// The root obligation is the last item in the backtrace - if there's only
|
||||||
// one item, then it's the same as the main obligation
|
// one item, then it's the same as the main obligation
|
||||||
let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation);
|
let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation);
|
||||||
FulfillmentError::new(obligation, error.error, root_obligation)
|
FulfillmentError::new(obligation, error.0.error, root_obligation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> {
|
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> {
|
||||||
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
|
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
|
||||||
match error.error {
|
match error.0.error {
|
||||||
FulfillmentErrorCode::Select(_)
|
FulfillmentErrorCode::Select(_)
|
||||||
| FulfillmentErrorCode::Project(_)
|
| FulfillmentErrorCode::Project(_)
|
||||||
| FulfillmentErrorCode::Subtype(_, _)
|
| FulfillmentErrorCode::Subtype(_, _)
|
||||||
|
@ -71,37 +71,6 @@ pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, Placeh
|
|||||||
|
|
||||||
pub use rustc_infer::traits::*;
|
pub use rustc_infer::traits::*;
|
||||||
|
|
||||||
/// A trait error with most of its information removed. This is the error
|
|
||||||
/// returned by an [`ObligationCtxt`] by default, and suitable if you just
|
|
||||||
/// want to see if a predicate holds, and don't particularly care about the
|
|
||||||
/// error itself (except for if it's an ambiguity or true error).
|
|
||||||
///
|
|
||||||
/// use [`ObligationCtxt::new_with_diagnostics`] to get a [`FulfillmentError`].
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum ScrubbedTraitError<'tcx> {
|
|
||||||
/// A real error. This goal definitely does not hold.
|
|
||||||
TrueError,
|
|
||||||
/// An ambiguity. This goal may hold if further inference is done.
|
|
||||||
Ambiguity,
|
|
||||||
/// An old-solver-style cycle error, which will fatal.
|
|
||||||
Cycle(Vec<PredicateObligation<'tcx>>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> ScrubbedTraitError<'tcx> {
|
|
||||||
fn is_true_error(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
ScrubbedTraitError::TrueError => true,
|
|
||||||
ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> FulfillmentErrorLike<'tcx> for ScrubbedTraitError<'tcx> {
|
|
||||||
fn is_true_error(&self) -> bool {
|
|
||||||
self.is_true_error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct FulfillmentError<'tcx> {
|
pub struct FulfillmentError<'tcx> {
|
||||||
pub obligation: PredicateObligation<'tcx>,
|
pub obligation: PredicateObligation<'tcx>,
|
||||||
pub code: FulfillmentErrorCode<'tcx>,
|
pub code: FulfillmentErrorCode<'tcx>,
|
||||||
@ -133,12 +102,6 @@ impl<'tcx> FulfillmentError<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> FulfillmentErrorLike<'tcx> for FulfillmentError<'tcx> {
|
|
||||||
fn is_true_error(&self) -> bool {
|
|
||||||
self.is_true_error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Debug for FulfillmentError<'tcx> {
|
impl<'tcx> Debug for FulfillmentError<'tcx> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "FulfillmentError({:?},{:?})", self.obligation, self.code)
|
write!(f, "FulfillmentError({:?},{:?})", self.obligation, self.code)
|
||||||
|
@ -46,14 +46,15 @@ impl<'tcx> At<'_, 'tcx> {
|
|||||||
/// existing fulfillment context in the old solver. Once we also eagerly prove goals with
|
/// existing fulfillment context in the old solver. Once we also eagerly prove goals with
|
||||||
/// the old solver or have removed the old solver, remove `traits::fully_normalize` and
|
/// the old solver or have removed the old solver, remove `traits::fully_normalize` and
|
||||||
/// rename this function to `At::fully_normalize`.
|
/// rename this function to `At::fully_normalize`.
|
||||||
fn deeply_normalize<
|
fn deeply_normalize<T, E>(
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
|
||||||
>(
|
|
||||||
self,
|
self,
|
||||||
value: T,
|
value: T,
|
||||||
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
||||||
) -> Result<T, Vec<E>> {
|
) -> Result<T, Vec<E>>
|
||||||
|
where
|
||||||
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||||
|
{
|
||||||
if self.infcx.next_trait_solver() {
|
if self.infcx.next_trait_solver() {
|
||||||
crate::solve::deeply_normalize(self, value)
|
crate::solve::deeply_normalize(self, value)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use crate::solve;
|
|
||||||
use crate::traits::query::NoSolution;
|
use crate::traits::query::NoSolution;
|
||||||
use crate::traits::wf;
|
use crate::traits::wf;
|
||||||
use crate::traits::ObligationCtxt;
|
use crate::traits::ObligationCtxt;
|
||||||
use crate::traits::ScrubbedTraitError;
|
|
||||||
|
|
||||||
use rustc_infer::infer::canonical::Canonical;
|
use rustc_infer::infer::canonical::Canonical;
|
||||||
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
|
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
|
||||||
@ -263,11 +261,9 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
|
|||||||
let mut ty_a = ocx.infcx.resolve_vars_if_possible(ty_a);
|
let mut ty_a = ocx.infcx.resolve_vars_if_possible(ty_a);
|
||||||
// Need to manually normalize in the new solver as `wf::obligations` does not.
|
// Need to manually normalize in the new solver as `wf::obligations` does not.
|
||||||
if ocx.infcx.next_trait_solver() {
|
if ocx.infcx.next_trait_solver() {
|
||||||
ty_a = solve::deeply_normalize(
|
ty_a = ocx
|
||||||
ocx.infcx.at(&ObligationCause::dummy(), param_env),
|
.deeply_normalize(&ObligationCause::dummy(), param_env, ty_a)
|
||||||
ty_a,
|
.map_err(|_| NoSolution)?;
|
||||||
)
|
|
||||||
.map_err(|_errs: Vec<ScrubbedTraitError<'tcx>>| NoSolution)?;
|
|
||||||
}
|
}
|
||||||
let mut components = smallvec![];
|
let mut components = smallvec![];
|
||||||
push_outlives_components(tcx, ty_a, &mut components);
|
push_outlives_components(tcx, ty_a, &mut components);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use rustc_infer::infer::at::At;
|
use rustc_infer::infer::at::At;
|
||||||
use rustc_infer::traits::{FulfillmentErrorLike, TraitEngine};
|
use rustc_infer::traits::TraitEngine;
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ use crate::traits::{NormalizeExt, Obligation};
|
|||||||
|
|
||||||
#[extension(pub trait StructurallyNormalizeExt<'tcx>)]
|
#[extension(pub trait StructurallyNormalizeExt<'tcx>)]
|
||||||
impl<'tcx> At<'_, 'tcx> {
|
impl<'tcx> At<'_, 'tcx> {
|
||||||
fn structurally_normalize<E: FulfillmentErrorLike<'tcx>>(
|
fn structurally_normalize<E: 'tcx>(
|
||||||
&self,
|
&self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
|
||||||
|
Loading…
Reference in New Issue
Block a user