mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
ergonomic improvements to the methods in infcx
This commit is contained in:
parent
c1e895d92c
commit
c7a2e32c10
310
src/librustc/infer/at.rs
Normal file
310
src/librustc/infer/at.rs
Normal file
@ -0,0 +1,310 @@
|
||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! A nice interface for working with the infcx. The basic idea is to
|
||||
//! do `infcx.at(cause, param_env)`, which sets the "cause" of the
|
||||
//! operation as well as the surrounding parameter environment. Then
|
||||
//! you can do something like `.sub(a, b)` or `.eq(a, b)` to create a
|
||||
//! subtype or equality relationship respectively. The first argument
|
||||
//! is always the "expected" output from the POV of diagnostics.
|
||||
//!
|
||||
//! Examples:
|
||||
//!
|
||||
//! infcx.at(cause, param_env).sub(a, b)
|
||||
//! // requires that `a <: b`, with `a` considered the "expected" type
|
||||
//!
|
||||
//! infcx.at(cause, param_env).sup(a, b)
|
||||
//! // requires that `b <: a`, with `a` considered the "expected" type
|
||||
//!
|
||||
//! infcx.at(cause, param_env).eq(a, b)
|
||||
//! // requires that `a == b`, with `a` considered the "expected" type
|
||||
//!
|
||||
//! For finer-grained control, you can also do use `trace`:
|
||||
//!
|
||||
//! infcx.at(...).trace(a, b).sub(&c, &d)
|
||||
//!
|
||||
//! This will set `a` and `b` as the "root" values for
|
||||
//! error-reporting, but actually operate on `c` and `d`. This is
|
||||
//! sometimes useful when the types of `c` and `d` are not traceable
|
||||
//! things. (That system should probably be refactored.)
|
||||
|
||||
use super::*;
|
||||
|
||||
use ty::relate::{Relate, TypeRelation};
|
||||
|
||||
pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
cause: &'a ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
pub struct Trace<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
at: At<'a, 'gcx, 'tcx>,
|
||||
a_is_expected: bool,
|
||||
trace: TypeTrace<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn at(&'a self,
|
||||
cause: &'a ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>)
|
||||
-> At<'a, 'gcx, 'tcx>
|
||||
{
|
||||
At { infcx: self, cause, param_env }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToTrace<'tcx>: Relate<'tcx> + Copy {
|
||||
fn to_trace(cause: &ObligationCause<'tcx>,
|
||||
a_is_expected: bool,
|
||||
a: Self,
|
||||
b: Self)
|
||||
-> TypeTrace<'tcx>;
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> At<'a, 'gcx, 'tcx> {
|
||||
/// Hacky routine for equating two impl headers in coherence.
|
||||
pub fn eq_impl_headers(self,
|
||||
expected: &ty::ImplHeader<'tcx>,
|
||||
actual: &ty::ImplHeader<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("eq_impl_header({:?} = {:?})", expected, actual);
|
||||
match (expected.trait_ref, actual.trait_ref) {
|
||||
(Some(a_ref), Some(b_ref)) =>
|
||||
self.eq(a_ref, b_ref),
|
||||
(None, None) =>
|
||||
self.eq(expected.self_ty, actual.self_ty),
|
||||
_ =>
|
||||
bug!("mk_eq_impl_headers given mismatched impl kinds"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Make `a <: b` where `a` may or may not be expected
|
||||
pub fn sub_exp<T>(self,
|
||||
a_is_expected: bool,
|
||||
a: T,
|
||||
b: T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.trace_exp(a_is_expected, a, b).sub(&a, &b)
|
||||
}
|
||||
|
||||
/// Make `actual <: expected`. For example, if type-checking a
|
||||
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
|
||||
/// `sup(i32, x)`, since the "expected" type is the type that
|
||||
/// appears in the signature.
|
||||
pub fn sup<T>(self,
|
||||
expected: T,
|
||||
actual: T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.sub_exp(false, actual, expected)
|
||||
}
|
||||
|
||||
/// Make `expected <: actual`
|
||||
pub fn sub<T>(self,
|
||||
expected: T,
|
||||
actual: T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.sub_exp(true, expected, actual)
|
||||
}
|
||||
|
||||
/// Make `expected <: actual`
|
||||
pub fn eq_exp<T>(self,
|
||||
a_is_expected: bool,
|
||||
a: T,
|
||||
b: T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.trace_exp(a_is_expected, a, b).eq(&a, &b)
|
||||
}
|
||||
|
||||
/// Make `expected <: actual`
|
||||
pub fn eq<T>(self,
|
||||
expected: T,
|
||||
actual: T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.trace(expected, actual).eq(&expected, &actual)
|
||||
}
|
||||
|
||||
/// Compute the least-upper-bound, or mutual supertype, of two
|
||||
/// values. The order of the arguments doesn't matter, but since
|
||||
/// this can result in an error (e.g., if asked to compute LUB of
|
||||
/// u32 and i32), it is meaningful to call one of them the
|
||||
/// "expected type".
|
||||
pub fn lub<T>(self,
|
||||
expected: T,
|
||||
actual: T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.trace(expected, actual).lub(&expected, &actual)
|
||||
}
|
||||
|
||||
/// Compute the greatest-lower-bound, or mutual subtype, of two
|
||||
/// values. As with `lub` order doesn't matter, except for error
|
||||
/// cases.
|
||||
pub fn glb<T>(self,
|
||||
expected: T,
|
||||
actual: T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.trace(expected, actual).glb(&expected, &actual)
|
||||
}
|
||||
|
||||
/// Sets the "trace" values that will be used for
|
||||
/// error-repporting, but doesn't actually perform any operation
|
||||
/// yet (this is useful when you want to set the trace using
|
||||
/// distinct values from those you wish to operate upon).
|
||||
pub fn trace<T>(self,
|
||||
expected: T,
|
||||
actual: T)
|
||||
-> Trace<'a, 'gcx, 'tcx>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
self.trace_exp(true, expected, actual)
|
||||
}
|
||||
|
||||
/// Like `trace`, but the expected value is determined by the
|
||||
/// boolean argument (if true, then the first argument `a` is the
|
||||
/// "expected" value).
|
||||
pub fn trace_exp<T>(self,
|
||||
a_is_expected: bool,
|
||||
a: T,
|
||||
b: T)
|
||||
-> Trace<'a, 'gcx, 'tcx>
|
||||
where T: ToTrace<'tcx>
|
||||
{
|
||||
let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b);
|
||||
Trace { at: self, trace: trace, a_is_expected }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> {
|
||||
/// Make `a <: b` where `a` may or may not be expected (if
|
||||
/// `a_is_expected` is true, then `a` is expected).
|
||||
/// Make `expected <: actual`
|
||||
pub fn sub<T>(self,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
debug!("sub({:?} <: {:?})", a, b);
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env);
|
||||
fields.sub(a_is_expected)
|
||||
.relate(a, b)
|
||||
.map(move |_| InferOk { value: (), obligations: fields.obligations })
|
||||
})
|
||||
}
|
||||
|
||||
/// Make `a == b`; the expectation is set by the call to
|
||||
/// `trace()`.
|
||||
pub fn eq<T>(self,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, ()>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
debug!("eq({:?} == {:?})", a, b);
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env);
|
||||
fields.equate(a_is_expected)
|
||||
.relate(a, b)
|
||||
.map(move |_| InferOk { value: (), obligations: fields.obligations })
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lub<T>(self,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
debug!("lub({:?} \\/ {:?})", a, b);
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env);
|
||||
fields.lub(a_is_expected)
|
||||
.relate(a, b)
|
||||
.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
||||
})
|
||||
}
|
||||
|
||||
pub fn glb<T>(self,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
debug!("glb({:?} /\\ {:?})", a, b);
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env);
|
||||
fields.glb(a_is_expected)
|
||||
.relate(a, b)
|
||||
.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
|
||||
fn to_trace(cause: &ObligationCause<'tcx>,
|
||||
a_is_expected: bool,
|
||||
a: Self,
|
||||
b: Self)
|
||||
-> TypeTrace<'tcx>
|
||||
{
|
||||
TypeTrace {
|
||||
cause: cause.clone(),
|
||||
values: Types(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
|
||||
fn to_trace(cause: &ObligationCause<'tcx>,
|
||||
a_is_expected: bool,
|
||||
a: Self,
|
||||
b: Self)
|
||||
-> TypeTrace<'tcx>
|
||||
{
|
||||
TypeTrace {
|
||||
cause: cause.clone(),
|
||||
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToTrace<'tcx> for ty::PolyTraitRef<'tcx> {
|
||||
fn to_trace(cause: &ObligationCause<'tcx>,
|
||||
a_is_expected: bool,
|
||||
a: Self,
|
||||
b: Self)
|
||||
-> TypeTrace<'tcx>
|
||||
{
|
||||
TypeTrace {
|
||||
cause: cause.clone(),
|
||||
values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ use ty::{TyVid, IntVid, FloatVid};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
use ty::relate::RelateResult;
|
||||
use traits::{self, ObligationCause, PredicateObligations, Reveal};
|
||||
use rustc_data_structures::unify::{self, UnificationTable};
|
||||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
@ -49,6 +49,7 @@ use self::region_inference::{RegionVarBindings, RegionSnapshot};
|
||||
use self::type_variable::TypeVariableOrigin;
|
||||
use self::unify_key::ToType;
|
||||
|
||||
pub mod at;
|
||||
mod combine;
|
||||
mod equate;
|
||||
pub mod error_reporting;
|
||||
@ -802,62 +803,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equate<T>(&'a self,
|
||||
a_is_expected: bool,
|
||||
trace: TypeTrace<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
let mut fields = self.combine_fields(trace, param_env);
|
||||
let result = fields.equate(a_is_expected).relate(a, b);
|
||||
result.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
||||
}
|
||||
|
||||
pub fn sub<T>(&'a self,
|
||||
a_is_expected: bool,
|
||||
trace: TypeTrace<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
let mut fields = self.combine_fields(trace, param_env);
|
||||
let result = fields.sub(a_is_expected).relate(a, b);
|
||||
result.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
||||
}
|
||||
|
||||
pub fn lub<T>(&'a self,
|
||||
a_is_expected: bool,
|
||||
trace: TypeTrace<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
let mut fields = self.combine_fields(trace, param_env);
|
||||
let result = fields.lub(a_is_expected).relate(a, b);
|
||||
result.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
||||
}
|
||||
|
||||
pub fn glb<T>(&'a self,
|
||||
a_is_expected: bool,
|
||||
trace: TypeTrace<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: &T,
|
||||
b: &T)
|
||||
-> InferResult<'tcx, T>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
let mut fields = self.combine_fields(trace, param_env);
|
||||
let result = fields.glb(a_is_expected).relate(a, b);
|
||||
result.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
||||
}
|
||||
|
||||
// Clear the "currently in a snapshot" flag, invoke the closure,
|
||||
// then restore the flag to its original value. This flag is a
|
||||
// debugging measure designed to detect cases where we start a
|
||||
@ -1017,102 +962,35 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.region_vars.add_given(sub, sup);
|
||||
}
|
||||
|
||||
pub fn sub_types(&self,
|
||||
a_is_expected: bool,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("sub_types({:?} <: {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(cause, a_is_expected, a, b);
|
||||
self.sub(a_is_expected, trace, param_env, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn can_sub_types(&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> UnitResult<'tcx>
|
||||
pub fn can_sub<T>(&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: T,
|
||||
b: T)
|
||||
-> UnitResult<'tcx>
|
||||
where T: at::ToTrace<'tcx>
|
||||
{
|
||||
let origin = &ObligationCause::dummy();
|
||||
self.probe(|_| {
|
||||
let origin = &ObligationCause::dummy();
|
||||
let trace = TypeTrace::types(origin, true, a, b);
|
||||
self.sub(true, trace, param_env, &a, &b).map(|InferOk { obligations: _, .. }| {
|
||||
self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| {
|
||||
// Ignore obligations, since we are unrolling
|
||||
// everything anyway.
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_types(&self,
|
||||
a_is_expected: bool,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
pub fn can_eq<T>(&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: T,
|
||||
b: T)
|
||||
-> UnitResult<'tcx>
|
||||
where T: at::ToTrace<'tcx>
|
||||
{
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(cause, a_is_expected, a, b);
|
||||
self.equate(a_is_expected, trace, param_env, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_trait_refs(&self,
|
||||
a_is_expected: bool,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: ty::TraitRef<'tcx>,
|
||||
b: ty::TraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("eq_trait_refs({:?} = {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace {
|
||||
cause: cause.clone(),
|
||||
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
};
|
||||
self.equate(a_is_expected, trace, param_env, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_impl_headers(&self,
|
||||
a_is_expected: bool,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: &ty::ImplHeader<'tcx>,
|
||||
b: &ty::ImplHeader<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("eq_impl_header({:?} = {:?})", a, b);
|
||||
match (a.trait_ref, b.trait_ref) {
|
||||
(Some(a_ref), Some(b_ref)) =>
|
||||
self.eq_trait_refs(a_is_expected, cause, param_env, a_ref, b_ref),
|
||||
(None, None) =>
|
||||
self.eq_types(a_is_expected, cause, param_env, a.self_ty, b.self_ty),
|
||||
_ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_poly_trait_refs(&self,
|
||||
a_is_expected: bool,
|
||||
cause: ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
a: ty::PolyTraitRef<'tcx>,
|
||||
b: ty::PolyTraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("sub_poly_trait_refs({:?} <: {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace {
|
||||
cause: cause,
|
||||
values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
};
|
||||
self.sub(a_is_expected, trace, param_env, &a, &b).map(|ok| ok.unit())
|
||||
let origin = &ObligationCause::dummy();
|
||||
self.probe(|_| {
|
||||
self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| {
|
||||
// Ignore obligations, since we are unrolling
|
||||
// everything anyway.
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -1134,7 +1012,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let (ty::EquatePredicate(a, b), skol_map) =
|
||||
self.skolemize_late_bound_regions(predicate, snapshot);
|
||||
let cause_span = cause.span;
|
||||
let eqty_ok = self.eq_types(false, cause, param_env, a, b)?;
|
||||
let eqty_ok = self.at(cause, param_env).eq(b, a)?;
|
||||
self.leak_check(false, cause_span, &skol_map, snapshot)?;
|
||||
self.pop_skolemized(skol_map, snapshot);
|
||||
Ok(eqty_ok.unit())
|
||||
@ -1172,7 +1050,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.skolemize_late_bound_regions(predicate, snapshot);
|
||||
|
||||
let cause_span = cause.span;
|
||||
let ok = self.sub_types(a_is_expected, cause, param_env, a, b)?;
|
||||
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
|
||||
self.leak_check(false, cause_span, &skol_map, snapshot)?;
|
||||
self.pop_skolemized(skol_map, snapshot);
|
||||
Ok(ok.unit())
|
||||
@ -1606,27 +1484,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.region_vars.verify_generic_bound(origin, kind, a, bound);
|
||||
}
|
||||
|
||||
pub fn can_equate<T>(&self, param_env: ty::ParamEnv<'tcx>, a: &T, b: &T) -> UnitResult<'tcx>
|
||||
where T: Relate<'tcx> + fmt::Debug
|
||||
{
|
||||
debug!("can_equate({:?}, {:?})", a, b);
|
||||
self.probe(|_| {
|
||||
// Gin up a dummy trace, since this won't be committed
|
||||
// anyhow. We should make this typetrace stuff more
|
||||
// generic so we don't have to do anything quite this
|
||||
// terrible.
|
||||
let trace = TypeTrace::dummy(self.tcx);
|
||||
self.equate(true, trace, param_env, a, b).map(|InferOk { obligations: _, .. }| {
|
||||
// We can intentionally ignore obligations here, since
|
||||
// this is part of a simple test for general
|
||||
// "equatability". However, it's not entirely clear
|
||||
// that we *ought* to be, perhaps a better thing would
|
||||
// be to use a mini-fulfillment context or something
|
||||
// like that.
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
|
||||
let ty = self.node_type(id);
|
||||
self.resolve_type_vars_or_error(&ty)
|
||||
|
@ -84,12 +84,9 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
||||
debug!("overlap: b_impl_header={:?}", b_impl_header);
|
||||
|
||||
// Do `a` and `b` unify? If not, no overlap.
|
||||
let obligations = match selcx.infcx().eq_impl_headers(true,
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
&a_impl_header,
|
||||
&b_impl_header) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
let obligations = match selcx.infcx().at(&ObligationCause::dummy(), param_env)
|
||||
.eq_impl_headers(&a_impl_header, &b_impl_header) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
obligations
|
||||
}
|
||||
Err(_) => return None
|
||||
|
@ -184,10 +184,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
obligation.cause.clone(),
|
||||
0
|
||||
);
|
||||
if let Err(error) = self.eq_types(
|
||||
false, &obligation.cause, obligation.param_env,
|
||||
data.ty, normalized.value
|
||||
) {
|
||||
if let Err(error) = self.at(&obligation.cause, obligation.param_env)
|
||||
.eq(normalized.value, data.ty) {
|
||||
values = Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: normalized.value,
|
||||
found: data.ty,
|
||||
@ -269,7 +267,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let impl_self_ty = impl_trait_ref.self_ty();
|
||||
|
||||
if let Ok(..) = self.can_equate(param_env, &trait_self_ty, &impl_self_ty) {
|
||||
if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) {
|
||||
self_match_impls.push(def_id);
|
||||
|
||||
if trait_ref.substs.types().skip(1)
|
||||
|
@ -181,11 +181,8 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>(
|
||||
obligations);
|
||||
|
||||
let infcx = selcx.infcx();
|
||||
match infcx.eq_types(true,
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
normalized_ty,
|
||||
obligation.predicate.ty) {
|
||||
match infcx.at(&obligation.cause, obligation.param_env)
|
||||
.eq(normalized_ty, obligation.predicate.ty) {
|
||||
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
||||
obligations.extend(inferred_obligations);
|
||||
Ok(Some(obligations))
|
||||
@ -840,16 +837,13 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
|
||||
data.to_poly_trait_ref();
|
||||
let obligation_poly_trait_ref =
|
||||
obligation_trait_ref.to_poly_trait_ref();
|
||||
infcx.sub_poly_trait_refs(false,
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
data_poly_trait_ref,
|
||||
obligation_poly_trait_ref)
|
||||
.map(|InferOk { obligations: _, value: () }| {
|
||||
// FIXME(#32730) -- do we need to take obligations
|
||||
// into account in any way? At the moment, no.
|
||||
})
|
||||
.is_ok()
|
||||
infcx.at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation_poly_trait_ref, data_poly_trait_ref)
|
||||
.map(|InferOk { obligations: _, value: () }| {
|
||||
// FIXME(#32730) -- do we need to take obligations
|
||||
// into account in any way? At the moment, no.
|
||||
})
|
||||
.is_ok()
|
||||
});
|
||||
|
||||
debug!("assemble_candidates_from_predicates: candidate={:?} \
|
||||
@ -1110,11 +1104,9 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
|
||||
let data_poly_trait_ref = data.to_poly_trait_ref();
|
||||
let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
|
||||
selcx.infcx().probe(|_| {
|
||||
selcx.infcx().sub_poly_trait_refs(false,
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
data_poly_trait_ref,
|
||||
obligation_poly_trait_ref).is_ok()
|
||||
selcx.infcx().at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation_poly_trait_ref, data_poly_trait_ref)
|
||||
.is_ok()
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -1269,12 +1269,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
-> bool
|
||||
{
|
||||
assert!(!skol_trait_ref.has_escaping_regions());
|
||||
let cause = obligation.cause.clone();
|
||||
match self.infcx.sub_poly_trait_refs(false,
|
||||
cause,
|
||||
obligation.param_env,
|
||||
trait_bound.clone(),
|
||||
ty::Binder(skol_trait_ref.clone())) {
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env)
|
||||
.sup(ty::Binder(skol_trait_ref), trait_bound) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
self.inferred_obligations.extend(obligations);
|
||||
}
|
||||
@ -2436,11 +2432,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
-> Result<(), SelectionError<'tcx>>
|
||||
{
|
||||
let obligation_trait_ref = obligation_trait_ref.clone();
|
||||
self.infcx.sub_poly_trait_refs(false,
|
||||
obligation_cause.clone(),
|
||||
obligation_param_env,
|
||||
expected_trait_ref.clone(),
|
||||
obligation_trait_ref.clone())
|
||||
self.infcx
|
||||
.at(&obligation_cause, obligation_param_env)
|
||||
.sup(obligation_trait_ref, expected_trait_ref)
|
||||
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
||||
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
|
||||
}
|
||||
@ -2475,12 +2469,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
let new_trait = tcx.mk_dynamic(
|
||||
ty::Binder(tcx.mk_existential_predicates(iter)), r_b);
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.eq_types(false,
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
new_trait,
|
||||
target)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.infcx.at(&obligation.cause, obligation.param_env)
|
||||
.eq(target, new_trait)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
|
||||
// Register one obligation for 'a: 'b.
|
||||
@ -2540,8 +2531,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
// [T; n] -> [T].
|
||||
(&ty::TyArray(a, _), &ty::TySlice(b)) => {
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.eq_types(false, &obligation.cause, obligation.param_env, a, b)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.infcx.at(&obligation.cause, obligation.param_env)
|
||||
.eq(b, a)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
}
|
||||
|
||||
@ -2603,12 +2595,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
});
|
||||
let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.eq_types(false,
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
new_struct,
|
||||
target)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.infcx.at(&obligation.cause, obligation.param_env)
|
||||
.eq(target, new_struct)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
|
||||
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
|
||||
@ -2696,15 +2685,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
skol_obligation_trait_ref);
|
||||
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.eq_trait_refs(false,
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
impl_trait_ref.value.clone(),
|
||||
skol_obligation_trait_ref)
|
||||
.map_err(|e| {
|
||||
debug!("match_impl: failed eq_trait_refs due to `{}`", e);
|
||||
()
|
||||
})?;
|
||||
self.infcx.at(&obligation.cause, obligation.param_env)
|
||||
.eq(skol_obligation_trait_ref, impl_trait_ref.value)
|
||||
.map_err(|e| {
|
||||
debug!("match_impl: failed eq_trait_refs due to `{}`", e);
|
||||
()
|
||||
})?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
|
||||
if let Err(e) = self.infcx.leak_check(false,
|
||||
@ -2770,13 +2756,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
obligation,
|
||||
poly_trait_ref);
|
||||
|
||||
self.infcx.sub_poly_trait_refs(false,
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
poly_trait_ref,
|
||||
obligation.predicate.to_poly_trait_ref())
|
||||
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
||||
.map_err(|_| ())
|
||||
self.infcx.at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
|
||||
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
||||
.map_err(|_| ())
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -228,11 +228,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
target_substs);
|
||||
|
||||
// do the impls unify? If not, no specialization.
|
||||
match infcx.eq_trait_refs(true,
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
source_trait_ref,
|
||||
target_trait_ref) {
|
||||
match infcx.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(source_trait_ref, target_trait_ref) {
|
||||
Ok(InferOk { obligations: o, .. }) => {
|
||||
obligations.extend(o);
|
||||
}
|
||||
|
@ -353,18 +353,20 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
infer_ok.value
|
||||
}
|
||||
|
||||
fn sub_types(&mut self, sup: Ty<'tcx>, sub: Ty<'tcx>)
|
||||
fn sub_types(&mut self, sub: Ty<'tcx>, sup: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
{
|
||||
self.infcx.sub_types(false, &self.misc(self.last_span), self.param_env, sup, sub)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
self.infcx.at(&self.misc(self.last_span), self.param_env)
|
||||
.sup(sup, sub)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
}
|
||||
|
||||
fn eq_types(&mut self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
{
|
||||
self.infcx.eq_types(false, &self.misc(span), self.param_env, a, b)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
self.infcx.at(&self.misc(span), self.param_env)
|
||||
.eq(b, a)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
@ -64,7 +64,7 @@ use check::{Diverges, FnCtxt};
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::{Coercion, InferResult, InferOk, TypeTrace};
|
||||
use rustc::infer::{Coercion, InferResult, InferOk};
|
||||
use rustc::infer::type_variable::TypeVariableOrigin;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
|
||||
@ -135,11 +135,13 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
|
||||
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(&self.cause, false, a, b);
|
||||
if self.use_lub {
|
||||
self.lub(false, trace, self.fcx.param_env, &a, &b)
|
||||
self.at(&self.cause, self.fcx.param_env)
|
||||
.lub(b, a)
|
||||
} else {
|
||||
self.sub(false, trace, self.fcx.param_env, &a, &b)
|
||||
self.at(&self.cause, self.fcx.param_env)
|
||||
.sup(b, a)
|
||||
.map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -771,20 +773,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
return Ok(prev_ty);
|
||||
}
|
||||
|
||||
let trace = TypeTrace::types(cause, true, prev_ty, new_ty);
|
||||
|
||||
// Special-case that coercion alone cannot handle:
|
||||
// Two function item types of differing IDs or Substs.
|
||||
match (&prev_ty.sty, &new_ty.sty) {
|
||||
(&ty::TyFnDef(a_def_id, a_substs, a_fty), &ty::TyFnDef(b_def_id, b_substs, b_fty)) => {
|
||||
// The signature must always match.
|
||||
let fty = self.lub(true, trace.clone(), self.param_env, &a_fty, &b_fty)
|
||||
let fty = self.at(cause, self.param_env)
|
||||
.trace(prev_ty, new_ty)
|
||||
.lub(&a_fty, &b_fty)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
||||
|
||||
if a_def_id == b_def_id {
|
||||
// Same function, maybe the parameters match.
|
||||
let substs = self.commit_if_ok(|_| {
|
||||
self.lub(true, trace.clone(), self.param_env, &a_substs, &b_substs)
|
||||
self.at(cause, self.param_env)
|
||||
.trace(prev_ty, new_ty)
|
||||
.lub(&a_substs, &b_substs)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
});
|
||||
|
||||
@ -853,7 +857,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
if !noop {
|
||||
return self.commit_if_ok(|_| {
|
||||
self.lub(true, trace.clone(), self.param_env, &prev_ty, &new_ty)
|
||||
self.at(cause, self.param_env)
|
||||
.lub(prev_ty, new_ty)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
});
|
||||
}
|
||||
@ -866,7 +871,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Err(e)
|
||||
} else {
|
||||
self.commit_if_ok(|_| {
|
||||
self.lub(true, trace, self.param_env, &prev_ty, &new_ty)
|
||||
self.at(cause, self.param_env)
|
||||
.lub(prev_ty, new_ty)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
})
|
||||
}
|
||||
@ -1109,7 +1115,8 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||
// Another example is `break` with no argument expression.
|
||||
assert!(expression_ty.is_nil());
|
||||
assert!(expression_ty.is_nil(), "if let hack without unit type");
|
||||
fcx.eq_types(label_expression_as_expected, cause, fcx.param_env, expression_ty, self.merged_ty())
|
||||
fcx.at(cause, fcx.param_env)
|
||||
.eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
|
||||
.map(|infer_ok| {
|
||||
fcx.register_infer_ok_obligations(infer_ok);
|
||||
expression_ty
|
||||
|
@ -289,7 +289,8 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
|
||||
|
||||
let sub_result = infcx.sub_types(false, &cause, param_env, impl_fty, trait_fty)
|
||||
let sub_result = infcx.at(&cause, param_env)
|
||||
.sup(trait_fty, impl_fty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
inh.register_predicates(obligations);
|
||||
});
|
||||
@ -460,28 +461,23 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
|
||||
impl_iter.zip(trait_iter)
|
||||
.zip(impl_m_iter)
|
||||
.zip(trait_m_iter)
|
||||
.filter_map(|(((impl_arg_ty, trait_arg_ty), impl_arg), trait_arg)| {
|
||||
match infcx.sub_types(true,
|
||||
&cause,
|
||||
param_env,
|
||||
trait_arg_ty,
|
||||
impl_arg_ty) {
|
||||
.filter_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| {
|
||||
match infcx.at(&cause, param_env).sub(trait_arg_ty, impl_arg_ty) {
|
||||
Ok(_) => None,
|
||||
Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
|
||||
}
|
||||
})
|
||||
.next()
|
||||
.unwrap_or_else(|| {
|
||||
if infcx.sub_types(false,
|
||||
&cause,
|
||||
param_env,
|
||||
impl_sig.output(),
|
||||
trait_sig.output())
|
||||
.is_err() {
|
||||
(impl_m_output.span(), Some(trait_m_output.span()))
|
||||
} else {
|
||||
(cause.span, tcx.hir.span_if_local(trait_m.def_id))
|
||||
}
|
||||
if
|
||||
infcx.at(&cause, param_env)
|
||||
.sup(trait_sig.output(), impl_sig.output())
|
||||
.is_err()
|
||||
{
|
||||
(impl_m_output.span(), Some(trait_m_output.span()))
|
||||
} else {
|
||||
(cause.span, tcx.hir.span_if_local(trait_m.def_id))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
(cause.span, tcx.hir.span_if_local(trait_m.def_id))
|
||||
@ -760,8 +756,9 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
debug!("compare_const_impl: trait_ty={:?}", trait_ty);
|
||||
|
||||
let err = infcx.sub_types(false, &cause, param_env, impl_ty, trait_ty)
|
||||
.map(|ok| inh.register_infer_ok_obligations(ok));
|
||||
let err = infcx.at(&cause, param_env)
|
||||
.sup(trait_ty, impl_ty)
|
||||
.map(|ok| inh.register_infer_ok_obligations(ok));
|
||||
|
||||
if let Err(terr) = err {
|
||||
debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
|
||||
|
@ -26,8 +26,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// Requires that the two types unify, and prints an error message if
|
||||
// they don't.
|
||||
pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
|
||||
let cause = self.misc(sp);
|
||||
match self.sub_types(false, &cause, self.param_env, actual, expected) {
|
||||
let cause = &self.misc(sp);
|
||||
match self.at(cause, self.param_env).sup(expected, actual) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
},
|
||||
@ -54,7 +54,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
match self.eq_types(false, cause, self.param_env, actual, expected) {
|
||||
match self.at(cause, self.param_env).eq(expected, actual) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
None
|
||||
|
@ -92,7 +92,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
||||
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs);
|
||||
|
||||
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
|
||||
match infcx.eq_types(true, cause, impl_param_env, named_type, fresh_impl_self_ty) {
|
||||
match infcx.at(cause, impl_param_env).eq(named_type, fresh_impl_self_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
fulfillment_cx.register_predicate_obligations(infcx, obligations);
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn unify_receivers(&mut self, self_ty: Ty<'tcx>, method_self_ty: Ty<'tcx>) {
|
||||
match self.sub_types(false, &self.misc(self.span), self.param_env, self_ty, method_self_ty) {
|
||||
match self.at(&self.misc(self.span), self.param_env).sup(method_self_ty, self_ty) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
}
|
||||
|
@ -679,7 +679,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
let output = fty.output().subst(self.tcx, substs);
|
||||
let (output, _) = self.replace_late_bound_regions_with_fresh_var(
|
||||
self.span, infer::FnCall, &output);
|
||||
self.can_sub_types(self.param_env, output, expected).is_ok()
|
||||
self.can_sub(self.param_env, output, expected).is_ok()
|
||||
})
|
||||
}
|
||||
_ => false,
|
||||
@ -885,7 +885,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
substs,
|
||||
bound);
|
||||
|
||||
if self.can_equate(self.param_env, &step.self_ty, &bound.self_ty()).is_ok() {
|
||||
if self.can_eq(self.param_env, step.self_ty, bound.self_ty()).is_ok() {
|
||||
let xform_self_ty = self.xform_self_ty(&item, bound.self_ty(), bound.substs);
|
||||
|
||||
debug!("assemble_projection_candidates: bound={:?} xform_self_ty={:?}",
|
||||
@ -1143,11 +1143,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
self.probe(|_| {
|
||||
// First check that the self type can be related.
|
||||
let sub_obligations = match self.sub_types(false,
|
||||
&ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
self_ty,
|
||||
probe.xform_self_ty) {
|
||||
let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env)
|
||||
.sup(probe.xform_self_ty, self_ty) {
|
||||
Ok(InferOk { obligations, value: () }) => obligations,
|
||||
Err(_) => {
|
||||
debug!("--> cannot relate self-types");
|
||||
|
@ -2723,7 +2723,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// is polymorphic) and the expected return type.
|
||||
// No argument expectations are produced if unification fails.
|
||||
let origin = self.misc(call_span);
|
||||
let ures = self.sub_types(false, &origin, self.param_env, formal_ret, ret_ty);
|
||||
let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
|
||||
|
||||
// FIXME(#15760) can't use try! here, FromError doesn't default
|
||||
// to identity so the resulting type is not constrained.
|
||||
@ -4218,7 +4218,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
_ => return,
|
||||
};
|
||||
let last_expr_ty = self.expr_ty(last_expr);
|
||||
if self.can_sub_types(self.param_env, last_expr_ty, expected_ty).is_err() {
|
||||
if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
|
||||
return;
|
||||
}
|
||||
let original_span = original_sp(last_stmt.span, blk.span);
|
||||
@ -4478,7 +4478,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let ty = self.tcx.type_of(impl_def_id);
|
||||
|
||||
let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
|
||||
match self.sub_types(false, &self.misc(span), self.param_env, self_ty, impl_ty) {
|
||||
match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
|
||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||
Err(_) => {
|
||||
span_bug!(span,
|
||||
|
@ -1660,7 +1660,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// check whether this predicate applies to our current projection
|
||||
let cause = self.fcx.misc(span);
|
||||
match self.eq_types(false, &cause, self.fcx.param_env, ty, outlives.0) {
|
||||
match self.at(&cause, self.fcx.param_env).eq(outlives.0, ty) {
|
||||
Ok(ok) => {
|
||||
self.register_infer_ok_obligations(ok);
|
||||
Ok(outlives.1)
|
||||
|
@ -308,7 +308,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// we may have to evaluate constraint
|
||||
// expressions in the course of execution.)
|
||||
// See e.g. #41936.
|
||||
if let Ok(ok) = infcx.eq_types(false, &cause, param_env, b, a) {
|
||||
if let Ok(ok) = infcx.at(&cause, param_env).eq(a, b) {
|
||||
if ok.obligations.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
tcx.infer_ctxt(()).enter(|ref infcx| {
|
||||
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
|
||||
let mut fulfill_cx = FulfillmentContext::new();
|
||||
match infcx.eq_types(false, &cause, param_env, expected, actual) {
|
||||
match infcx.at(&cause, param_env).eq(expected, actual) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user