Skip to content

Refactoring towards region obligation #37717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 17, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
@@ -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
75 changes: 59 additions & 16 deletions src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
@@ -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",
}
}
}

14 changes: 7 additions & 7 deletions src/librustc/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
@@ -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);
}
Loading