use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
-use hir::def_id::CRATE_DEF_ID;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::undo_log::Rollback;
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
+use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::mir::interpret::EvalToConstValueResult;
use rustc_middle::traits::select;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
/// This is used so that the region values inferred by HIR region solving are
/// not exposed, and so that we can avoid doing work in HIR typeck that MIR
/// typeck will also do.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Default)]
pub enum RegionckMode {
/// The default mode: report region errors, don't erase regions.
+ #[default]
Solve,
/// Erase the results of region after solving.
Erase {
},
}
-impl Default for RegionckMode {
- fn default() -> Self {
- RegionckMode::Solve
- }
-}
-
impl RegionckMode {
/// Indicates that the MIR borrowck will repeat these region
/// checks, so we should ignore errors if NLL is (unconditionally)
/// The `DefId` of the item in whose context we are performing inference or typeck.
/// It is used to check whether an opaque type use is a defining use.
- pub defining_use_anchor: LocalDefId,
+ ///
+ /// If it is `None`, we can't resolve opaque types here and need to bubble up
+ /// the obligation. This frequently happens for
+ /// short lived InferCtxt within queries. The opaque type obligations are forwarded
+ /// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
+ pub defining_use_anchor: Option<LocalDefId>,
/// During type-checking/inference of a body, `in_progress_typeck_results`
/// contains a reference to the typeck results being built up, which are
/// Comparing the signature and requirements of an impl method against
/// the containing trait.
- CompareImplMethodObligation {
- span: Span,
- item_name: Symbol,
- impl_item_def_id: DefId,
- trait_item_def_id: DefId,
- },
+ CompareImplMethodObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId },
/// Comparing the signature and requirements of an impl associated type
/// against the containing trait
- CompareImplTypeObligation {
- span: Span,
- item_name: Symbol,
- impl_item_def_id: DefId,
- trait_item_def_id: DefId,
- },
+ CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId },
}
// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
AddrOfRegion(Span),
/// Regions created as part of an autoref of a method receiver
- Autoref(Span, ty::AssocItem),
+ Autoref(Span),
/// Regions created as part of an automatic coercion
Coercion(Span),
pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
- defining_use_anchor: LocalDefId,
+ defining_use_anchor: Option<LocalDefId>,
}
pub trait TyCtxtInferExt<'tcx> {
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx>;
}
-impl TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
+impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
- InferCtxtBuilder {
- tcx: self,
- defining_use_anchor: CRATE_DEF_ID,
- fresh_typeck_results: None,
- }
+ InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
}
}
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
/// in mir borrowck.
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
- self.defining_use_anchor = defining_use_anchor;
+ self.defining_use_anchor = Some(defining_use_anchor);
self
}
unevaluated: ty::Unevaluated<'tcx>,
span: Option<Span>,
) -> EvalToConstValueResult<'tcx> {
- let mut original_values = OriginalQueryValues::default();
- let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values);
+ let substs = self.resolve_vars_if_possible(unevaluated.substs);
+
+ // Postpone the evaluation of constants whose substs depend on inference
+ // variables
+ if substs.has_infer_types_or_consts() {
+ return Err(ErrorHandled::TooGeneric);
+ }
+
+ let param_env_erased = self.tcx.erase_regions(param_env);
+ let substs_erased = self.tcx.erase_regions(substs);
+
+ let unevaluated = ty::Unevaluated {
+ def: unevaluated.def,
+ substs: substs_erased,
+ promoted: unevaluated.promoted,
+ };
- let (param_env, unevaluated) = canonical.value;
// The return value is the evaluated value which doesn't contain any reference to inference
// variables, thus we don't need to substitute back the original values.
- self.tcx.const_eval_resolve(param_env, unevaluated, span)
+ self.tcx.const_eval_resolve(param_env_erased, unevaluated, span)
}
/// If `typ` is a type variable of some kind, resolve it one level
Const(ConstVid<'tcx>),
}
-impl TyOrConstInferVar<'tcx> {
+impl<'tcx> TyOrConstInferVar<'tcx> {
/// Tries to extract an inference variable from a type or a constant, returns `None`
/// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
where
F: FnOnce() -> Self,
{
- match cause.code {
+ match *cause.code() {
traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) => {
SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
}
traits::ObligationCauseCode::CompareImplMethodObligation {
- item_name,
impl_item_def_id,
trait_item_def_id,
} => SubregionOrigin::CompareImplMethodObligation {
span: cause.span,
- item_name,
impl_item_def_id,
trait_item_def_id,
},
traits::ObligationCauseCode::CompareImplTypeObligation {
- item_name,
impl_item_def_id,
trait_item_def_id,
} => SubregionOrigin::CompareImplTypeObligation {
span: cause.span,
- item_name,
impl_item_def_id,
trait_item_def_id,
},
MiscVariable(a)
| PatternRegion(a)
| AddrOfRegion(a)
- | Autoref(a, _)
+ | Autoref(a)
| Coercion(a)
| EarlyBoundRegion(a, ..)
| LateBoundRegion(a, ..)