Skip to content

Commit c7df1f5

Browse files
committed
Auto merge of #54453 - nikomatsakis:nll-issue-53121-shred-outlives, r=pnkfelix
rework how we handle outlives relationships When we encounter an outlives relationship involving a projection, we use to over-constrain in some cases with region constraints. We also used to evaluate whether the where-clauses in the environment might apply **before** running inference. We now avoid doing both of those things: - If there are where-clauses in the environment that might be useful, we add no constraints. - After inference is done, we check if we wound up inferring values compatible with the where-clause, and make use of them if so. I realize now that this PR includes some meandering commits and refactorings from when I expected to go in a different direction. If desired, I could try to remove some of those. Fixes #53121 Fixes #53789 r? @pnkfelix
2 parents 6846f22 + f23fd4b commit c7df1f5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2573
-1603
lines changed

src/librustc/infer/error_reporting/mod.rs

+73-76
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,22 @@
5555
//! ported to this system, and which relies on string concatenation at the
5656
//! time of error detection.
5757
58-
use infer;
59-
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
60-
use super::region_constraints::GenericKind;
6158
use super::lexical_region_resolve::RegionResolutionError;
59+
use super::region_constraints::GenericKind;
60+
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
61+
use infer::{self, SuppressRegionErrors};
6262

63-
use std::{cmp, fmt};
63+
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
6464
use hir;
65-
use hir::Node;
6665
use hir::def_id::DefId;
66+
use hir::Node;
6767
use middle::region;
68-
use traits::{ObligationCause, ObligationCauseCode};
69-
use ty::{self, subst::Subst, Region, Ty, TyCtxt, TypeFoldable, TyKind};
70-
use ty::error::TypeError;
71-
use session::config::BorrowckMode;
68+
use std::{cmp, fmt};
7269
use syntax::ast::DUMMY_NODE_ID;
7370
use syntax_pos::{Pos, Span};
74-
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
71+
use traits::{ObligationCause, ObligationCauseCode};
72+
use ty::error::TypeError;
73+
use ty::{self, subst::Subst, Region, Ty, TyCtxt, TyKind, TypeFoldable};
7574

7675
mod note;
7776

@@ -153,8 +152,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
153152
}
154153

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

177175
fn msg_span_from_free_region(self, region: ty::Region<'tcx>) -> (String, Option<Span>) {
178176
match *region {
179-
ty::ReEarlyBound(_) | ty::ReFree(_) => {
177+
ty::ReEarlyBound(_) | ty::ReFree(_) => {
180178
self.msg_span_from_early_bound_and_free_regions(region)
181-
},
179+
}
182180
ty::ReStatic => ("the static lifetime".to_owned(), None),
183181
_ => bug!("{:?}", region),
184182
}
@@ -197,25 +195,28 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
197195
Some(Node::Item(it)) => Self::item_scope_tag(&it),
198196
Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it),
199197
Some(Node::ImplItem(it)) => Self::impl_item_scope_tag(&it),
200-
_ => unreachable!()
198+
_ => unreachable!(),
201199
};
202200
let (prefix, span) = match *region {
203201
ty::ReEarlyBound(ref br) => {
204202
let mut sp = cm.def_span(self.hir.span(node));
205-
if let Some(param) = self.hir.get_generics(scope).and_then(|generics| {
206-
generics.get_named(&br.name)
207-
}) {
203+
if let Some(param) = self.hir
204+
.get_generics(scope)
205+
.and_then(|generics| generics.get_named(&br.name))
206+
{
208207
sp = param.span;
209208
}
210209
(format!("the lifetime {} as defined on", br.name), sp)
211210
}
212211
ty::ReFree(ty::FreeRegion {
213-
bound_region: ty::BoundRegion::BrNamed(_, ref name), ..
212+
bound_region: ty::BoundRegion::BrNamed(_, ref name),
213+
..
214214
}) => {
215215
let mut sp = cm.def_span(self.hir.span(node));
216-
if let Some(param) = self.hir.get_generics(scope).and_then(|generics| {
217-
generics.get_named(&name)
218-
}) {
216+
if let Some(param) = self.hir
217+
.get_generics(scope)
218+
.and_then(|generics| generics.get_named(&name))
219+
{
219220
sp = param.span;
220221
}
221222
(format!("the lifetime {} as defined on", name), sp)
@@ -278,9 +279,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
278279
fn impl_item_scope_tag(item: &hir::ImplItem) -> &'static str {
279280
match item.node {
280281
hir::ImplItemKind::Method(..) => "method body",
281-
hir::ImplItemKind::Const(..) |
282-
hir::ImplItemKind::Existential(..) |
283-
hir::ImplItemKind::Type(..) => "associated item",
282+
hir::ImplItemKind::Const(..)
283+
| hir::ImplItemKind::Existential(..)
284+
| hir::ImplItemKind::Type(..) => "associated item",
284285
}
285286
}
286287

@@ -298,20 +299,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
298299
&self,
299300
region_scope_tree: &region::ScopeTree,
300301
errors: &Vec<RegionResolutionError<'tcx>>,
301-
will_later_be_reported_by_nll: bool,
302+
suppress: SuppressRegionErrors,
302303
) {
303-
debug!("report_region_errors(): {} errors to start", errors.len());
304-
305-
// If the errors will later be reported by NLL, choose wether to display them or not based
306-
// on the borrowck mode
307-
if will_later_be_reported_by_nll {
308-
match self.tcx.borrowck_mode() {
309-
// If we're on AST or Migrate mode, report AST region errors
310-
BorrowckMode::Ast | BorrowckMode::Migrate => {},
311-
// If we're on MIR or Compare mode, don't report AST region errors as they should
312-
// be reported by NLL
313-
BorrowckMode::Compare | BorrowckMode::Mir => return,
314-
}
304+
debug!(
305+
"report_region_errors(): {} errors to start, suppress = {:?}",
306+
errors.len(),
307+
suppress
308+
);
309+
310+
if suppress.suppressed() {
311+
return;
315312
}
316313

317314
// try to pre-process the errors, which will group some of them
@@ -482,17 +479,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
482479
} else {
483480
err.span_label(arm_span, msg);
484481
}
485-
},
486-
hir::MatchSource::TryDesugar => { // Issue #51632
482+
}
483+
hir::MatchSource::TryDesugar => {
484+
// Issue #51632
487485
if let Ok(try_snippet) = self.tcx.sess.source_map().span_to_snippet(arm_span) {
488486
err.span_suggestion_with_applicability(
489487
arm_span,
490488
"try wrapping with a success variant",
491489
format!("Ok({})", try_snippet),
492-
Applicability::MachineApplicable
490+
Applicability::MachineApplicable,
493491
);
494492
}
495-
},
493+
}
496494
_ => {
497495
let msg = "match arm with an incompatible type";
498496
if self.tcx.sess.source_map().is_multiline(arm_span) {
@@ -641,16 +639,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
641639
fn strip_generic_default_params(
642640
&self,
643641
def_id: DefId,
644-
substs: &ty::subst::Substs<'tcx>
642+
substs: &ty::subst::Substs<'tcx>,
645643
) -> &'tcx ty::subst::Substs<'tcx> {
646644
let generics = self.tcx.generics_of(def_id);
647645
let mut num_supplied_defaults = 0;
648-
let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind {
649-
ty::GenericParamDefKind::Lifetime => None,
650-
ty::GenericParamDefKind::Type { has_default, .. } => {
651-
Some((param.def_id, has_default))
652-
}
653-
}).peekable();
646+
let mut type_params = generics
647+
.params
648+
.iter()
649+
.rev()
650+
.filter_map(|param| match param.kind {
651+
ty::GenericParamDefKind::Lifetime => None,
652+
ty::GenericParamDefKind::Type { has_default, .. } => {
653+
Some((param.def_id, has_default))
654+
}
655+
})
656+
.peekable();
654657
let has_default = {
655658
let has_default = type_params.peek().map(|(_, has_default)| has_default);
656659
*has_default.unwrap_or(&false)
@@ -684,10 +687,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
684687
| (&ty::Infer(ty::InferTy::IntVar(_)), &ty::Infer(ty::InferTy::IntVar(_)))
685688
| (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
686689
| (&ty::Infer(ty::InferTy::FloatVar(_)), &ty::Float(_))
687-
| (
688-
&ty::Infer(ty::InferTy::FloatVar(_)),
689-
&ty::Infer(ty::InferTy::FloatVar(_)),
690-
) => true,
690+
| (&ty::Infer(ty::InferTy::FloatVar(_)), &ty::Infer(ty::InferTy::FloatVar(_))) => {
691+
true
692+
}
691693
_ => false,
692694
}
693695
}
@@ -703,11 +705,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
703705
"&{}{}{}",
704706
r,
705707
if r == "" { "" } else { " " },
706-
if mutbl == hir::MutMutable {
707-
"mut "
708-
} else {
709-
""
710-
}
708+
if mutbl == hir::MutMutable { "mut " } else { "" }
711709
));
712710
s.push_normal(ty.to_string());
713711
}
@@ -738,9 +736,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
738736
let common_len = cmp::min(len1, len2);
739737
let remainder1: Vec<_> = sub1.types().skip(common_len).collect();
740738
let remainder2: Vec<_> = sub2.types().skip(common_len).collect();
741-
let common_default_params =
742-
remainder1.iter().rev().zip(remainder2.iter().rev())
743-
.filter(|(a, b)| a == b).count();
739+
let common_default_params = remainder1
740+
.iter()
741+
.rev()
742+
.zip(remainder2.iter().rev())
743+
.filter(|(a, b)| a == b)
744+
.count();
744745
let len = sub1.len() - common_default_params;
745746

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

868869
// When encountering &T != &mut T, highlight only the borrow
869-
(&ty::Ref(r1, ref_ty1, mutbl1),
870-
&ty::Ref(r2, ref_ty2, mutbl2)) if equals(&ref_ty1, &ref_ty2) => {
870+
(&ty::Ref(r1, ref_ty1, mutbl1), &ty::Ref(r2, ref_ty2, mutbl2))
871+
if equals(&ref_ty1, &ref_ty2) =>
872+
{
871873
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
872874
push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0);
873875
push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1);
@@ -1068,11 +1070,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10681070
bound_kind: GenericKind<'tcx>,
10691071
sub: Region<'tcx>,
10701072
) {
1071-
self.construct_generic_bound_failure(region_scope_tree,
1072-
span,
1073-
origin,
1074-
bound_kind,
1075-
sub)
1073+
self.construct_generic_bound_failure(region_scope_tree, span, origin, bound_kind, sub)
10761074
.emit()
10771075
}
10781076

@@ -1083,8 +1081,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10831081
origin: Option<SubregionOrigin<'tcx>>,
10841082
bound_kind: GenericKind<'tcx>,
10851083
sub: Region<'tcx>,
1086-
) -> DiagnosticBuilder<'a>
1087-
{
1084+
) -> DiagnosticBuilder<'a> {
10881085
// Attempt to obtain the span of the parameter so we can
10891086
// suggest adding an explicit lifetime bound to it.
10901087
let type_param_span = match (self.in_progress_tables, bound_kind) {
@@ -1161,8 +1158,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11611158
let tail = if has_lifetimes { " + " } else { "" };
11621159
let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
11631160
err.span_suggestion_short_with_applicability(
1164-
sp, consider, suggestion,
1165-
Applicability::MaybeIncorrect // Issue #41966
1161+
sp,
1162+
consider,
1163+
suggestion,
1164+
Applicability::MaybeIncorrect, // Issue #41966
11661165
);
11671166
} else {
11681167
err.help(consider);
@@ -1358,12 +1357,10 @@ impl<'tcx> ObligationCause<'tcx> {
13581357
match self.code {
13591358
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
13601359
MatchExpressionArm { source, .. } => Error0308(match source {
1361-
hir::MatchSource::IfLetDesugar { .. } => {
1362-
"`if let` arms have incompatible types"
1363-
},
1360+
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types",
13641361
hir::MatchSource::TryDesugar => {
13651362
"try expression alternatives have incompatible types"
1366-
},
1363+
}
13671364
_ => "match arms have incompatible types",
13681365
}),
13691366
IfExpression => Error0308("if and else have incompatible types"),

0 commit comments

Comments
 (0)