Skip to content
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

rework how we handle outlives relationships #54453

Merged
merged 34 commits into from
Sep 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
80ed62e
regionck: rustfmt
nikomatsakis Sep 12, 2018
1fb4ea9
outlives/env: rustfmt
nikomatsakis Sep 12, 2018
84563da
build up a map of the region-bound pairs for each body-id
nikomatsakis Sep 12, 2018
1830c9e
use a `UnlessNll` flag to consolidate error reporting paths
nikomatsakis Sep 12, 2018
672e071
change `RegionObligation` to store a `SubregionOrigin`
nikomatsakis Sep 12, 2018
d5d2232
auto_trait.rs: rustfmt
nikomatsakis Sep 12, 2018
2f31698
use `RegionBoundPairs` type alias
nikomatsakis Sep 12, 2018
9e305a8
type_check/mod.rs: rustfmt
nikomatsakis Sep 12, 2018
b2e0215
apply `process_registered_region_obligations` at the end of regionck
nikomatsakis Sep 12, 2018
b0e1fec
break out the code that computes VerifyBounds
nikomatsakis Sep 14, 2018
9b63dcc
split out getting the declared bounds from the env versus trait
nikomatsakis Sep 17, 2018
db0e626
introduce a "comparison fn" instead of always use `==`
nikomatsakis Sep 17, 2018
13d579b
introduce the idea of an "approximate match"
nikomatsakis Sep 17, 2018
4b193cb
propagate the `compare_ty` fn further up
nikomatsakis Sep 17, 2018
689b791
use approx. bounds to decide whether to add outlives obligations
nikomatsakis Sep 17, 2018
a4955d1
refactor NLL relate_tys to use Region internally, not RegionVid
nikomatsakis Sep 17, 2018
c6f4513
extract out NLL-specific code from relate-tys into a delegate
nikomatsakis Sep 17, 2018
582a369
encapsulate `infcx` too into the delegate
nikomatsakis Sep 17, 2018
688aaf3
lexical_region_resolve: rustfmt
nikomatsakis Sep 19, 2018
b5469c5
make `normalize` work on any type-foldable
nikomatsakis Sep 19, 2018
85d12e2
remove handling of verify from taintset
nikomatsakis Sep 19, 2018
58fd6fa
change to use impl Trait a bit
nikomatsakis Sep 19, 2018
18b86e9
introduce `VerifyBound::IfEq` (presently unused)
nikomatsakis Sep 19, 2018
7f8c42d
refactor away `AnyRegions` and `AllRegions`
nikomatsakis Sep 19, 2018
dc9317f
use `IfEq` to defer equality comparison around `where` clauses`
nikomatsakis Sep 19, 2018
2392a09
region_infer: rustfmt
nikomatsakis Sep 21, 2018
0f5dae0
switch to use `VerifyBound` instead of `RegionTest`
nikomatsakis Sep 21, 2018
0b4791e
make NLL handle `IfEq` bounds by using SCC normalization
nikomatsakis Sep 21, 2018
a13c9f6
convert from an `UnlessNll` flag to a `SuppressRegionErrors` flag
nikomatsakis Sep 24, 2018
f87189d
update tests and add stderr files
nikomatsakis Sep 24, 2018
ffe87f6
rustfmt `error_reporting/mod.rs` and `dropck.rs`
nikomatsakis Sep 25, 2018
e2deef3
pacify the mercilous tidy.
nikomatsakis Sep 25, 2018
cbaf36a
fix rustc_driver tests
nikomatsakis Sep 25, 2018
f23fd4b
rustc_driver/test.rs: rustfmt
nikomatsakis Sep 25, 2018
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
149 changes: 73 additions & 76 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,22 @@
//! ported to this system, and which relies on string concatenation at the
//! time of error detection.

use infer;
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
use super::region_constraints::GenericKind;
use super::lexical_region_resolve::RegionResolutionError;
use super::region_constraints::GenericKind;
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
use infer::{self, SuppressRegionErrors};

use std::{cmp, fmt};
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use hir;
use hir::Node;
use hir::def_id::DefId;
use hir::Node;
use middle::region;
use traits::{ObligationCause, ObligationCauseCode};
use ty::{self, subst::Subst, Region, Ty, TyCtxt, TypeFoldable, TyKind};
use ty::error::TypeError;
use session::config::BorrowckMode;
use std::{cmp, fmt};
use syntax::ast::DUMMY_NODE_ID;
use syntax_pos::{Pos, Span};
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use traits::{ObligationCause, ObligationCauseCode};
use ty::error::TypeError;
use ty::{self, subst::Subst, Region, Ty, TyCtxt, TyKind, TypeFoldable};

mod note;

Expand Down Expand Up @@ -153,8 +152,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

// We shouldn't encounter an error message with ReClosureBound.
ty::ReCanonical(..) |
ty::ReClosureBound(..) => {
ty::ReCanonical(..) | ty::ReClosureBound(..) => {
bug!("encountered unexpected ReClosureBound: {:?}", region,);
}
};
Expand All @@ -176,9 +174,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

fn msg_span_from_free_region(self, region: ty::Region<'tcx>) -> (String, Option<Span>) {
match *region {
ty::ReEarlyBound(_) | ty::ReFree(_) => {
ty::ReEarlyBound(_) | ty::ReFree(_) => {
self.msg_span_from_early_bound_and_free_regions(region)
},
}
ty::ReStatic => ("the static lifetime".to_owned(), None),
_ => bug!("{:?}", region),
}
Expand All @@ -197,25 +195,28 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
Some(Node::Item(it)) => Self::item_scope_tag(&it),
Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it),
Some(Node::ImplItem(it)) => Self::impl_item_scope_tag(&it),
_ => unreachable!()
_ => unreachable!(),
};
let (prefix, span) = match *region {
ty::ReEarlyBound(ref br) => {
let mut sp = cm.def_span(self.hir.span(node));
if let Some(param) = self.hir.get_generics(scope).and_then(|generics| {
generics.get_named(&br.name)
}) {
if let Some(param) = self.hir
.get_generics(scope)
.and_then(|generics| generics.get_named(&br.name))
{
sp = param.span;
}
(format!("the lifetime {} as defined on", br.name), sp)
}
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegion::BrNamed(_, ref name), ..
bound_region: ty::BoundRegion::BrNamed(_, ref name),
..
}) => {
let mut sp = cm.def_span(self.hir.span(node));
if let Some(param) = self.hir.get_generics(scope).and_then(|generics| {
generics.get_named(&name)
}) {
if let Some(param) = self.hir
.get_generics(scope)
.and_then(|generics| generics.get_named(&name))
{
sp = param.span;
}
(format!("the lifetime {} as defined on", name), sp)
Expand Down Expand Up @@ -278,9 +279,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
fn impl_item_scope_tag(item: &hir::ImplItem) -> &'static str {
match item.node {
hir::ImplItemKind::Method(..) => "method body",
hir::ImplItemKind::Const(..) |
hir::ImplItemKind::Existential(..) |
hir::ImplItemKind::Type(..) => "associated item",
hir::ImplItemKind::Const(..)
| hir::ImplItemKind::Existential(..)
| hir::ImplItemKind::Type(..) => "associated item",
}
}

Expand All @@ -298,20 +299,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
&self,
region_scope_tree: &region::ScopeTree,
errors: &Vec<RegionResolutionError<'tcx>>,
will_later_be_reported_by_nll: bool,
suppress: SuppressRegionErrors,
) {
debug!("report_region_errors(): {} errors to start", errors.len());

// If the errors will later be reported by NLL, choose wether to display them or not based
// on the borrowck mode
if will_later_be_reported_by_nll {
match self.tcx.borrowck_mode() {
// If we're on AST or Migrate mode, report AST region errors
BorrowckMode::Ast | BorrowckMode::Migrate => {},
// If we're on MIR or Compare mode, don't report AST region errors as they should
// be reported by NLL
BorrowckMode::Compare | BorrowckMode::Mir => return,
}
debug!(
"report_region_errors(): {} errors to start, suppress = {:?}",
errors.len(),
suppress
);

if suppress.suppressed() {
return;
}

// try to pre-process the errors, which will group some of them
Expand Down Expand Up @@ -482,17 +479,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} else {
err.span_label(arm_span, msg);
}
},
hir::MatchSource::TryDesugar => { // Issue #51632
}
hir::MatchSource::TryDesugar => {
// Issue #51632
if let Ok(try_snippet) = self.tcx.sess.source_map().span_to_snippet(arm_span) {
err.span_suggestion_with_applicability(
arm_span,
"try wrapping with a success variant",
format!("Ok({})", try_snippet),
Applicability::MachineApplicable
Applicability::MachineApplicable,
);
}
},
}
_ => {
let msg = "match arm with an incompatible type";
if self.tcx.sess.source_map().is_multiline(arm_span) {
Expand Down Expand Up @@ -641,16 +639,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn strip_generic_default_params(
&self,
def_id: DefId,
substs: &ty::subst::Substs<'tcx>
substs: &ty::subst::Substs<'tcx>,
) -> &'tcx ty::subst::Substs<'tcx> {
let generics = self.tcx.generics_of(def_id);
let mut num_supplied_defaults = 0;
let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => {
Some((param.def_id, has_default))
}
}).peekable();
let mut type_params = generics
.params
.iter()
.rev()
.filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => {
Some((param.def_id, has_default))
}
})
.peekable();
let has_default = {
let has_default = type_params.peek().map(|(_, has_default)| has_default);
*has_default.unwrap_or(&false)
Expand Down Expand Up @@ -684,10 +687,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
| (&ty::Infer(ty::InferTy::IntVar(_)), &ty::Infer(ty::InferTy::IntVar(_)))
| (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
| (&ty::Infer(ty::InferTy::FloatVar(_)), &ty::Float(_))
| (
&ty::Infer(ty::InferTy::FloatVar(_)),
&ty::Infer(ty::InferTy::FloatVar(_)),
) => true,
| (&ty::Infer(ty::InferTy::FloatVar(_)), &ty::Infer(ty::InferTy::FloatVar(_))) => {
true
}
_ => false,
}
}
Expand All @@ -703,11 +705,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"&{}{}{}",
r,
if r == "" { "" } else { " " },
if mutbl == hir::MutMutable {
"mut "
} else {
""
}
if mutbl == hir::MutMutable { "mut " } else { "" }
));
s.push_normal(ty.to_string());
}
Expand Down Expand Up @@ -738,9 +736,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let common_len = cmp::min(len1, len2);
let remainder1: Vec<_> = sub1.types().skip(common_len).collect();
let remainder2: Vec<_> = sub2.types().skip(common_len).collect();
let common_default_params =
remainder1.iter().rev().zip(remainder2.iter().rev())
.filter(|(a, b)| a == b).count();
let common_default_params = remainder1
.iter()
.rev()
.zip(remainder2.iter().rev())
.filter(|(a, b)| a == b)
.count();
let len = sub1.len() - common_default_params;

// Only draw `<...>` if there're lifetime/type arguments.
Expand Down Expand Up @@ -866,8 +867,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

// When encountering &T != &mut T, highlight only the borrow
(&ty::Ref(r1, ref_ty1, mutbl1),
&ty::Ref(r2, ref_ty2, mutbl2)) if equals(&ref_ty1, &ref_ty2) => {
(&ty::Ref(r1, ref_ty1, mutbl1), &ty::Ref(r2, ref_ty2, mutbl2))
if equals(&ref_ty1, &ref_ty2) =>
{
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0);
push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1);
Expand Down Expand Up @@ -1068,11 +1070,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>,
) {
self.construct_generic_bound_failure(region_scope_tree,
span,
origin,
bound_kind,
sub)
self.construct_generic_bound_failure(region_scope_tree, span, origin, bound_kind, sub)
.emit()
}

Expand All @@ -1083,8 +1081,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
origin: Option<SubregionOrigin<'tcx>>,
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>,
) -> DiagnosticBuilder<'a>
{
) -> DiagnosticBuilder<'a> {
// Attempt to obtain the span of the parameter so we can
// suggest adding an explicit lifetime bound to it.
let type_param_span = match (self.in_progress_tables, bound_kind) {
Expand Down Expand Up @@ -1161,8 +1158,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let tail = if has_lifetimes { " + " } else { "" };
let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
err.span_suggestion_short_with_applicability(
sp, consider, suggestion,
Applicability::MaybeIncorrect // Issue #41966
sp,
consider,
suggestion,
Applicability::MaybeIncorrect, // Issue #41966
);
} else {
err.help(consider);
Expand Down Expand Up @@ -1358,12 +1357,10 @@ impl<'tcx> ObligationCause<'tcx> {
match self.code {
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
MatchExpressionArm { source, .. } => Error0308(match source {
hir::MatchSource::IfLetDesugar { .. } => {
"`if let` arms have incompatible types"
},
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types",
hir::MatchSource::TryDesugar => {
"try expression alternatives have incompatible types"
},
}
_ => "match arms have incompatible types",
}),
IfExpression => Error0308("if and else have incompatible types"),
Expand Down
Loading