remove TypeOrigin and use ObligationCause instead
In general having all these different structs for "origins" is not great, since equating types can cause obligations and vice-versa. I think we should gradually collapse these things. We almost certainly also need to invest a big more energy into the `error_reporting` code to rationalize it: this PR does kind of the minimal effort in that direction.
This commit is contained in:
parent
43006fcea0
commit
19c1a47713
28 changed files with 389 additions and 354 deletions
|
|
@ -274,7 +274,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
|
|||
{
|
||||
let mut generalize = Generalizer {
|
||||
infcx: self.infcx,
|
||||
span: self.trace.origin.span(),
|
||||
span: self.trace.cause.span,
|
||||
for_vid: for_vid,
|
||||
make_region_vars: make_region_vars,
|
||||
cycle_detected: false
|
||||
|
|
|
|||
|
|
@ -80,8 +80,9 @@ use hir::print as pprust;
|
|||
use lint;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use infer::{self, TypeOrigin};
|
||||
use infer;
|
||||
use middle::region;
|
||||
use traits::{ObligationCause, ObligationCauseCode};
|
||||
use ty::{self, TyCtxt, TypeFoldable};
|
||||
use ty::{Region, ReFree};
|
||||
use ty::error::TypeError;
|
||||
|
|
@ -524,10 +525,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn note_error_origin(&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
origin: &TypeOrigin)
|
||||
cause: &ObligationCause<'tcx>)
|
||||
{
|
||||
match origin {
|
||||
&TypeOrigin::MatchExpressionArm(_, arm_span, source) => match source {
|
||||
match cause.code {
|
||||
ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source {
|
||||
hir::MatchSource::IfLetDesugar {..} => {
|
||||
err.span_note(arm_span, "`if let` arm with an incompatible type");
|
||||
}
|
||||
|
|
@ -541,7 +542,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
pub fn note_type_err(&self,
|
||||
diag: &mut DiagnosticBuilder<'tcx>,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
secondary_span: Option<(Span, String)>,
|
||||
values: Option<ValuePairs<'tcx>>,
|
||||
terr: &TypeError<'tcx>)
|
||||
|
|
@ -558,7 +559,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
let span = origin.span();
|
||||
let span = cause.span;
|
||||
|
||||
if let Some((expected, found)) = expected_found {
|
||||
let is_simple_error = if let &TypeError::Sorts(ref values) = terr {
|
||||
|
|
@ -588,7 +589,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
diag.span_label(sp, &msg);
|
||||
}
|
||||
|
||||
self.note_error_origin(diag, &origin);
|
||||
self.note_error_origin(diag, &cause);
|
||||
self.check_and_note_conflicting_crates(diag, terr, span);
|
||||
self.tcx.note_and_explain_type_err(diag, terr, span);
|
||||
}
|
||||
|
|
@ -598,17 +599,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
terr: &TypeError<'tcx>)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
let span = trace.origin.span();
|
||||
let failure_str = trace.origin.as_failure_str();
|
||||
let mut diag = match trace.origin {
|
||||
TypeOrigin::IfExpressionWithNoElse(_) => {
|
||||
let span = trace.cause.span;
|
||||
let failure_str = trace.cause.as_failure_str();
|
||||
let mut diag = match trace.cause.code {
|
||||
ObligationCauseCode::IfExpressionWithNoElse => {
|
||||
struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str)
|
||||
},
|
||||
_ => {
|
||||
struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str)
|
||||
},
|
||||
};
|
||||
self.note_type_err(&mut diag, trace.origin, None, Some(trace.values), terr);
|
||||
self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr);
|
||||
diag
|
||||
}
|
||||
|
||||
|
|
@ -1695,18 +1696,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
if let Some((expected, found)) = self.values_str(&trace.values) {
|
||||
// FIXME: do we want a "the" here?
|
||||
err.span_note(
|
||||
trace.origin.span(),
|
||||
trace.cause.span,
|
||||
&format!("...so that {} (expected {}, found {})",
|
||||
trace.origin.as_requirement_str(), expected, found));
|
||||
trace.cause.as_requirement_str(), expected, found));
|
||||
} else {
|
||||
// FIXME: this really should be handled at some earlier stage. Our
|
||||
// handling of region checking when type errors are present is
|
||||
// *terrible*.
|
||||
|
||||
err.span_note(
|
||||
trace.origin.span(),
|
||||
trace.cause.span,
|
||||
&format!("...so that {}",
|
||||
trace.origin.as_requirement_str()));
|
||||
trace.cause.as_requirement_str()));
|
||||
}
|
||||
}
|
||||
infer::Reborrow(span) => {
|
||||
|
|
@ -1961,3 +1962,45 @@ fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime {
|
|||
span: syntax_pos::DUMMY_SP,
|
||||
name: name }
|
||||
}
|
||||
|
||||
impl<'tcx> ObligationCause<'tcx> {
|
||||
fn as_failure_str(&self) -> &'static str {
|
||||
use traits::ObligationCauseCode::*;
|
||||
match self.code {
|
||||
CompareImplMethodObligation { .. } => "method not compatible with trait",
|
||||
MatchExpressionArm { source, .. } => match source {
|
||||
hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
|
||||
_ => "match arms have incompatible types",
|
||||
},
|
||||
IfExpression => "if and else have incompatible types",
|
||||
IfExpressionWithNoElse => "if may be missing an else clause",
|
||||
EquatePredicate => "equality predicate not satisfied",
|
||||
MainFunctionType => "main function has wrong type",
|
||||
StartFunctionType => "start function has wrong type",
|
||||
IntrinsicType => "intrinsic has wrong type",
|
||||
MethodReceiver => "mismatched method receiver",
|
||||
_ => "mismatched types",
|
||||
}
|
||||
}
|
||||
|
||||
fn as_requirement_str(&self) -> &'static str {
|
||||
use traits::ObligationCauseCode::*;
|
||||
match self.code {
|
||||
CompareImplMethodObligation { .. } => "method type is compatible with trait",
|
||||
ExprAssignable => "expression is assignable",
|
||||
MatchExpressionArm { source, .. } => match source {
|
||||
hir::MatchSource::IfLetDesugar{..} => "`if let` arms have compatible types",
|
||||
_ => "match arms have compatible types",
|
||||
},
|
||||
IfExpression => "if and else have compatible types",
|
||||
IfExpressionWithNoElse => "if missing an else returns ()",
|
||||
EquatePredicate => "equality where clause is satisfied",
|
||||
MainFunctionType => "`main` function has the correct type",
|
||||
StartFunctionType => "`start` function has the correct type",
|
||||
IntrinsicType => "intrinsic has the correct type",
|
||||
MethodReceiver => "method receiver has the correct type",
|
||||
_ => "types are compatible",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
// Start a snapshot so we can examine "all bindings that were
|
||||
// created as part of this type comparison".
|
||||
return self.infcx.commit_if_ok(|snapshot| {
|
||||
let span = self.trace.origin.span();
|
||||
let span = self.trace.cause.span;
|
||||
|
||||
// First, we instantiate each bound region in the subtype with a fresh
|
||||
// region variable.
|
||||
|
|
@ -230,7 +230,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
// created as part of this type comparison".
|
||||
return self.infcx.commit_if_ok(|snapshot| {
|
||||
// Instantiate each bound region with a fresh region variable.
|
||||
let span = self.trace.origin.span();
|
||||
let span = self.trace.cause.span;
|
||||
let (a_with_fresh, a_map) =
|
||||
self.infcx.replace_late_bound_regions_with_fresh_var(
|
||||
span, HigherRankedType, a);
|
||||
|
|
@ -247,7 +247,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
|
||||
// Generalize the regions appearing in result0 if possible
|
||||
let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
|
||||
let span = self.trace.origin.span();
|
||||
let span = self.trace.cause.span;
|
||||
let result1 =
|
||||
fold_regions_in(
|
||||
self.tcx(),
|
||||
|
|
@ -325,10 +325,10 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
// Instantiate each bound region with a fresh region variable.
|
||||
let (a_with_fresh, a_map) =
|
||||
self.infcx.replace_late_bound_regions_with_fresh_var(
|
||||
self.trace.origin.span(), HigherRankedType, a);
|
||||
self.trace.cause.span, HigherRankedType, a);
|
||||
let (b_with_fresh, b_map) =
|
||||
self.infcx.replace_late_bound_regions_with_fresh_var(
|
||||
self.trace.origin.span(), HigherRankedType, b);
|
||||
self.trace.cause.span, HigherRankedType, b);
|
||||
let a_vars = var_ids(self, &a_map);
|
||||
let b_vars = var_ids(self, &b_map);
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
|
||||
// Generalize the regions appearing in result0 if possible
|
||||
let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
|
||||
let span = self.trace.origin.span();
|
||||
let span = self.trace.cause.span;
|
||||
let result1 =
|
||||
fold_regions_in(
|
||||
self.tcx(),
|
||||
|
|
@ -463,7 +463,7 @@ fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
|
|||
ty::ReVar(r) => { r }
|
||||
_ => {
|
||||
span_bug!(
|
||||
fields.trace.origin.span(),
|
||||
fields.trace.cause.span,
|
||||
"found non-region-vid: {:?}",
|
||||
r);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ use ty::{self, Ty, TyCtxt};
|
|||
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
use traits::{self, PredicateObligations, Reveal};
|
||||
use traits::{self, ObligationCause, PredicateObligations, Reveal};
|
||||
use rustc_data_structures::unify::{self, UnificationTable};
|
||||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
use std::fmt;
|
||||
|
|
@ -173,89 +173,6 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||
/// region that each late-bound region was replaced with.
|
||||
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
|
||||
|
||||
/// Why did we require that the two types be related?
|
||||
///
|
||||
/// See `error_reporting.rs` for more details
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum TypeOrigin {
|
||||
// Not yet categorized in a better way
|
||||
Misc(Span),
|
||||
|
||||
// Checking that method of impl is compatible with trait
|
||||
MethodCompatCheck(Span),
|
||||
|
||||
// Checking that this expression can be assigned where it needs to be
|
||||
ExprAssignable(Span),
|
||||
|
||||
// Relating trait type parameters to those found in impl etc
|
||||
RelateOutputImplTypes(Span),
|
||||
|
||||
// Computing common supertype in the arms of a match expression
|
||||
MatchExpressionArm(Span, Span, hir::MatchSource),
|
||||
|
||||
// Computing common supertype in an if expression
|
||||
IfExpression(Span),
|
||||
|
||||
// Computing common supertype of an if expression with no else counter-part
|
||||
IfExpressionWithNoElse(Span),
|
||||
|
||||
// `where a == b`
|
||||
EquatePredicate(Span),
|
||||
|
||||
// `main` has wrong type
|
||||
MainFunctionType(Span),
|
||||
|
||||
// `start` has wrong type
|
||||
StartFunctionType(Span),
|
||||
|
||||
// intrinsic has wrong type
|
||||
IntrinsicType(Span),
|
||||
|
||||
// method receiver
|
||||
MethodReceiver(Span),
|
||||
}
|
||||
|
||||
impl TypeOrigin {
|
||||
fn as_failure_str(&self) -> &'static str {
|
||||
match self {
|
||||
&TypeOrigin::Misc(_) |
|
||||
&TypeOrigin::RelateOutputImplTypes(_) |
|
||||
&TypeOrigin::ExprAssignable(_) => "mismatched types",
|
||||
&TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
|
||||
&TypeOrigin::MatchExpressionArm(.., source) => match source {
|
||||
hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
|
||||
_ => "match arms have incompatible types",
|
||||
},
|
||||
&TypeOrigin::IfExpression(_) => "if and else have incompatible types",
|
||||
&TypeOrigin::IfExpressionWithNoElse(_) => "if may be missing an else clause",
|
||||
&TypeOrigin::EquatePredicate(_) => "equality predicate not satisfied",
|
||||
&TypeOrigin::MainFunctionType(_) => "main function has wrong type",
|
||||
&TypeOrigin::StartFunctionType(_) => "start function has wrong type",
|
||||
&TypeOrigin::IntrinsicType(_) => "intrinsic has wrong type",
|
||||
&TypeOrigin::MethodReceiver(_) => "mismatched method receiver",
|
||||
}
|
||||
}
|
||||
|
||||
fn as_requirement_str(&self) -> &'static str {
|
||||
match self {
|
||||
&TypeOrigin::Misc(_) => "types are compatible",
|
||||
&TypeOrigin::MethodCompatCheck(_) => "method type is compatible with trait",
|
||||
&TypeOrigin::ExprAssignable(_) => "expression is assignable",
|
||||
&TypeOrigin::RelateOutputImplTypes(_) => {
|
||||
"trait type parameters matches those specified on the impl"
|
||||
}
|
||||
&TypeOrigin::MatchExpressionArm(..) => "match arms have compatible types",
|
||||
&TypeOrigin::IfExpression(_) => "if and else have compatible types",
|
||||
&TypeOrigin::IfExpressionWithNoElse(_) => "if missing an else returns ()",
|
||||
&TypeOrigin::EquatePredicate(_) => "equality where clause is satisfied",
|
||||
&TypeOrigin::MainFunctionType(_) => "`main` function has the correct type",
|
||||
&TypeOrigin::StartFunctionType(_) => "`start` function has the correct type",
|
||||
&TypeOrigin::IntrinsicType(_) => "intrinsic has the correct type",
|
||||
&TypeOrigin::MethodReceiver(_) => "method receiver has the correct type",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See `error_reporting.rs` for more details
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ValuePairs<'tcx> {
|
||||
|
|
@ -270,7 +187,7 @@ pub enum ValuePairs<'tcx> {
|
|||
/// See `error_reporting.rs` for more details.
|
||||
#[derive(Clone)]
|
||||
pub struct TypeTrace<'tcx> {
|
||||
origin: TypeOrigin,
|
||||
cause: ObligationCause<'tcx>,
|
||||
values: ValuePairs<'tcx>,
|
||||
}
|
||||
|
||||
|
|
@ -1006,14 +923,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
pub fn sub_types(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("sub_types({:?} <: {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(origin, a_is_expected, a, b);
|
||||
let trace = TypeTrace::types(cause, a_is_expected, a, b);
|
||||
self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
|
@ -1024,7 +941,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
-> UnitResult<'tcx>
|
||||
{
|
||||
self.probe(|_| {
|
||||
let origin = TypeOrigin::Misc(syntax_pos::DUMMY_SP);
|
||||
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
|
||||
|
|
@ -1035,20 +952,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
pub fn eq_types(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(origin, a_is_expected, a, b);
|
||||
let trace = TypeTrace::types(cause, a_is_expected, a, b);
|
||||
self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_trait_refs(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
a: ty::TraitRef<'tcx>,
|
||||
b: ty::TraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
|
|
@ -1056,7 +973,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
debug!("eq_trait_refs({:?} = {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace {
|
||||
origin: origin,
|
||||
cause: cause.clone(),
|
||||
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
};
|
||||
self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
|
||||
|
|
@ -1065,22 +982,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
pub fn eq_impl_headers(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'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, origin, a_ref, b_ref),
|
||||
(None, None) => self.eq_types(a_is_expected, origin, a.self_ty, b.self_ty),
|
||||
(Some(a_ref), Some(b_ref)) => self.eq_trait_refs(a_is_expected, cause, a_ref, b_ref),
|
||||
(None, None) => self.eq_types(a_is_expected, cause, 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,
|
||||
origin: TypeOrigin,
|
||||
cause: ObligationCause<'tcx>,
|
||||
a: ty::PolyTraitRef<'tcx>,
|
||||
b: ty::PolyTraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
|
|
@ -1088,7 +1005,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
debug!("sub_poly_trait_refs({:?} <: {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace {
|
||||
origin: origin,
|
||||
cause: cause,
|
||||
values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
};
|
||||
self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
|
||||
|
|
@ -1104,16 +1021,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn equality_predicate(&self,
|
||||
span: Span,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
predicate: &ty::PolyEquatePredicate<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
self.commit_if_ok(|snapshot| {
|
||||
let (ty::EquatePredicate(a, b), skol_map) =
|
||||
self.skolemize_late_bound_regions(predicate, snapshot);
|
||||
let origin = TypeOrigin::EquatePredicate(span);
|
||||
let eqty_ok = self.eq_types(false, origin, a, b)?;
|
||||
self.leak_check(false, span, &skol_map, snapshot)?;
|
||||
let cause_span = cause.span;
|
||||
let eqty_ok = self.eq_types(false, cause, a, b)?;
|
||||
self.leak_check(false, cause_span, &skol_map, snapshot)?;
|
||||
self.pop_skolemized(skol_map, snapshot);
|
||||
Ok(eqty_ok.unit())
|
||||
})
|
||||
|
|
@ -1443,26 +1360,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn report_mismatched_types(&self,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
err: TypeError<'tcx>) {
|
||||
let trace = TypeTrace {
|
||||
origin: origin,
|
||||
values: Types(ExpectedFound {
|
||||
expected: expected,
|
||||
found: actual
|
||||
})
|
||||
};
|
||||
let trace = TypeTrace::types(cause, true, expected, actual);
|
||||
self.report_and_explain_type_error(trace, &err).emit();
|
||||
}
|
||||
|
||||
pub fn report_conflicting_default_types(&self,
|
||||
span: Span,
|
||||
body_id: ast::NodeId,
|
||||
expected: type_variable::Default<'tcx>,
|
||||
actual: type_variable::Default<'tcx>) {
|
||||
let trace = TypeTrace {
|
||||
origin: TypeOrigin::Misc(span),
|
||||
cause: ObligationCause::misc(span, body_id),
|
||||
values: Types(ExpectedFound {
|
||||
expected: expected.ty,
|
||||
found: actual.ty
|
||||
|
|
@ -1507,15 +1419,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
/// See `higher_ranked_match` in `higher_ranked/mod.rs` for more
|
||||
/// details.
|
||||
pub fn match_poly_projection_predicate(&self,
|
||||
origin: TypeOrigin,
|
||||
cause: ObligationCause<'tcx>,
|
||||
match_a: ty::PolyProjectionPredicate<'tcx>,
|
||||
match_b: ty::TraitRef<'tcx>)
|
||||
-> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
|
||||
{
|
||||
let span = origin.span();
|
||||
let span = cause.span;
|
||||
let match_trait_ref = match_a.skip_binder().projection_ty.trait_ref;
|
||||
let trace = TypeTrace {
|
||||
origin: origin,
|
||||
cause: cause,
|
||||
values: TraitRefs(ExpectedFound::new(true, match_trait_ref, match_b))
|
||||
};
|
||||
|
||||
|
|
@ -1664,23 +1576,23 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
|
||||
pub fn span(&self) -> Span {
|
||||
self.origin.span()
|
||||
self.cause.span
|
||||
}
|
||||
|
||||
pub fn types(origin: TypeOrigin,
|
||||
pub fn types(cause: &ObligationCause<'tcx>,
|
||||
a_is_expected: bool,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> TypeTrace<'tcx> {
|
||||
TypeTrace {
|
||||
origin: origin,
|
||||
cause: cause.clone(),
|
||||
values: Types(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dummy(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TypeTrace<'tcx> {
|
||||
TypeTrace {
|
||||
origin: TypeOrigin::Misc(syntax_pos::DUMMY_SP),
|
||||
cause: ObligationCause::dummy(),
|
||||
values: Types(ExpectedFound {
|
||||
expected: tcx.types.err,
|
||||
found: tcx.types.err,
|
||||
|
|
@ -1691,26 +1603,7 @@ impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
|
|||
|
||||
impl<'tcx> fmt::Debug for TypeTrace<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TypeTrace({:?})", self.origin)
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOrigin {
|
||||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
TypeOrigin::MethodCompatCheck(span) => span,
|
||||
TypeOrigin::ExprAssignable(span) => span,
|
||||
TypeOrigin::Misc(span) => span,
|
||||
TypeOrigin::RelateOutputImplTypes(span) => span,
|
||||
TypeOrigin::MatchExpressionArm(match_span, ..) => match_span,
|
||||
TypeOrigin::IfExpression(span) => span,
|
||||
TypeOrigin::IfExpressionWithNoElse(span) => span,
|
||||
TypeOrigin::EquatePredicate(span) => span,
|
||||
TypeOrigin::MainFunctionType(span) => span,
|
||||
TypeOrigin::StartFunctionType(span) => span,
|
||||
TypeOrigin::IntrinsicType(span) => span,
|
||||
TypeOrigin::MethodReceiver(span) => span,
|
||||
}
|
||||
write!(f, "TypeTrace({:?})", self.cause)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1787,16 +1680,6 @@ impl RegionVariableOrigin {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for TypeOrigin {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
|
|
@ -1824,12 +1707,12 @@ impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
|
|||
impl<'tcx> TypeFoldable<'tcx> for TypeTrace<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
TypeTrace {
|
||||
origin: self.origin.fold_with(folder),
|
||||
cause: self.cause.fold_with(folder),
|
||||
values: self.values.fold_with(folder)
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.origin.visit_with(visitor) || self.values.visit_with(visitor)
|
||||
self.cause.visit_with(visitor) || self.values.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
|||
-> RelateResult<'tcx, &'tcx ty::Region> {
|
||||
debug!("{}.regions({:?}, {:?}) self.cause={:?}",
|
||||
self.tag(), a, b, self.fields.cause);
|
||||
|
||||
// FIXME -- we have more fine-grained information available
|
||||
// from the "cause" field, we could perhaps give more tailored
|
||||
// error messages.
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use super::{SelectionContext, Obligation, ObligationCause};
|
|||
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use infer::{InferCtxt, InferOk, TypeOrigin};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
use infer::{InferCtxt, InferOk};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct InferIsLocal(bool);
|
||||
|
|
@ -55,8 +55,10 @@ 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.
|
||||
match selcx.infcx().eq_impl_headers(true, TypeOrigin::Misc(DUMMY_SP), &a_impl_header,
|
||||
&b_impl_header) {
|
||||
match selcx.infcx().eq_impl_headers(true,
|
||||
&ObligationCause::dummy(),
|
||||
&a_impl_header,
|
||||
&b_impl_header) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use super::{
|
|||
|
||||
use fmt_macros::{Parser, Piece, Position};
|
||||
use hir::def_id::DefId;
|
||||
use infer::{self, InferCtxt, TypeOrigin};
|
||||
use infer::{self, InferCtxt};
|
||||
use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
|
||||
use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::error::ExpectedFound;
|
||||
|
|
@ -100,7 +100,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
self.probe(|_| {
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
let err_buf;
|
||||
let mut err = &error.err;
|
||||
let mut values = None;
|
||||
|
|
@ -121,9 +120,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
obligation.cause.clone(),
|
||||
0
|
||||
);
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
if let Err(error) = self.eq_types(
|
||||
false, origin,
|
||||
false, &obligation.cause,
|
||||
data.ty, normalized.value
|
||||
) {
|
||||
values = Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
|
|
@ -136,10 +134,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
let mut diag = struct_span_err!(
|
||||
self.tcx.sess, origin.span(), E0271,
|
||||
self.tcx.sess, obligation.cause.span, E0271,
|
||||
"type mismatch resolving `{}`", predicate
|
||||
);
|
||||
self.note_type_err(&mut diag, origin, None, values, err);
|
||||
self.note_type_err(&mut diag, &obligation.cause, None, values, err);
|
||||
self.note_obligation_cause(&mut diag, obligation);
|
||||
diag.emit();
|
||||
});
|
||||
|
|
@ -529,7 +527,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
ty::Predicate::Equate(ref predicate) => {
|
||||
let predicate = self.resolve_type_vars_if_possible(predicate);
|
||||
let err = self.equality_predicate(span,
|
||||
let err = self.equality_predicate(&obligation.cause,
|
||||
&predicate).err().unwrap();
|
||||
struct_span_err!(self.tcx.sess, span, E0278,
|
||||
"the requirement `{}` is not satisfied (`{}`)",
|
||||
|
|
@ -851,7 +849,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
{
|
||||
let tcx = self.tcx;
|
||||
match *cause_code {
|
||||
ObligationCauseCode::MiscObligation => { }
|
||||
ObligationCauseCode::ExprAssignable |
|
||||
ObligationCauseCode::MatchExpressionArm { .. } |
|
||||
ObligationCauseCode::IfExpression |
|
||||
ObligationCauseCode::IfExpressionWithNoElse |
|
||||
ObligationCauseCode::EquatePredicate |
|
||||
ObligationCauseCode::MainFunctionType |
|
||||
ObligationCauseCode::StartFunctionType |
|
||||
ObligationCauseCode::IntrinsicType |
|
||||
ObligationCauseCode::MethodReceiver |
|
||||
ObligationCauseCode::MiscObligation => {
|
||||
}
|
||||
ObligationCauseCode::SliceOrArrayElem => {
|
||||
err.note("slice and array elements must have `Sized` type");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
|
|||
}
|
||||
|
||||
ty::Predicate::Equate(ref binder) => {
|
||||
match selcx.infcx().equality_predicate(obligation.cause.span, binder) {
|
||||
match selcx.infcx().equality_predicate(&obligation.cause, binder) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ pub use self::FulfillmentErrorCode::*;
|
|||
pub use self::Vtable::*;
|
||||
pub use self::ObligationCauseCode::*;
|
||||
|
||||
use hir;
|
||||
use hir::def_id::DefId;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use ty::subst::Substs;
|
||||
|
|
@ -148,6 +149,35 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
trait_item_def_id: DefId,
|
||||
lint_id: Option<ast::NodeId>,
|
||||
},
|
||||
|
||||
// Checking that this expression can be assigned where it needs to be
|
||||
// FIXME(eddyb) #11161 is the original Expr required?
|
||||
ExprAssignable,
|
||||
|
||||
// Computing common supertype in the arms of a match expression
|
||||
MatchExpressionArm { arm_span: Span,
|
||||
source: hir::MatchSource },
|
||||
|
||||
// Computing common supertype in an if expression
|
||||
IfExpression,
|
||||
|
||||
// Computing common supertype of an if expression with no else counter-part
|
||||
IfExpressionWithNoElse,
|
||||
|
||||
// `where a == b`
|
||||
EquatePredicate,
|
||||
|
||||
// `main` has wrong type
|
||||
MainFunctionType,
|
||||
|
||||
// `start` has wrong type
|
||||
StartFunctionType,
|
||||
|
||||
// intrinsic has wrong type
|
||||
IntrinsicType,
|
||||
|
||||
// method receiver
|
||||
MethodReceiver,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use super::VtableImplData;
|
|||
use super::util;
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use infer::{InferOk, TypeOrigin};
|
||||
use infer::InferOk;
|
||||
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
|
||||
use syntax::parse::token;
|
||||
use syntax::ast;
|
||||
|
|
@ -209,8 +209,7 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>(
|
|||
obligations);
|
||||
|
||||
let infcx = selcx.infcx();
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
match infcx.eq_types(true, origin, normalized_ty, obligation.predicate.ty) {
|
||||
match infcx.eq_types(true, &obligation.cause, normalized_ty, obligation.predicate.ty) {
|
||||
Ok(InferOk { obligations: inferred_obligations, .. }) => {
|
||||
// FIXME(#32730) once obligations are generated in inference, drop this assertion
|
||||
assert!(inferred_obligations.is_empty());
|
||||
|
|
@ -840,13 +839,12 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
|
|||
let same_name = data.item_name() == obligation.predicate.item_name;
|
||||
|
||||
let is_match = same_name && infcx.probe(|_| {
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
let data_poly_trait_ref =
|
||||
data.to_poly_trait_ref();
|
||||
let obligation_poly_trait_ref =
|
||||
obligation_trait_ref.to_poly_trait_ref();
|
||||
infcx.sub_poly_trait_refs(false,
|
||||
origin,
|
||||
obligation.cause.clone(),
|
||||
data_poly_trait_ref,
|
||||
obligation_poly_trait_ref)
|
||||
// FIXME(#32730) once obligations are propagated from unification in
|
||||
|
|
@ -1153,12 +1151,11 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
|
|||
|
||||
// select those with a relevant trait-ref
|
||||
let mut env_predicates = env_predicates.filter(|data| {
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
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,
|
||||
origin,
|
||||
obligation.cause.clone(),
|
||||
data_poly_trait_ref,
|
||||
obligation_poly_trait_ref).is_ok()
|
||||
})
|
||||
|
|
@ -1265,9 +1262,9 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
|
|||
-> Progress<'tcx>
|
||||
{
|
||||
let infcx = selcx.infcx();
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
let cause = obligation.cause.clone();
|
||||
let trait_ref = obligation.predicate.trait_ref;
|
||||
match infcx.match_poly_projection_predicate(origin, poly_projection, trait_ref) {
|
||||
match infcx.match_poly_projection_predicate(cause, poly_projection, trait_ref) {
|
||||
Ok(InferOk { value: ty_match, obligations }) => {
|
||||
// FIXME(#32730) once obligations are generated in inference, drop this assertion
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use super::util;
|
|||
|
||||
use hir::def_id::DefId;
|
||||
use infer;
|
||||
use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin};
|
||||
use infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
use ty::subst::{Kind, Subst, Substs};
|
||||
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||
use traits;
|
||||
|
|
@ -521,7 +521,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
|
||||
ty::Predicate::Equate(ref p) => {
|
||||
// does this code ever run?
|
||||
match self.infcx.equality_predicate(obligation.cause.span, p) {
|
||||
match self.infcx.equality_predicate(&obligation.cause, p) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
self.inferred_obligations.extend(obligations);
|
||||
EvaluatedToOk
|
||||
|
|
@ -1247,9 +1247,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
-> bool
|
||||
{
|
||||
assert!(!skol_trait_ref.has_escaping_regions());
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
let cause = obligation.cause.clone();
|
||||
match self.infcx.sub_poly_trait_refs(false,
|
||||
origin,
|
||||
cause,
|
||||
trait_bound.clone(),
|
||||
ty::Binder(skol_trait_ref.clone())) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
|
|
@ -2439,16 +2439,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
/// selection of the impl. Therefore, if there is a mismatch, we
|
||||
/// report an error to the user.
|
||||
fn confirm_poly_trait_refs(&mut self,
|
||||
obligation_cause: ObligationCause,
|
||||
obligation_cause: ObligationCause<'tcx>,
|
||||
obligation_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
expected_trait_ref: ty::PolyTraitRef<'tcx>)
|
||||
-> Result<(), SelectionError<'tcx>>
|
||||
{
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation_cause.span);
|
||||
|
||||
let obligation_trait_ref = obligation_trait_ref.clone();
|
||||
self.infcx.sub_poly_trait_refs(false,
|
||||
origin,
|
||||
obligation_cause.clone(),
|
||||
expected_trait_ref.clone(),
|
||||
obligation_trait_ref.clone())
|
||||
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
||||
|
|
@ -2482,9 +2480,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
builtin_bounds: data_b.builtin_bounds,
|
||||
projection_bounds: data_a.projection_bounds.clone(),
|
||||
});
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.sub_types(false, origin, new_trait, target)
|
||||
self.infcx.sub_types(false, &obligation.cause, new_trait, target)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
|
||||
|
|
@ -2553,9 +2550,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
|
||||
// [T; n] -> [T].
|
||||
(&ty::TyArray(a, _), &ty::TySlice(b)) => {
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.sub_types(false, origin, a, b)
|
||||
self.infcx.sub_types(false, &obligation.cause, a, b)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
}
|
||||
|
|
@ -2617,9 +2613,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
});
|
||||
let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.sub_types(false, origin, new_struct, target)
|
||||
self.infcx.sub_types(false, &obligation.cause, new_struct, target)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
self.inferred_obligations.extend(obligations);
|
||||
|
||||
|
|
@ -2705,10 +2700,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
impl_trait_ref,
|
||||
skol_obligation_trait_ref);
|
||||
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.eq_trait_refs(false,
|
||||
origin,
|
||||
&obligation.cause,
|
||||
impl_trait_ref.value.clone(),
|
||||
skol_obligation_trait_ref)
|
||||
.map_err(|e| {
|
||||
|
|
@ -2780,9 +2774,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
obligation,
|
||||
poly_trait_ref);
|
||||
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
self.infcx.sub_poly_trait_refs(false,
|
||||
origin,
|
||||
obligation.cause.clone(),
|
||||
poly_trait_ref,
|
||||
obligation.predicate.to_poly_trait_ref())
|
||||
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use super::util::impl_trait_ref_and_oblig;
|
|||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use hir::def_id::DefId;
|
||||
use infer::{InferCtxt, InferOk, TypeOrigin};
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use middle::region;
|
||||
use ty::subst::{Subst, Substs};
|
||||
use traits::{self, Reveal, ObligationCause};
|
||||
|
|
@ -223,8 +223,10 @@ 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, TypeOrigin::Misc(DUMMY_SP), source_trait_ref,
|
||||
target_trait_ref) {
|
||||
match infcx.eq_trait_refs(true,
|
||||
&ObligationCause::dummy(),
|
||||
source_trait_ref,
|
||||
target_trait_ref) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty())
|
||||
|
|
|
|||
|
|
@ -213,6 +213,34 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
|||
lint_id: lint_id,
|
||||
})
|
||||
}
|
||||
super::ExprAssignable => {
|
||||
Some(super::ExprAssignable)
|
||||
}
|
||||
super::MatchExpressionArm { arm_span, source } => {
|
||||
Some(super::MatchExpressionArm { arm_span: arm_span,
|
||||
source: source })
|
||||
}
|
||||
super::IfExpression => {
|
||||
Some(super::IfExpression)
|
||||
}
|
||||
super::IfExpressionWithNoElse => {
|
||||
Some(super::IfExpressionWithNoElse)
|
||||
}
|
||||
super::EquatePredicate => {
|
||||
Some(super::EquatePredicate)
|
||||
}
|
||||
super::MainFunctionType => {
|
||||
Some(super::MainFunctionType)
|
||||
}
|
||||
super::StartFunctionType => {
|
||||
Some(super::StartFunctionType)
|
||||
}
|
||||
super::IntrinsicType => {
|
||||
Some(super::IntrinsicType)
|
||||
}
|
||||
super::MethodReceiver => {
|
||||
Some(super::MethodReceiver)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -461,6 +489,15 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
|
|||
impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
super::ExprAssignable |
|
||||
super::MatchExpressionArm { arm_span: _, source: _ } |
|
||||
super::IfExpression |
|
||||
super::IfExpressionWithNoElse |
|
||||
super::EquatePredicate |
|
||||
super::MainFunctionType |
|
||||
super::StartFunctionType |
|
||||
super::IntrinsicType |
|
||||
super::MethodReceiver |
|
||||
super::MiscObligation |
|
||||
super::SliceOrArrayElem |
|
||||
super::TupleElem |
|
||||
|
|
@ -497,6 +534,15 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
|
|||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
match *self {
|
||||
super::ExprAssignable |
|
||||
super::MatchExpressionArm { arm_span: _, source: _ } |
|
||||
super::IfExpression |
|
||||
super::IfExpressionWithNoElse |
|
||||
super::EquatePredicate |
|
||||
super::MainFunctionType |
|
||||
super::StartFunctionType |
|
||||
super::IntrinsicType |
|
||||
super::MethodReceiver |
|
||||
super::MiscObligation |
|
||||
super::SliceOrArrayElem |
|
||||
super::TupleElem |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue