Use extension trait derive
This commit is contained in:
parent
3250e95305
commit
9c25823bb4
29 changed files with 121 additions and 974 deletions
|
@ -17,49 +17,8 @@ use std::fmt::Debug;
|
|||
|
||||
pub use rustc_infer::infer::*;
|
||||
|
||||
pub trait InferCtxtExt<'tcx> {
|
||||
fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool;
|
||||
|
||||
fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool;
|
||||
|
||||
/// Check whether a `ty` implements given trait(trait_def_id) without side-effects.
|
||||
///
|
||||
/// The inputs are:
|
||||
///
|
||||
/// - the def-id of the trait
|
||||
/// - the type parameters of the trait, including the self-type
|
||||
/// - the parameter environment
|
||||
///
|
||||
/// Invokes `evaluate_obligation`, so in the event that evaluating
|
||||
/// `Ty: Trait` causes overflow, EvaluatedToErrStackDependent
|
||||
/// (or EvaluatedToAmbigStackDependent) will be returned.
|
||||
fn type_implements_trait(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> traits::EvaluationResult;
|
||||
|
||||
/// Returns `Some` if a type implements a trait shallowly, without side-effects,
|
||||
/// along with any errors that would have been reported upon further obligation
|
||||
/// processing.
|
||||
///
|
||||
/// - If this returns `Some([])`, then the trait holds modulo regions.
|
||||
/// - If this returns `Some([errors..])`, then the trait has an impl for
|
||||
/// the self type, but some nested obligations do not hold.
|
||||
/// - If this returns `None`, no implementation that applies could be found.
|
||||
///
|
||||
/// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
|
||||
/// this will probably only ever return `Some([])` or `None`.
|
||||
fn type_implements_trait_shallow(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
ty: Ty<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<Vec<traits::FulfillmentError<'tcx>>>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
|
||||
|
@ -81,6 +40,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
|
||||
}
|
||||
|
||||
/// Check whether a `ty` implements given trait(trait_def_id) without side-effects.
|
||||
///
|
||||
/// The inputs are:
|
||||
///
|
||||
/// - the def-id of the trait
|
||||
/// - the type parameters of the trait, including the self-type
|
||||
/// - the parameter environment
|
||||
///
|
||||
/// Invokes `evaluate_obligation`, so in the event that evaluating
|
||||
/// `Ty: Trait` causes overflow, EvaluatedToErrStackDependent
|
||||
/// (or EvaluatedToAmbigStackDependent) will be returned.
|
||||
#[instrument(level = "debug", skip(self, params), ret)]
|
||||
fn type_implements_trait(
|
||||
&self,
|
||||
|
@ -99,6 +69,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
|
||||
}
|
||||
|
||||
/// Returns `Some` if a type implements a trait shallowly, without side-effects,
|
||||
/// along with any errors that would have been reported upon further obligation
|
||||
/// processing.
|
||||
///
|
||||
/// - If this returns `Some([])`, then the trait holds modulo regions.
|
||||
/// - If this returns `Some([errors..])`, then the trait has an impl for
|
||||
/// the self type, but some nested obligations do not hold.
|
||||
/// - If this returns `None`, no implementation that applies could be found.
|
||||
///
|
||||
/// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
|
||||
/// this will probably only ever return `Some([])` or `None`.
|
||||
fn type_implements_trait_shallow(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
|
@ -124,19 +105,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait InferCtxtBuilderExt<'tcx> {
|
||||
fn enter_canonical_trait_query<K, R>(
|
||||
self,
|
||||
canonical_key: &Canonical<'tcx, K>,
|
||||
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, 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>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
|
||||
/// The "main method" for a canonicalized trait query. Given the
|
||||
/// canonical key `canonical_key`, this method will create a new
|
||||
/// inference context, instantiate the key, and run your operation
|
||||
|
|
|
@ -3,20 +3,14 @@ use rustc_infer::infer::{InferCtxt, RegionResolutionError};
|
|||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
|
||||
pub trait InferCtxtRegionExt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
|
||||
/// Resolve regions, using the deep normalizer to normalize any type-outlives
|
||||
/// obligations in the process. This is in `rustc_trait_selection` because
|
||||
/// we need to normalize.
|
||||
///
|
||||
/// Prefer this method over `resolve_regions_with_normalize`, unless you are
|
||||
/// doing something specific for normalization.
|
||||
fn resolve_regions(
|
||||
&self,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
) -> Vec<RegionResolutionError<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
|
||||
fn resolve_regions(
|
||||
&self,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
|
|
|
@ -131,22 +131,12 @@ pub enum GenerateProofTree {
|
|||
Never,
|
||||
}
|
||||
|
||||
pub trait InferCtxtEvalExt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
||||
/// Evaluates a goal from **outside** of the trait solver.
|
||||
///
|
||||
/// Using this while inside of the solver is wrong as it uses a new
|
||||
/// search graph which would break cycle detection.
|
||||
fn evaluate_root_goal(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
generate_proof_tree: GenerateProofTree,
|
||||
) -> (
|
||||
Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
|
||||
Option<inspect::GoalEvaluation<'tcx>>,
|
||||
);
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn evaluate_root_goal(
|
||||
&self,
|
||||
|
|
|
@ -17,14 +17,8 @@ use crate::solve::inspect::ProofTreeBuilder;
|
|||
use crate::traits::StructurallyNormalizeExt;
|
||||
use crate::traits::TraitEngineExt;
|
||||
|
||||
pub trait InferCtxtSelectExt<'tcx> {
|
||||
fn select_in_new_trait_solver(
|
||||
&self,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
) -> SelectionResult<'tcx, Selection<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
|
||||
fn select_in_new_trait_solver(
|
||||
&self,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
|
|
|
@ -216,15 +216,8 @@ pub trait ProofTreeVisitor<'tcx> {
|
|||
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy>;
|
||||
}
|
||||
|
||||
pub trait ProofTreeInferCtxtExt<'tcx> {
|
||||
fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
visitor: &mut V,
|
||||
) -> ControlFlow<V::BreakTy>;
|
||||
}
|
||||
|
||||
impl<'tcx> ProofTreeInferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> ProofTreeInferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
|
|
|
@ -61,10 +61,7 @@ enum GoalEvaluationKind {
|
|||
Nested { is_normalizes_to_hack: IsNormalizesToHack },
|
||||
}
|
||||
|
||||
trait CanonicalResponseExt {
|
||||
fn has_no_inference_or_external_constraints(&self) -> bool;
|
||||
}
|
||||
|
||||
#[extension]
|
||||
impl<'tcx> CanonicalResponseExt for Canonical<'tcx, Response<'tcx>> {
|
||||
fn has_no_inference_or_external_constraints(&self) -> bool {
|
||||
self.value.external_constraints.region_constraints.is_empty()
|
||||
|
|
|
@ -27,11 +27,8 @@ use rustc_middle::ty::TypeFoldable;
|
|||
use rustc_middle::ty::Variance;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub trait TraitEngineExt<'tcx> {
|
||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
|
||||
}
|
||||
|
||||
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
|
||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
|
||||
if infcx.next_trait_solver() {
|
||||
Box::new(NextFulfillmentCtxt::new(infcx))
|
||||
|
|
|
@ -11,38 +11,8 @@ use super::ArgKind;
|
|||
|
||||
pub use rustc_infer::traits::error_reporting::*;
|
||||
|
||||
pub trait InferCtxtExt<'tcx> {
|
||||
/// Given some node representing a fn-like thing in the HIR map,
|
||||
/// returns a span and `ArgKind` information that describes the
|
||||
/// arguments it expects. This can be supplied to
|
||||
/// `report_arg_count_mismatch`.
|
||||
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)>;
|
||||
|
||||
/// Reports an error when the number of arguments needed by a
|
||||
/// trait match doesn't match the number that the expression
|
||||
/// provides.
|
||||
fn report_arg_count_mismatch(
|
||||
&self,
|
||||
span: Span,
|
||||
found_span: Option<Span>,
|
||||
expected_args: Vec<ArgKind>,
|
||||
found_args: Vec<ArgKind>,
|
||||
is_closure: bool,
|
||||
closure_pipe_span: Option<Span>,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
|
||||
/// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
|
||||
/// in that order, and returns the generic type corresponding to the
|
||||
/// argument of that trait (corresponding to the closure arguments).
|
||||
fn type_implements_fn_trait(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
polarity: ty::ImplPolarity,
|
||||
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
/// Given some node representing a fn-like thing in the HIR map,
|
||||
/// returns a span and `ArgKind` information that describes the
|
||||
/// arguments it expects. This can be supplied to
|
||||
|
@ -229,6 +199,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
err
|
||||
}
|
||||
|
||||
/// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
|
||||
/// in that order, and returns the generic type corresponding to the
|
||||
/// argument of that trait (corresponding to the closure arguments).
|
||||
fn type_implements_fn_trait(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
|
|
@ -23,24 +23,6 @@ use crate::errors::{
|
|||
|
||||
use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt;
|
||||
|
||||
pub trait TypeErrCtxtExt<'tcx> {
|
||||
/*private*/
|
||||
fn impl_similar_to(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> Option<(DefId, GenericArgsRef<'tcx>)>;
|
||||
|
||||
/*private*/
|
||||
fn describe_enclosure(&self, def_id: LocalDefId) -> Option<&'static str>;
|
||||
|
||||
fn on_unimplemented_note(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> OnUnimplementedNote;
|
||||
}
|
||||
|
||||
/// The symbols which are always allowed in a format string
|
||||
static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
|
||||
kw::SelfUpper,
|
||||
|
@ -56,7 +38,8 @@ static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
|
|||
sym::Trait,
|
||||
];
|
||||
|
||||
impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
fn impl_similar_to(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
|
|
|
@ -106,279 +106,6 @@ impl<'tcx, 'a> CoroutineData<'tcx, 'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// This trait is public to expose the diagnostics methods to clippy.
|
||||
pub trait TypeErrCtxtExt<'tcx> {
|
||||
fn suggest_restricting_param_bound(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
associated_item: Option<(&'static str, Ty<'tcx>)>,
|
||||
body_id: LocalDefId,
|
||||
);
|
||||
|
||||
fn suggest_dereferences(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn get_closure_name(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
err: &mut Diagnostic,
|
||||
msg: Cow<'static, str>,
|
||||
) -> Option<Symbol>;
|
||||
|
||||
fn suggest_fn_call(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn check_for_binding_assigned_block_without_tail_expression(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_add_clone_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn extract_callable_info(
|
||||
&self,
|
||||
body_id: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)>;
|
||||
|
||||
fn suggest_add_reference_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
has_custom_message: bool,
|
||||
) -> bool;
|
||||
|
||||
fn suggest_borrowing_for_object_cast(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
object_ty: Ty<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_remove_reference(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic);
|
||||
|
||||
fn suggest_change_mut(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_semicolon_removal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span>;
|
||||
|
||||
fn suggest_impl_trait(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn point_at_returns_when_relevant(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
);
|
||||
|
||||
fn report_closure_arg_mismatch(
|
||||
&self,
|
||||
span: Span,
|
||||
found_span: Option<Span>,
|
||||
found: ty::PolyTraitRef<'tcx>,
|
||||
expected: ty::PolyTraitRef<'tcx>,
|
||||
cause: &ObligationCauseCode<'tcx>,
|
||||
found_node: Option<Node<'_>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
|
||||
fn note_conflicting_fn_args(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
cause: &ObligationCauseCode<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
);
|
||||
|
||||
fn note_conflicting_closure_bounds(
|
||||
&self,
|
||||
cause: &ObligationCauseCode<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_fully_qualified_path(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
item_def_id: DefId,
|
||||
span: Span,
|
||||
trait_ref: DefId,
|
||||
);
|
||||
|
||||
fn maybe_note_obligation_cause_for_async_await(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn note_obligation_cause_for_async_await(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
interior_or_upvar_span: CoroutineInteriorOrUpvar,
|
||||
is_async: bool,
|
||||
outer_coroutine: Option<DefId>,
|
||||
trait_pred: ty::TraitPredicate<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
next_code: Option<&ObligationCauseCode<'tcx>>,
|
||||
);
|
||||
|
||||
fn note_obligation_cause_code<T>(
|
||||
&self,
|
||||
body_id: LocalDefId,
|
||||
err: &mut Diagnostic,
|
||||
predicate: T,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||
seen_requirements: &mut FxHashSet<DefId>,
|
||||
) where
|
||||
T: ToPredicate<'tcx>;
|
||||
|
||||
/// Suggest to await before try: future? => future.await?
|
||||
fn suggest_await_before_try(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
span: Span,
|
||||
);
|
||||
|
||||
fn suggest_floating_point_literal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_derive(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_dereferencing_index(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_option_method_if_applicable(
|
||||
&self,
|
||||
failed_pred: ty::Predicate<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
expr: &hir::Expr<'_>,
|
||||
);
|
||||
|
||||
fn note_function_argument_obligation(
|
||||
&self,
|
||||
body_id: LocalDefId,
|
||||
err: &mut Diagnostic,
|
||||
arg_hir_id: HirId,
|
||||
parent_code: &ObligationCauseCode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
call_hir_id: HirId,
|
||||
);
|
||||
|
||||
fn look_for_iterator_item_mistakes(
|
||||
&self,
|
||||
assocs_in_this_method: &[Option<(Span, (DefId, Ty<'tcx>))>],
|
||||
typeck_results: &TypeckResults<'tcx>,
|
||||
type_diffs: &[TypeError<'tcx>],
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
path_segment: &hir::PathSegment<'_>,
|
||||
args: &[hir::Expr<'_>],
|
||||
err: &mut Diagnostic,
|
||||
);
|
||||
|
||||
fn point_at_chain(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
typeck_results: &TypeckResults<'tcx>,
|
||||
type_diffs: Vec<TypeError<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
);
|
||||
|
||||
fn probe_assoc_types_at_expr(
|
||||
&self,
|
||||
type_diffs: &[TypeError<'tcx>],
|
||||
span: Span,
|
||||
prev_ty: Ty<'tcx>,
|
||||
body_id: hir::HirId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
|
||||
|
||||
fn suggest_convert_to_slice(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
candidate_impls: &[ImplCandidate<'tcx>],
|
||||
span: Span,
|
||||
);
|
||||
|
||||
fn explain_hrtb_projection(
|
||||
&self,
|
||||
diag: &mut Diagnostic,
|
||||
pred: ty::PolyTraitPredicate<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_desugaring_async_fn_in_trait(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
);
|
||||
}
|
||||
|
||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
|
||||
(
|
||||
generics.tail_span_for_predicate_suggestion(),
|
||||
|
@ -509,7 +236,8 @@ pub fn suggest_restriction<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
fn suggest_restricting_param_bound(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
|
|
|
@ -57,78 +57,8 @@ use super::{
|
|||
|
||||
pub use rustc_infer::traits::error_reporting::*;
|
||||
|
||||
pub trait TypeErrCtxtExt<'tcx> {
|
||||
fn build_overflow_error<T>(
|
||||
&self,
|
||||
predicate: &T,
|
||||
span: Span,
|
||||
suggest_increasing_limit: bool,
|
||||
) -> DiagnosticBuilder<'tcx>
|
||||
where
|
||||
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
|
||||
|
||||
fn report_overflow_error<T>(
|
||||
&self,
|
||||
predicate: &T,
|
||||
span: Span,
|
||||
suggest_increasing_limit: bool,
|
||||
mutate: impl FnOnce(&mut Diagnostic),
|
||||
) -> !
|
||||
where
|
||||
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
|
||||
|
||||
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed;
|
||||
|
||||
fn report_fulfillment_errors(&self, errors: Vec<FulfillmentError<'tcx>>) -> ErrorGuaranteed;
|
||||
|
||||
fn report_overflow_obligation<T>(
|
||||
&self,
|
||||
obligation: &Obligation<'tcx, T>,
|
||||
suggest_increasing_limit: bool,
|
||||
) -> !
|
||||
where
|
||||
T: ToPredicate<'tcx> + Clone;
|
||||
|
||||
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
|
||||
|
||||
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
|
||||
|
||||
/// The `root_obligation` parameter should be the `root_obligation` field
|
||||
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
|
||||
/// then it should be the same as `obligation`.
|
||||
fn report_selection_error(
|
||||
&self,
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
root_obligation: &PredicateObligation<'tcx>,
|
||||
error: &SelectionError<'tcx>,
|
||||
) -> ErrorGuaranteed;
|
||||
|
||||
fn emit_specialized_closure_kind_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Option<ErrorGuaranteed>;
|
||||
|
||||
fn fn_arg_obligation(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed>;
|
||||
|
||||
fn try_conversion_context(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
) -> bool;
|
||||
|
||||
fn report_const_param_not_wf(
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
}
|
||||
|
||||
impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
fn report_fulfillment_errors(
|
||||
&self,
|
||||
mut errors: Vec<FulfillmentError<'tcx>>,
|
||||
|
@ -382,6 +312,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.emit()
|
||||
}
|
||||
|
||||
/// The `root_obligation` parameter should be the `root_obligation` field
|
||||
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
|
||||
/// then it should be the same as `obligation`.
|
||||
fn report_selection_error(
|
||||
&self,
|
||||
mut obligation: PredicateObligation<'tcx>,
|
||||
|
@ -1393,209 +1326,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) trait InferCtxtPrivExt<'tcx> {
|
||||
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
|
||||
// `error` occurring implies that `cond` occurs.
|
||||
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool;
|
||||
|
||||
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed;
|
||||
|
||||
fn report_projection_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
error: &MismatchedProjectionTypes<'tcx>,
|
||||
) -> ErrorGuaranteed;
|
||||
|
||||
fn maybe_detailed_projection_msg(
|
||||
&self,
|
||||
pred: ty::ProjectionPredicate<'tcx>,
|
||||
normalized_ty: ty::Term<'tcx>,
|
||||
expected_ty: ty::Term<'tcx>,
|
||||
) -> Option<String>;
|
||||
|
||||
fn fuzzy_match_tys(
|
||||
&self,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
ignoring_lifetimes: bool,
|
||||
) -> Option<CandidateSimilarity>;
|
||||
|
||||
fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str;
|
||||
|
||||
fn find_similar_impl_candidates(
|
||||
&self,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> Vec<ImplCandidate<'tcx>>;
|
||||
|
||||
fn report_similar_impl_candidates(
|
||||
&self,
|
||||
impl_candidates: &[ImplCandidate<'tcx>],
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
body_def_id: LocalDefId,
|
||||
err: &mut Diagnostic,
|
||||
other: bool,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn report_similar_impl_candidates_for_root_obligation(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
|
||||
body_def_id: LocalDefId,
|
||||
err: &mut Diagnostic,
|
||||
);
|
||||
|
||||
/// Gets the parent trait chain start
|
||||
fn get_parent_trait_ref(
|
||||
&self,
|
||||
code: &ObligationCauseCode<'tcx>,
|
||||
) -> Option<(Ty<'tcx>, Option<Span>)>;
|
||||
|
||||
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
|
||||
/// with the same path as `trait_ref`, a help message about
|
||||
/// a probable version mismatch is added to `err`
|
||||
fn note_version_mismatch(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
/// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
|
||||
/// `trait_ref`.
|
||||
///
|
||||
/// For this to work, `new_self_ty` must have no escaping bound variables.
|
||||
fn mk_trait_obligation_with_new_self_ty(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
||||
) -> PredicateObligation<'tcx>;
|
||||
|
||||
fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed;
|
||||
|
||||
fn predicate_can_apply(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>);
|
||||
|
||||
fn suggest_unsized_bound_if_applicable(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
);
|
||||
|
||||
fn annotate_source_of_ambiguity(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
impls: &[ambiguity::Ambiguity],
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
);
|
||||
|
||||
fn maybe_suggest_unsized_generics(&self, err: &mut Diagnostic, span: Span, node: Node<'tcx>);
|
||||
|
||||
fn maybe_indirection_for_unsized(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
item: &'tcx Item<'tcx>,
|
||||
param: &'tcx GenericParam<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn is_recursive_obligation(
|
||||
&self,
|
||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn get_standard_error_message(
|
||||
&self,
|
||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
||||
message: Option<String>,
|
||||
predicate_is_const: bool,
|
||||
append_const_msg: Option<AppendConstMessage>,
|
||||
post_message: String,
|
||||
) -> String;
|
||||
|
||||
fn get_safe_transmute_error_and_reason(
|
||||
&self,
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
span: Span,
|
||||
) -> GetSafeTransmuteErrorAndReason;
|
||||
|
||||
fn add_tuple_trait_message(
|
||||
&self,
|
||||
obligation_cause_code: &ObligationCauseCode<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
);
|
||||
|
||||
fn try_to_add_help_message(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
is_fn_trait: bool,
|
||||
suggested: bool,
|
||||
unsatisfied_const: bool,
|
||||
);
|
||||
|
||||
fn add_help_message_for_fn_trait(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
implemented_kind: ty::ClosureKind,
|
||||
params: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
);
|
||||
|
||||
fn maybe_add_note_for_unsatisfied_const(
|
||||
&self,
|
||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
) -> UnsatisfiedConst;
|
||||
|
||||
fn report_closure_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
found_kind: ty::ClosureKind,
|
||||
kind: ty::ClosureKind,
|
||||
trait_prefix: &'static str,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
|
||||
fn report_cyclic_signature_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
terr: TypeError<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
|
||||
fn report_opaque_type_auto_trait_leakage(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
|
||||
fn report_signature_mismatch_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
span: Span,
|
||||
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
|
||||
|
||||
fn report_not_const_evaluatable_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
#[extension]
|
||||
pub(super) impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
|
||||
// `error` occurring implies that `cond` occurs.
|
||||
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
|
||||
|
@ -2414,6 +2146,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
suggested
|
||||
}
|
||||
|
||||
/// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
|
||||
/// `trait_ref`.
|
||||
///
|
||||
/// For this to work, `new_self_ty` must have no escaping bound variables.
|
||||
fn mk_trait_obligation_with_new_self_ty(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
|
|
@ -11,25 +11,6 @@ pub use rustc_middle::traits::query::OutlivesBound;
|
|||
|
||||
pub type BoundsCompat<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
|
||||
pub type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
|
||||
pub trait InferCtxtExt<'a, 'tcx> {
|
||||
/// Do *NOT* call this directly.
|
||||
fn implied_bounds_tys_compat(
|
||||
&'a self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body_id: LocalDefId,
|
||||
tys: &'a FxIndexSet<Ty<'tcx>>,
|
||||
compat: bool,
|
||||
) -> BoundsCompat<'a, 'tcx>;
|
||||
|
||||
/// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat`
|
||||
/// with `compat` set to `true`, otherwise `false`.
|
||||
fn implied_bounds_tys(
|
||||
&'a self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body_id: LocalDefId,
|
||||
tys: &'a FxIndexSet<Ty<'tcx>>,
|
||||
) -> Bounds<'a, 'tcx>;
|
||||
}
|
||||
|
||||
/// Implied bounds are region relationships that we deduce
|
||||
/// automatically. The idea is that (e.g.) a caller must check that a
|
||||
|
@ -130,7 +111,9 @@ fn implied_outlives_bounds<'a, 'tcx>(
|
|||
bounds
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
|
||||
/// Do *NOT* call this directly.
|
||||
fn implied_bounds_tys_compat(
|
||||
&'a self,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
|
@ -142,6 +125,8 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
|
|||
.flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, *ty, compat))
|
||||
}
|
||||
|
||||
/// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat`
|
||||
/// with `compat` set to `true`, otherwise `false`.
|
||||
fn implied_bounds_tys(
|
||||
&'a self,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
|
|
|
@ -52,12 +52,22 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
|
|||
|
||||
pub(super) struct InProgress;
|
||||
|
||||
pub trait NormalizeExt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
|
||||
/// Normalize a value using the `AssocTypeNormalizer`.
|
||||
///
|
||||
/// This normalization should be used when the type contains inference variables or the
|
||||
/// projection may be fallible.
|
||||
fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
|
||||
fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
|
||||
if self.infcx.next_trait_solver() {
|
||||
InferOk { value, obligations: Vec::new() }
|
||||
} else {
|
||||
let mut selcx = SelectionContext::new(self.infcx);
|
||||
let Normalized { value, obligations } =
|
||||
normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
|
||||
InferOk { value, obligations }
|
||||
}
|
||||
}
|
||||
|
||||
/// Deeply normalizes `value`, replacing all aliases which can by normalized in
|
||||
/// the current environment. In the new solver this errors in case normalization
|
||||
|
@ -73,25 +83,6 @@ pub trait NormalizeExt<'tcx> {
|
|||
/// 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
|
||||
/// rename this function to `At::fully_normalize`.
|
||||
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
value: T,
|
||||
fulfill_cx: &mut dyn TraitEngine<'tcx>,
|
||||
) -> Result<T, Vec<FulfillmentError<'tcx>>>;
|
||||
}
|
||||
|
||||
impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
|
||||
fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
|
||||
if self.infcx.next_trait_solver() {
|
||||
InferOk { value, obligations: Vec::new() }
|
||||
} else {
|
||||
let mut selcx = SelectionContext::new(self.infcx);
|
||||
let Normalized { value, obligations } =
|
||||
normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
|
||||
InferOk { value, obligations }
|
||||
}
|
||||
}
|
||||
|
||||
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
value: T,
|
||||
|
|
|
@ -4,32 +4,8 @@ use crate::infer::canonical::OriginalQueryValues;
|
|||
use crate::infer::InferCtxt;
|
||||
use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
|
||||
|
||||
pub trait InferCtxtExt<'tcx> {
|
||||
fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool;
|
||||
|
||||
fn predicate_must_hold_considering_regions(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'tcx>) -> bool;
|
||||
|
||||
fn evaluate_obligation(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError>;
|
||||
|
||||
// Helper function that canonicalizes and runs the query. If an
|
||||
// overflow results, we re-run it in the local context so we can
|
||||
// report a nice error.
|
||||
/*crate*/
|
||||
fn evaluate_obligation_no_overflow(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> EvaluationResult;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
/// Evaluates whether the predicate can be satisfied (by any means)
|
||||
/// in the given `ParamEnv`.
|
||||
fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool {
|
||||
|
@ -114,9 +90,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Helper function that canonicalizes and runs the query. If an
|
||||
// overflow results, we re-run it in the local context so we can
|
||||
// report a nice error.
|
||||
/// Helper function that canonicalizes and runs the query. If an
|
||||
/// overflow results, we re-run it in the local context so we can
|
||||
/// report a nice error.
|
||||
fn evaluate_obligation_no_overflow(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
|
|
|
@ -22,20 +22,8 @@ use super::NoSolution;
|
|||
|
||||
pub use rustc_middle::traits::query::NormalizationResult;
|
||||
|
||||
pub trait QueryNormalizeExt<'tcx> {
|
||||
/// Normalize a value using the `QueryNormalizer`.
|
||||
///
|
||||
/// This normalization should *only* be used when the projection does not
|
||||
/// have possible ambiguity or may not be well-formed.
|
||||
///
|
||||
/// After codegen, when lifetimes do not matter, it is preferable to instead
|
||||
/// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
|
||||
fn query_normalize<T>(self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
|
||||
#[extension]
|
||||
pub impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
|
||||
/// Normalize `value` in the context of the inference context,
|
||||
/// yielding a resulting type, or an error if `value` cannot be
|
||||
/// normalized. If you don't care about regions, you should prefer
|
||||
|
|
|
@ -33,19 +33,7 @@ enum Inserted<'tcx> {
|
|||
ShouldRecurseOn(DefId),
|
||||
}
|
||||
|
||||
trait ChildrenExt<'tcx> {
|
||||
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId);
|
||||
fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId);
|
||||
|
||||
fn insert(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
simplified_self: Option<SimplifiedType>,
|
||||
overlap_mode: OverlapMode,
|
||||
) -> Result<Inserted<'tcx>, OverlapError<'tcx>>;
|
||||
}
|
||||
|
||||
#[extension]
|
||||
impl<'tcx> ChildrenExt<'tcx> for Children {
|
||||
/// Insert an impl into this set of children without comparing to any existing impls.
|
||||
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
|
||||
|
@ -247,22 +235,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub trait GraphExt<'tcx> {
|
||||
/// Insert a local impl into the specialization graph. If an existing impl
|
||||
/// conflicts with it (has overlap, but neither specializes the other),
|
||||
/// information about the area of overlap is returned in the `Err`.
|
||||
fn insert(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
overlap_mode: OverlapMode,
|
||||
) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>>;
|
||||
|
||||
/// Insert cached metadata mapping from a child impl back to its parent.
|
||||
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId);
|
||||
}
|
||||
|
||||
impl<'tcx> GraphExt<'tcx> for Graph {
|
||||
#[extension]
|
||||
pub impl<'tcx> GraphExt<'tcx> for Graph {
|
||||
/// Insert a local impl into the specialization graph. If an existing impl
|
||||
/// conflicts with it (has overlap, but neither specializes the other),
|
||||
/// information about the area of overlap is returned in the `Err`.
|
||||
|
|
|
@ -5,15 +5,8 @@ use rustc_middle::ty::{self, Ty};
|
|||
|
||||
use crate::traits::{NormalizeExt, Obligation};
|
||||
|
||||
pub trait StructurallyNormalizeExt<'tcx> {
|
||||
fn structurally_normalize(
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
fulfill_cx: &mut dyn TraitEngine<'tcx>,
|
||||
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>>;
|
||||
}
|
||||
|
||||
impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
|
||||
#[extension]
|
||||
pub impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
|
||||
fn structurally_normalize(
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue