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 |
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ use rustc::middle::region::CodeExtentData;
|
|||
use rustc::middle::resolve_lifetime;
|
||||
use rustc::middle::stability;
|
||||
use rustc::ty::subst::{Kind, Subst};
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::traits::{ObligationCause, Reveal};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
|
||||
use rustc::infer::{self, InferOk, InferResult};
|
||||
use rustc_metadata::cstore::CStore;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::session::{self, config};
|
||||
|
|
@ -36,7 +36,6 @@ use errors::emitter::Emitter;
|
|||
use errors::{Level, DiagnosticBuilder};
|
||||
use syntax::parse::token;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
use rustc::hir;
|
||||
|
||||
|
|
@ -245,7 +244,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn make_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
|
||||
match self.infcx.sub_types(true, TypeOrigin::Misc(DUMMY_SP), a, b) {
|
||||
match self.infcx.sub_types(true, &ObligationCause::dummy(), a, b) {
|
||||
Ok(_) => true,
|
||||
Err(ref e) => panic!("Encountered error: {}", e),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,22 +306,28 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
pub struct TypeChecker<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
fulfillment_cx: traits::FulfillmentContext<'tcx>,
|
||||
last_span: Span
|
||||
last_span: Span,
|
||||
body_id: ast::NodeId,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||
fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, body_id: ast::NodeId) -> Self {
|
||||
TypeChecker {
|
||||
infcx: infcx,
|
||||
fulfillment_cx: traits::FulfillmentContext::new(),
|
||||
last_span: DUMMY_SP
|
||||
last_span: DUMMY_SP,
|
||||
body_id: body_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn misc(&self, span: Span) -> traits::ObligationCause<'tcx> {
|
||||
traits::ObligationCause::misc(span, self.body_id)
|
||||
}
|
||||
|
||||
fn sub_types(&self, span: Span, sup: Ty<'tcx>, sub: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
{
|
||||
self.infcx.sub_types(false, infer::TypeOrigin::Misc(span), sup, sub)
|
||||
self.infcx.sub_types(false, &self.misc(span), sup, sub)
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
|
||||
}
|
||||
|
|
@ -329,7 +335,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
fn eq_types(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
{
|
||||
self.infcx.eq_types(false, infer::TypeOrigin::Misc(span), a, b)
|
||||
self.infcx.eq_types(false, &self.misc(span), a, b)
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
|
||||
}
|
||||
|
|
@ -715,7 +721,7 @@ impl<'tcx> MirPass<'tcx> for TypeckMir {
|
|||
}
|
||||
let param_env = ty::ParameterEnvironment::for_item(tcx, src.item_id());
|
||||
tcx.infer_ctxt(None, Some(param_env), Reveal::NotSpecializable).enter(|infcx| {
|
||||
let mut checker = TypeChecker::new(&infcx);
|
||||
let mut checker = TypeChecker::new(&infcx, src.item_id());
|
||||
{
|
||||
let mut verifier = TypeVerifier::new(&mut checker, mir);
|
||||
verifier.visit_mir(mir);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
use rustc::hir::{self, PatKind};
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc::infer::{self, InferOk, TypeOrigin};
|
||||
use rustc::infer::{self, InferOk};
|
||||
use rustc::traits::ObligationCauseCode;
|
||||
use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
|
||||
use check::{FnCtxt, Expectation, Diverges};
|
||||
use util::nodemap::FxHashMap;
|
||||
|
|
@ -450,14 +451,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
_ => false
|
||||
};
|
||||
|
||||
let origin = if is_if_let_fallback {
|
||||
TypeOrigin::IfExpressionWithNoElse(expr.span)
|
||||
let cause = if is_if_let_fallback {
|
||||
self.cause(expr.span, ObligationCauseCode::IfExpressionWithNoElse)
|
||||
} else {
|
||||
TypeOrigin::MatchExpressionArm(expr.span, arm.body.span, match_src)
|
||||
self.cause(expr.span, ObligationCauseCode::MatchExpressionArm {
|
||||
arm_span: arm.body.span,
|
||||
source: match_src
|
||||
})
|
||||
};
|
||||
|
||||
let result = if is_if_let_fallback {
|
||||
self.eq_types(true, origin, arm_ty, result_ty)
|
||||
self.eq_types(true, &cause, arm_ty, result_ty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
@ -468,7 +472,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
self.try_coerce(&arm.body, arm_ty, coerce_first)
|
||||
} else {
|
||||
let prev_arms = || arms[..i].iter().map(|arm| &*arm.body);
|
||||
self.try_find_coercion_lub(origin, prev_arms, result_ty, &arm.body, arm_ty)
|
||||
self.try_find_coercion_lub(&cause, prev_arms, result_ty, &arm.body, arm_ty)
|
||||
};
|
||||
|
||||
result_ty = match result {
|
||||
|
|
@ -479,7 +483,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
} else {
|
||||
(result_ty, arm_ty)
|
||||
};
|
||||
self.report_mismatched_types(origin, expected, found, e);
|
||||
self.report_mismatched_types(&cause, expected, found, e);
|
||||
self.tcx.types.err
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@
|
|||
use check::FnCtxt;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::infer::{Coercion, InferOk, TypeOrigin, TypeTrace};
|
||||
use rustc::traits::{self, ObligationCause};
|
||||
use rustc::infer::{Coercion, InferOk, TypeTrace};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
|
||||
use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
|
|
@ -78,7 +78,7 @@ use std::ops::Deref;
|
|||
|
||||
struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
|
||||
origin: TypeOrigin,
|
||||
cause: ObligationCause<'tcx>,
|
||||
use_lub: bool,
|
||||
unsizing_obligations: RefCell<Vec<traits::PredicateObligation<'tcx>>>,
|
||||
}
|
||||
|
|
@ -104,10 +104,10 @@ fn coerce_mutbls<'tcx>(from_mutbl: hir::Mutability,
|
|||
}
|
||||
|
||||
impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>, origin: TypeOrigin) -> Self {
|
||||
fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>, cause: ObligationCause<'tcx>) -> Self {
|
||||
Coerce {
|
||||
fcx: fcx,
|
||||
origin: origin,
|
||||
cause: cause,
|
||||
use_lub: false,
|
||||
unsizing_obligations: RefCell::new(vec![]),
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
|
||||
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(self.origin, false, a, b);
|
||||
let trace = TypeTrace::types(&self.cause, false, a, b);
|
||||
if self.use_lub {
|
||||
self.lub(false, trace, &a, &b)
|
||||
.map(|InferOk { value, obligations }| {
|
||||
|
|
@ -238,7 +238,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
_ => return self.unify_and_identity(a, b),
|
||||
};
|
||||
|
||||
let span = self.origin.span();
|
||||
let span = self.cause.span;
|
||||
|
||||
let mut first_error = None;
|
||||
let mut r_borrow_var = None;
|
||||
|
|
@ -430,7 +430,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
(&ty::TyRef(_, mt_a), &ty::TyRef(_, mt_b)) => {
|
||||
coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?;
|
||||
|
||||
let coercion = Coercion(self.origin.span());
|
||||
let coercion = Coercion(self.cause.span);
|
||||
let r_borrow = self.next_region_var(coercion);
|
||||
(mt_a.ty, Some(AutoBorrow::Ref(r_borrow, mt_b.mutbl)))
|
||||
}
|
||||
|
|
@ -449,7 +449,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
let mut leftover_predicates = vec![];
|
||||
|
||||
// Create an obligation for `Source: CoerceUnsized<Target>`.
|
||||
let cause = ObligationCause::misc(self.origin.span(), self.body_id);
|
||||
let cause = ObligationCause::misc(self.cause.span, self.body_id);
|
||||
queue.push_back(self.tcx
|
||||
.predicate_for_trait_def(cause, coerce_unsized_did, 0, source, &[target]));
|
||||
|
||||
|
|
@ -635,7 +635,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let source = self.resolve_type_vars_with_obligations(expr_ty);
|
||||
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
|
||||
|
||||
let mut coerce = Coerce::new(self, TypeOrigin::ExprAssignable(expr.span));
|
||||
let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable);
|
||||
let mut coerce = Coerce::new(self, cause);
|
||||
self.commit_if_ok(|_| {
|
||||
let adjustment = apply(&mut coerce, &|| Some(expr), source, target)?;
|
||||
if !adjustment.is_identity() {
|
||||
|
|
@ -655,7 +656,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
/// tries to unify the types, potentially inserting coercions on any of the
|
||||
/// provided expressions and returns their LUB (aka "common supertype").
|
||||
pub fn try_find_coercion_lub<'b, E, I>(&self,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
exprs: E,
|
||||
prev_ty: Ty<'tcx>,
|
||||
new: &'b hir::Expr,
|
||||
|
|
@ -669,7 +670,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let new_ty = self.resolve_type_vars_with_obligations(new_ty);
|
||||
debug!("coercion::try_find_lub({:?}, {:?})", prev_ty, new_ty);
|
||||
|
||||
let trace = TypeTrace::types(origin, true, prev_ty, new_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.
|
||||
|
|
@ -715,7 +716,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let mut coerce = Coerce::new(self, origin);
|
||||
let mut coerce = Coerce::new(self, cause.clone());
|
||||
coerce.use_lub = true;
|
||||
|
||||
// First try to coerce the new expression to the type of the previous ones,
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
// except according to those terms.
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::infer::{self, InferOk, TypeOrigin};
|
||||
use rustc::infer::{self, InferOk};
|
||||
use rustc::middle::free_region::FreeRegionMap;
|
||||
use rustc::ty;
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
|
||||
use rustc::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::hir::{ImplItemKind, TraitItem_, Ty_};
|
||||
|
|
@ -95,6 +95,17 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
||||
|
||||
let cause = ObligationCause {
|
||||
span: impl_m_span,
|
||||
body_id: impl_m_body_id,
|
||||
code: ObligationCauseCode::CompareImplMethodObligation {
|
||||
item_name: impl_m.name,
|
||||
impl_item_def_id: impl_m.def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
lint_id: if !old_broken_mode { Some(impl_m_body_id) } else { None },
|
||||
},
|
||||
};
|
||||
|
||||
// This code is best explained by example. Consider a trait:
|
||||
//
|
||||
// trait Trait<'t,T> {
|
||||
|
|
@ -235,20 +246,9 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
let traits::Normalized { value: predicate, .. } =
|
||||
traits::normalize(&mut selcx, normalize_cause.clone(), &predicate);
|
||||
|
||||
let cause = traits::ObligationCause {
|
||||
span: impl_m_span,
|
||||
body_id: impl_m_body_id,
|
||||
code: traits::ObligationCauseCode::CompareImplMethodObligation {
|
||||
item_name: impl_m.name,
|
||||
impl_item_def_id: impl_m.def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
lint_id: if !old_broken_mode { Some(impl_m_body_id) } else { None },
|
||||
},
|
||||
};
|
||||
|
||||
fulfillment_cx.borrow_mut().register_predicate_obligation(
|
||||
&infcx,
|
||||
traits::Obligation::new(cause, predicate));
|
||||
traits::Obligation::new(cause.clone(), predicate));
|
||||
}
|
||||
|
||||
// We now need to check that the signature of the impl method is
|
||||
|
|
@ -266,7 +266,6 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
// Compute skolemized form of impl and trait method tys.
|
||||
let tcx = infcx.tcx;
|
||||
let origin = TypeOrigin::MethodCompatCheck(impl_m_span);
|
||||
|
||||
let m_fty = |method: &ty::AssociatedItem| {
|
||||
match tcx.item_type(method.def_id).sty {
|
||||
|
|
@ -315,7 +314,7 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
|
||||
|
||||
let sub_result = infcx.sub_types(false, origin, impl_fty, trait_fty)
|
||||
let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
@ -328,22 +327,25 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
let (impl_err_span, trait_err_span) = extract_spans_for_error_reporting(&infcx,
|
||||
&terr,
|
||||
origin,
|
||||
&cause,
|
||||
impl_m,
|
||||
impl_sig,
|
||||
trait_m,
|
||||
trait_sig);
|
||||
|
||||
let origin = TypeOrigin::MethodCompatCheck(impl_err_span);
|
||||
let cause = ObligationCause {
|
||||
span: impl_err_span,
|
||||
..cause.clone()
|
||||
};
|
||||
|
||||
let mut diag = struct_span_err!(tcx.sess,
|
||||
origin.span(),
|
||||
cause.span,
|
||||
E0053,
|
||||
"method `{}` has an incompatible type for trait",
|
||||
trait_m.name);
|
||||
|
||||
infcx.note_type_err(&mut diag,
|
||||
origin,
|
||||
&cause,
|
||||
trait_err_span.map(|sp| (sp, format!("type in trait"))),
|
||||
Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: trait_fty,
|
||||
|
|
@ -429,7 +431,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
|
||||
terr: &TypeError,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
impl_m: &ty::AssociatedItem,
|
||||
impl_sig: ty::FnSig<'tcx>,
|
||||
trait_m: &ty::AssociatedItem,
|
||||
|
|
@ -478,9 +480,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
|
|||
}
|
||||
}
|
||||
})
|
||||
.unwrap_or((origin.span(), tcx.map.span_if_local(trait_m.def_id)))
|
||||
.unwrap_or((cause.span, tcx.map.span_if_local(trait_m.def_id)))
|
||||
} else {
|
||||
(origin.span(), tcx.map.span_if_local(trait_m.def_id))
|
||||
(cause.span, tcx.map.span_if_local(trait_m.def_id))
|
||||
}
|
||||
}
|
||||
TypeError::Sorts(ExpectedFound { .. }) => {
|
||||
|
|
@ -499,25 +501,25 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
|
|||
.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, origin, trait_arg_ty, impl_arg_ty) {
|
||||
match infcx.sub_types(true, &cause, trait_arg_ty, impl_arg_ty) {
|
||||
Ok(_) => None,
|
||||
Err(_) => Some((impl_arg.ty.span, Some(trait_arg.ty.span))),
|
||||
}
|
||||
})
|
||||
.next()
|
||||
.unwrap_or_else(|| {
|
||||
if infcx.sub_types(false, origin, impl_sig.output, trait_sig.output)
|
||||
if infcx.sub_types(false, &cause, impl_sig.output, trait_sig.output)
|
||||
.is_err() {
|
||||
(impl_m_output.span(), Some(trait_m_output.span()))
|
||||
} else {
|
||||
(origin.span(), tcx.map.span_if_local(trait_m.def_id))
|
||||
(cause.span, tcx.map.span_if_local(trait_m.def_id))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
(origin.span(), tcx.map.span_if_local(trait_m.def_id))
|
||||
(cause.span, tcx.map.span_if_local(trait_m.def_id))
|
||||
}
|
||||
}
|
||||
_ => (origin.span(), tcx.map.span_if_local(trait_m.def_id)),
|
||||
_ => (cause.span, tcx.map.span_if_local(trait_m.def_id)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -787,7 +789,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
// Compute skolemized form of impl and trait const tys.
|
||||
let impl_ty = tcx.item_type(impl_c.def_id).subst(tcx, impl_to_skol_substs);
|
||||
let trait_ty = tcx.item_type(trait_c.def_id).subst(tcx, trait_to_skol_substs);
|
||||
let mut origin = TypeOrigin::Misc(impl_c_span);
|
||||
let mut cause = ObligationCause::misc(impl_c_span, impl_c_node_id);
|
||||
|
||||
let err = infcx.commit_if_ok(|_| {
|
||||
// There is no "body" here, so just pass dummy id.
|
||||
|
|
@ -807,7 +809,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
debug!("compare_const_impl: trait_ty={:?}", trait_ty);
|
||||
|
||||
infcx.sub_types(false, origin, impl_ty, trait_ty)
|
||||
infcx.sub_types(false, &cause, impl_ty, trait_ty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty())
|
||||
|
|
@ -821,12 +823,12 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
// Locate the Span containing just the type of the offending impl
|
||||
match tcx.map.expect_impl_item(impl_c_node_id).node {
|
||||
ImplItemKind::Const(ref ty, _) => origin = TypeOrigin::Misc(ty.span),
|
||||
ImplItemKind::Const(ref ty, _) => cause.span = ty.span,
|
||||
_ => bug!("{:?} is not a impl const", impl_c),
|
||||
}
|
||||
|
||||
let mut diag = struct_span_err!(tcx.sess,
|
||||
origin.span(),
|
||||
cause.span,
|
||||
E0326,
|
||||
"implemented const `{}` has an incompatible type for \
|
||||
trait",
|
||||
|
|
@ -840,7 +842,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
};
|
||||
|
||||
infcx.note_type_err(&mut diag,
|
||||
origin,
|
||||
&cause,
|
||||
Some((trait_c_span, format!("type in trait"))),
|
||||
Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: trait_ty,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
use check::FnCtxt;
|
||||
use rustc::ty::Ty;
|
||||
use rustc::infer::{InferOk, TypeOrigin};
|
||||
use rustc::infer::{InferOk};
|
||||
use rustc::traits::ObligationCause;
|
||||
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
|
|
@ -20,34 +21,34 @@ 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 origin = TypeOrigin::Misc(sp);
|
||||
match self.sub_types(false, origin, actual, expected) {
|
||||
let cause = self.misc(sp);
|
||||
match self.sub_types(false, &cause, actual, expected) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
},
|
||||
Err(e) => {
|
||||
self.report_mismatched_types(origin, expected, actual, e);
|
||||
self.report_mismatched_types(&cause, expected, actual, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
|
||||
self.demand_eqtype_with_origin(TypeOrigin::Misc(sp), expected, actual);
|
||||
self.demand_eqtype_with_origin(&self.misc(sp), expected, actual);
|
||||
}
|
||||
|
||||
pub fn demand_eqtype_with_origin(&self,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>)
|
||||
{
|
||||
match self.eq_types(false, origin, actual, expected) {
|
||||
match self.eq_types(false, cause, actual, expected) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
},
|
||||
Err(e) => {
|
||||
self.report_mismatched_types(origin, expected, actual, e);
|
||||
self.report_mismatched_types(cause, expected, actual, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,9 +57,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) {
|
||||
let expected = self.resolve_type_vars_with_obligations(expected);
|
||||
if let Err(e) = self.try_coerce(expr, checked_ty, expected) {
|
||||
let origin = TypeOrigin::Misc(expr.span);
|
||||
let cause = self.misc(expr.span);
|
||||
let expr_ty = self.resolve_type_vars_with_obligations(checked_ty);
|
||||
self.report_mismatched_types(origin, expected, expr_ty, e);
|
||||
self.report_mismatched_types(&cause, expected, expr_ty, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc::infer::{self, InferOk};
|
|||
use middle::region;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::traits::{self, ObligationCause, Reveal};
|
||||
use util::nodemap::FxHashSet;
|
||||
|
||||
use syntax::ast;
|
||||
|
|
@ -93,8 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
|||
infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did);
|
||||
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs);
|
||||
|
||||
match infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
|
||||
named_type, fresh_impl_self_ty) {
|
||||
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
|
||||
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
//! intrinsics that the compiler exposes.
|
||||
|
||||
use intrinsics;
|
||||
use rustc::infer::TypeOrigin;
|
||||
use rustc::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::FnSig;
|
||||
use rustc::ty::{self, Ty};
|
||||
|
|
@ -63,7 +63,9 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
.emit();
|
||||
} else {
|
||||
require_same_types(ccx,
|
||||
TypeOrigin::IntrinsicType(it.span),
|
||||
&ObligationCause::new(it.span,
|
||||
it.id,
|
||||
ObligationCauseCode::IntrinsicType),
|
||||
tcx.item_type(def_id),
|
||||
fty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc::traits;
|
|||
use rustc::ty::{self, LvaluePreference, NoPreference, PreferMutLvalue, Ty};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::infer::{self, InferOk, TypeOrigin};
|
||||
use rustc::infer::{self, InferOk};
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
|
||||
|
|
@ -330,7 +330,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, TypeOrigin::Misc(self.span), self_ty, method_self_ty) {
|
||||
match self.sub_types(false, &self.misc(self.span), self_ty, method_self_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ use check::FnCtxt;
|
|||
use hir::def_id::DefId;
|
||||
use hir::def::Def;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::traits;
|
||||
use rustc::traits::{self, ObligationCause};
|
||||
use rustc::ty::{self, Ty, ToPolyTraitRef, TraitRef, TypeFoldable};
|
||||
use rustc::infer::{InferOk, TypeOrigin};
|
||||
use rustc::infer::InferOk;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
use syntax::ast;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
|
|
@ -1032,7 +1032,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
self.probe(|_| {
|
||||
// First check that the self type can be related.
|
||||
match self.sub_types(false,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
&ObligationCause::dummy(),
|
||||
self_ty,
|
||||
probe.xform_self_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ use hir::def::{Def, CtorKind, PathResolution};
|
|||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use hir::pat_util;
|
||||
use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin,
|
||||
TypeOrigin, TypeTrace, type_variable};
|
||||
TypeTrace, type_variable};
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
|
||||
use rustc::ty::{ParamTy, ParameterEnvironment};
|
||||
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
|
||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility};
|
||||
|
|
@ -1521,6 +1521,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cause(&self,
|
||||
span: Span,
|
||||
code: ObligationCauseCode<'tcx>)
|
||||
-> ObligationCause<'tcx> {
|
||||
ObligationCause::new(span, self.body_id, code)
|
||||
}
|
||||
|
||||
pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
|
||||
self.cause(span, ObligationCauseCode::MiscObligation)
|
||||
}
|
||||
|
||||
/// Resolves type variables in `ty` if possible. Unlike the infcx
|
||||
/// version (resolve_type_vars_if_possible), this version will
|
||||
/// also select obligations if it seems useful, in an effort
|
||||
|
|
@ -2096,8 +2107,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
if let Some(default) = default_map.get(ty) {
|
||||
let default = default.clone();
|
||||
match self.eq_types(false,
|
||||
TypeOrigin::Misc(default.origin_span),
|
||||
ty, default.ty) {
|
||||
&self.misc(default.origin_span),
|
||||
ty,
|
||||
default.ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty())
|
||||
|
|
@ -2146,6 +2158,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
self.report_conflicting_default_types(
|
||||
first_default.origin_span,
|
||||
self.body_id,
|
||||
first_default,
|
||||
second_default)
|
||||
}
|
||||
|
|
@ -2194,8 +2207,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
if let Some(default) = default_map.get(ty) {
|
||||
let default = default.clone();
|
||||
match self.eq_types(false,
|
||||
TypeOrigin::Misc(default.origin_span),
|
||||
ty, default.ty) {
|
||||
&self.misc(default.origin_span),
|
||||
ty,
|
||||
default.ty) {
|
||||
// FIXME(#32730) propagate obligations
|
||||
Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
|
||||
Err(_) => {
|
||||
|
|
@ -2765,8 +2779,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// return type (likely containing type variables if the function
|
||||
// is polymorphic) and the expected return type.
|
||||
// No argument expectations are produced if unification fails.
|
||||
let origin = TypeOrigin::Misc(call_span);
|
||||
let ures = self.sub_types(false, origin, formal_ret, ret_ty);
|
||||
let origin = self.misc(call_span);
|
||||
let ures = self.sub_types(false, &origin, formal_ret, ret_ty);
|
||||
// FIXME(#15760) can't use try! here, FromError doesn't default
|
||||
// to identity so the resulting type is not constrained.
|
||||
match ures {
|
||||
|
|
@ -2852,16 +2866,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
self.diverges.set(Diverges::Maybe);
|
||||
|
||||
let unit = self.tcx.mk_nil();
|
||||
let (origin, expected, found, result) =
|
||||
let (cause, expected_ty, found_ty, result);
|
||||
if let Some(else_expr) = opt_else_expr {
|
||||
let else_ty = self.check_expr_with_expectation(else_expr, expected);
|
||||
let else_diverges = self.diverges.get();
|
||||
cause = self.cause(sp, ObligationCauseCode::IfExpression);
|
||||
|
||||
// Only try to coerce-unify if we have a then expression
|
||||
// to assign coercions to, otherwise it's () or diverging.
|
||||
let origin = TypeOrigin::IfExpression(sp);
|
||||
let result = if let Some(ref then) = then_blk.expr {
|
||||
let res = self.try_find_coercion_lub(origin, || Some(&**then),
|
||||
expected_ty = then_ty;
|
||||
found_ty = else_ty;
|
||||
result = if let Some(ref then) = then_blk.expr {
|
||||
let res = self.try_find_coercion_lub(&cause, || Some(&**then),
|
||||
then_ty, else_expr, else_ty);
|
||||
|
||||
// In case we did perform an adjustment, we have to update
|
||||
|
|
@ -2876,7 +2892,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
res
|
||||
} else {
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(origin, true, then_ty, else_ty);
|
||||
let trace = TypeTrace::types(&cause, true, then_ty, else_ty);
|
||||
self.lub(true, trace, &then_ty, &else_ty)
|
||||
.map(|InferOk { value, obligations }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
|
|
@ -2888,21 +2904,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
// We won't diverge unless both branches do (or the condition does).
|
||||
self.diverges.set(cond_diverges | then_diverges & else_diverges);
|
||||
|
||||
(origin, then_ty, else_ty, result)
|
||||
} else {
|
||||
// If the condition is false we can't diverge.
|
||||
self.diverges.set(cond_diverges);
|
||||
|
||||
let origin = TypeOrigin::IfExpressionWithNoElse(sp);
|
||||
(origin, unit, then_ty,
|
||||
self.eq_types(true, origin, unit, then_ty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
unit
|
||||
}))
|
||||
};
|
||||
cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
|
||||
expected_ty = unit;
|
||||
found_ty = then_ty;
|
||||
result = self.eq_types(true, &cause, unit, then_ty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
unit
|
||||
});
|
||||
}
|
||||
|
||||
match result {
|
||||
Ok(ty) => {
|
||||
|
|
@ -2913,7 +2928,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
self.report_mismatched_types(origin, expected, found, e);
|
||||
self.report_mismatched_types(&cause, expected_ty, found_ty, e);
|
||||
self.tcx.types.err
|
||||
}
|
||||
}
|
||||
|
|
@ -3565,7 +3580,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
self.check_expr_coercable_to_type(&e, self.ret_ty);
|
||||
} else {
|
||||
let eq_result = self.eq_types(false,
|
||||
TypeOrigin::Misc(expr.span),
|
||||
&self.misc(expr.span),
|
||||
self.ret_ty,
|
||||
tcx.mk_nil())
|
||||
// FIXME(#32730) propagate obligations
|
||||
|
|
@ -3695,20 +3710,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
for (i, e) in args.iter().enumerate() {
|
||||
let e_ty = self.check_expr_with_hint(e, coerce_to);
|
||||
let origin = TypeOrigin::Misc(e.span);
|
||||
let cause = self.misc(e.span);
|
||||
|
||||
// Special-case the first element, as it has no "previous expressions".
|
||||
let result = if i == 0 {
|
||||
self.try_coerce(e, e_ty, coerce_to)
|
||||
} else {
|
||||
let prev_elems = || args[..i].iter().map(|e| &**e);
|
||||
self.try_find_coercion_lub(origin, prev_elems, unified, e, e_ty)
|
||||
self.try_find_coercion_lub(&cause, prev_elems, unified, e, e_ty)
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(ty) => unified = ty,
|
||||
Err(e) => {
|
||||
self.report_mismatched_types(origin, unified, e_ty, e);
|
||||
self.report_mismatched_types(&cause, unified, e_ty, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4064,9 +4079,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// We're not diverging and there's an expected type, which,
|
||||
// in case it's not `()`, could result in an error higher-up.
|
||||
// We have a chance to error here early and be more helpful.
|
||||
let origin = TypeOrigin::Misc(blk.span);
|
||||
let trace = TypeTrace::types(origin, false, ty, ety);
|
||||
match self.sub_types(false, origin, ty, ety) {
|
||||
let cause = self.misc(blk.span);
|
||||
let trace = TypeTrace::types(&cause, false, ty, ety);
|
||||
match self.sub_types(false, &cause, ty, ety) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
@ -4367,7 +4382,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let ty = self.tcx.item_type(impl_def_id);
|
||||
|
||||
let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
|
||||
match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
|
||||
match self.sub_types(false, &self.misc(span), self_ty, impl_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ use middle::region::{self, CodeExtent};
|
|||
use rustc::ty::subst::Substs;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, MethodCall, TypeFoldable};
|
||||
use rustc::infer::{self, GenericKind, InferOk, SubregionOrigin, TypeOrigin, VerifyBound};
|
||||
use rustc::infer::{self, GenericKind, InferOk, SubregionOrigin, VerifyBound};
|
||||
use hir::pat_util;
|
||||
use rustc::ty::adjustment;
|
||||
use rustc::ty::wf::ImpliedBound;
|
||||
|
|
@ -1762,7 +1762,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
outlives);
|
||||
|
||||
// check whether this predicate applies to our current projection
|
||||
match self.eq_types(false, TypeOrigin::Misc(span), ty, outlives.0) {
|
||||
let cause = self.fcx.misc(span);
|
||||
match self.eq_types(false, &cause, ty, outlives.0) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ use CrateCtxt;
|
|||
|
||||
use hir::def_id::DefId;
|
||||
use middle::region::{CodeExtent};
|
||||
use rustc::infer::TypeOrigin;
|
||||
use rustc::traits;
|
||||
use rustc::traits::{self, ObligationCauseCode};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
|
||||
|
|
@ -29,7 +28,7 @@ use rustc::hir;
|
|||
|
||||
pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> {
|
||||
ccx: &'ccx CrateCtxt<'ccx, 'tcx>,
|
||||
code: traits::ObligationCauseCode<'tcx>,
|
||||
code: ObligationCauseCode<'tcx>,
|
||||
}
|
||||
|
||||
/// Helper type of a temporary returned by .for_item(...).
|
||||
|
|
@ -37,7 +36,7 @@ pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> {
|
|||
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
|
||||
struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
|
||||
code: traits::ObligationCauseCode<'gcx>,
|
||||
code: ObligationCauseCode<'gcx>,
|
||||
id: ast::NodeId,
|
||||
span: Span
|
||||
}
|
||||
|
|
@ -67,7 +66,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
-> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
CheckTypeWellFormedVisitor {
|
||||
ccx: ccx,
|
||||
code: traits::ObligationCauseCode::MiscObligation
|
||||
code: ObligationCauseCode::MiscObligation
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -515,8 +514,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
|
||||
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
|
||||
|
||||
let origin = TypeOrigin::MethodReceiver(span);
|
||||
fcx.demand_eqtype_with_origin(origin, rcvr_ty, self_arg_ty);
|
||||
let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
|
||||
fcx.demand_eqtype_with_origin(&cause, rcvr_ty, self_arg_ty);
|
||||
}
|
||||
|
||||
fn check_variances_for_type_defn(&self,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use hir::def_id::DefId;
|
|||
use middle::lang_items::UnsizeTraitLangItem;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::traits::{self, ObligationCause, Reveal};
|
||||
use rustc::ty::ParameterEnvironment;
|
||||
use rustc::ty::{Ty, TyBool, TyChar, TyError};
|
||||
use rustc::ty::{TyParam, TyRawPtr};
|
||||
|
|
@ -30,7 +30,7 @@ use rustc::ty::{TyProjection, TyAnon};
|
|||
use rustc::ty::util::CopyImplementationError;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use CrateCtxt;
|
||||
use rustc::infer::{self, InferCtxt, TypeOrigin};
|
||||
use rustc::infer::{self, InferCtxt};
|
||||
use syntax_pos::Span;
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::hir::map as hir_map;
|
||||
|
|
@ -344,12 +344,12 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
|||
target);
|
||||
|
||||
tcx.infer_ctxt(None, Some(param_env), Reveal::ExactMatch).enter(|infcx| {
|
||||
let origin = TypeOrigin::Misc(span);
|
||||
let cause = ObligationCause::misc(span, impl_node_id);
|
||||
let check_mutbl = |mt_a: ty::TypeAndMut<'gcx>,
|
||||
mt_b: ty::TypeAndMut<'gcx>,
|
||||
mk_ptr: &Fn(Ty<'gcx>) -> Ty<'gcx>| {
|
||||
if (mt_a.mutbl, mt_b.mutbl) == (hir::MutImmutable, hir::MutMutable) {
|
||||
infcx.report_mismatched_types(origin,
|
||||
infcx.report_mismatched_types(&cause,
|
||||
mk_ptr(mt_b.ty),
|
||||
target,
|
||||
ty::error::TypeError::Mutability);
|
||||
|
|
@ -397,7 +397,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// Ignore fields that aren't significantly changed
|
||||
if let Ok(ok) = infcx.sub_types(false, origin, b, a) {
|
||||
if let Ok(ok) = infcx.sub_types(false, &cause, b, a) {
|
||||
if ok.obligations.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ pub use rustc::util;
|
|||
|
||||
use dep_graph::DepNode;
|
||||
use hir::map as hir_map;
|
||||
use rustc::infer::{InferOk, TypeOrigin};
|
||||
use rustc::infer::InferOk;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
|
||||
use session::{config, CompileResult};
|
||||
use util::common::time;
|
||||
|
||||
|
|
@ -172,19 +172,19 @@ fn require_c_abi_if_variadic(tcx: TyCtxt,
|
|||
}
|
||||
|
||||
fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
origin: TypeOrigin,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>)
|
||||
-> bool {
|
||||
ccx.tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
|
||||
match infcx.eq_types(false, origin.clone(), expected, actual) {
|
||||
match infcx.eq_types(false, &cause, expected, actual) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
true
|
||||
}
|
||||
Err(err) => {
|
||||
infcx.report_mismatched_types(origin, expected, actual, err);
|
||||
infcx.report_mismatched_types(cause, expected, actual, err);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
|
|||
|
||||
require_same_types(
|
||||
ccx,
|
||||
TypeOrigin::MainFunctionType(main_span),
|
||||
&ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
|
||||
se_ty,
|
||||
main_t);
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
|||
|
||||
require_same_types(
|
||||
ccx,
|
||||
TypeOrigin::StartFunctionType(start_span),
|
||||
&ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
|
||||
se_ty,
|
||||
start_t);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue