use self::type_variable::TypeVariableOrigin;
use self::unify_key::ToType;
-mod bivariate;
mod combine;
mod equate;
pub mod error_reporting;
/// region that each late-bound region was replaced with.
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
-/// See `error_reporting.rs` for more details
+/// See `error_reporting` module for more details
#[derive(Clone, Debug)]
pub enum ValuePairs<'tcx> {
Types(ExpectedFound<Ty<'tcx>>),
/// The trace designates the path through inference that we took to
/// encounter an error or subtyping constraint.
///
-/// See `error_reporting.rs` for more details.
+/// See `error_reporting` module for more details.
#[derive(Clone)]
pub struct TypeTrace<'tcx> {
cause: ObligationCause<'tcx>,
/// The origin of a `r1 <= r2` constraint.
///
-/// See `error_reporting.rs` for more details
+/// See `error_reporting` module for more details
#[derive(Clone, Debug)]
pub enum SubregionOrigin<'tcx> {
// Arose from a subtyping relation
/// Reasons to create a region inference variable
///
-/// See `error_reporting.rs` for more details
+/// See `error_reporting` module for more details
#[derive(Clone, Debug)]
pub enum RegionVariableOrigin {
// Region variables created for ill-categorized reasons,
evaluation_cache: traits::EvaluationCache::new(),
projection_cache: RefCell::new(traits::ProjectionCache::new()),
reported_trait_errors: RefCell::new(FxHashSet()),
- projection_mode: Reveal::NotSpecializable,
+ projection_mode: Reveal::UserFacing,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: self.sess.err_count(),
obligations_in_snapshot: Cell::new(false),
}
impl<T> ExpectedFound<T> {
- fn new(a_is_expected: bool, a: T, b: T) -> Self {
+ pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
if a_is_expected {
ExpectedFound {expected: a, found: b}
} else {
Ty<'gcx>,
&'gcx Substs<'gcx>,
ty::FnSig<'gcx>,
- &'gcx ty::BareFnTy<'gcx>,
+ ty::PolyFnSig<'gcx>,
ty::ClosureSubsts<'gcx>,
ty::PolyTraitRef<'gcx>,
ty::ExistentialTraitRef<'gcx>
self.probe(|_| {
let origin = &ObligationCause::dummy();
let trace = TypeTrace::types(origin, true, a, b);
- self.sub(true, trace, &a, &b).map(|InferOk { obligations, .. }| {
- // FIXME(#32730) propagate obligations
- assert!(obligations.is_empty());
+ self.sub(true, trace, &a, &b).map(|InferOk { obligations: _, .. }| {
+ // Ignore obligations, since we are unrolling
+ // everything anyway.
})
})
}
})
}
+ pub fn subtype_predicate(&self,
+ cause: &ObligationCause<'tcx>,
+ predicate: &ty::PolySubtypePredicate<'tcx>)
+ -> Option<InferResult<'tcx, ()>>
+ {
+ // Subtle: it's ok to skip the binder here and resolve because
+ // `shallow_resolve` just ignores anything that is not a type
+ // variable, and because type variable's can't (at present, at
+ // least) capture any of the things bound by this binder.
+ //
+ // Really, there is no *particular* reason to do this
+ // `shallow_resolve` here except as a
+ // micro-optimization. Naturally I could not
+ // resist. -nmatsakis
+ let two_unbound_type_vars = {
+ let a = self.shallow_resolve(predicate.skip_binder().a);
+ let b = self.shallow_resolve(predicate.skip_binder().b);
+ a.is_ty_var() && b.is_ty_var()
+ };
+
+ if two_unbound_type_vars {
+ // Two unbound type variables? Can't make progress.
+ return None;
+ }
+
+ Some(self.commit_if_ok(|snapshot| {
+ let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
+ self.skolemize_late_bound_regions(predicate, snapshot);
+
+ let cause_span = cause.span;
+ let ok = self.sub_types(a_is_expected, cause, a, b)?;
+ self.leak_check(false, cause_span, &skol_map, snapshot)?;
+ self.pop_skolemized(skol_map, snapshot);
+ Ok(ok.unit())
+ }))
+ }
+
pub fn region_outlives_predicate(&self,
cause: &traits::ObligationCause<'tcx>,
predicate: &ty::PolyRegionOutlivesPredicate<'tcx>)
/// as the substitutions for the default, `(T, U)`.
pub fn type_var_for_def(&self,
span: Span,
- def: &ty::TypeParameterDef<'tcx>,
+ def: &ty::TypeParameterDef,
substs: &[Kind<'tcx>])
-> Ty<'tcx> {
- let default = def.default.map(|default| {
- type_variable::Default {
+ let default = if def.has_default {
+ let default = self.tcx.item_type(def.def_id);
+ Some(type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
- def_id: def.default_def_id
- }
- });
+ def_id: def.def_id
+ })
+ } else {
+ None
+ };
let ty_var_id = self.type_variables
// this infcx was in use. This is totally hokey but
// otherwise we have a hard time separating legit region
// errors from silly ones.
- self.report_region_errors(&errors); // see error_reporting.rs
+ self.report_region_errors(&errors); // see error_reporting module
}
}
Some(self.tcx.closure_kind(def_id))
}
- pub fn closure_type(&self,
- def_id: DefId,
- substs: ty::ClosureSubsts<'tcx>)
- -> ty::ClosureTy<'tcx>
- {
+ pub fn closure_type(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> {
if let InferTables::InProgress(tables) = self.tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
- if let Some(ty) = tables.borrow().closure_tys.get(&id) {
- return ty.subst(self.tcx, substs.substs);
+ if let Some(&ty) = tables.borrow().closure_tys.get(&id) {
+ return ty;
}
}
}
- self.tcx.closure_type(def_id, substs)
+ self.tcx.closure_type(def_id)
}
}