Skip to content

Commit 2bd16f3

Browse files
committed
Improve opaque type lifetime errors
* Use better span for member constraint errors * Avoid a bad suggestion * Don't report member constraint errors if we have other universal region errors.
1 parent 5cfa7d1 commit 2bd16f3

File tree

6 files changed

+41
-31
lines changed

6 files changed

+41
-31
lines changed

src/librustc/infer/error_reporting/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -405,17 +405,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
405405
}
406406

407407
RegionResolutionError::MemberConstraintFailure {
408-
opaque_type_def_id,
409408
hidden_ty,
410409
member_region,
411-
span: _,
412-
choice_regions: _,
410+
span,
413411
} => {
414412
let hidden_ty = self.resolve_vars_if_possible(&hidden_ty);
415413
opaque_types::unexpected_hidden_region_diagnostic(
416414
self.tcx,
417415
Some(region_scope_tree),
418-
opaque_type_def_id,
416+
span,
419417
hidden_ty,
420418
member_region,
421419
)

src/librustc/infer/lexical_region_resolve/mod.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_data_structures::fx::FxHashSet;
1818
use rustc_data_structures::graph::implementation::{
1919
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
2020
};
21-
use rustc_hir::def_id::DefId;
2221
use rustc_index::vec::{Idx, IndexVec};
2322
use rustc_span::Span;
2423
use std::fmt;
@@ -95,13 +94,7 @@ pub enum RegionResolutionError<'tcx> {
9594
/// Indicates a failure of a `MemberConstraint`. These arise during
9695
/// impl trait processing explicitly -- basically, the impl trait's hidden type
9796
/// included some region that it was not supposed to.
98-
MemberConstraintFailure {
99-
span: Span,
100-
opaque_type_def_id: DefId,
101-
hidden_ty: Ty<'tcx>,
102-
member_region: Region<'tcx>,
103-
choice_regions: Vec<Region<'tcx>>,
104-
},
97+
MemberConstraintFailure { span: Span, hidden_ty: Ty<'tcx>, member_region: Region<'tcx> },
10598
}
10699

107100
struct RegionAndOrigin<'tcx> {
@@ -656,10 +649,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
656649
let span = self.tcx().def_span(member_constraint.opaque_type_def_id);
657650
errors.push(RegionResolutionError::MemberConstraintFailure {
658651
span,
659-
opaque_type_def_id: member_constraint.opaque_type_def_id,
660652
hidden_ty: member_constraint.hidden_ty,
661653
member_region,
662-
choice_regions: choice_regions.collect(),
663654
});
664655
}
665656
}

src/librustc/infer/opaque_types/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -595,11 +595,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
595595
pub fn unexpected_hidden_region_diagnostic(
596596
tcx: TyCtxt<'tcx>,
597597
region_scope_tree: Option<&region::ScopeTree>,
598-
opaque_type_def_id: DefId,
598+
span: Span,
599599
hidden_ty: Ty<'tcx>,
600600
hidden_region: ty::Region<'tcx>,
601601
) -> DiagnosticBuilder<'tcx> {
602-
let span = tcx.def_span(opaque_type_def_id);
603602
let mut err = struct_span_err!(
604603
tcx.sess,
605604
span,
@@ -851,7 +850,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
851850
unexpected_hidden_region_diagnostic(
852851
self.tcx,
853852
None,
854-
self.opaque_type_def_id,
853+
self.tcx.def_span(self.opaque_type_def_id),
855854
hidden_ty,
856855
r,
857856
)

src/librustc_mir/borrow_check/diagnostics/region_errors.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc::infer::{
66
use rustc::mir::ConstraintCategory;
77
use rustc::ty::{self, RegionVid, Ty};
88
use rustc_errors::{Applicability, DiagnosticBuilder};
9-
use rustc_hir::def_id::DefId;
109
use rustc_span::symbol::kw;
1110
use rustc_span::Span;
1211

@@ -58,8 +57,8 @@ crate enum RegionErrorKind<'tcx> {
5857

5958
/// An unexpected hidden region for an opaque type.
6059
UnexpectedHiddenRegion {
61-
/// The def id of the opaque type.
62-
opaque_type_def_id: DefId,
60+
/// The span for the member constraint.
61+
span: Span,
6362
/// The hidden type.
6463
hidden_ty: Ty<'tcx>,
6564
/// The unexpected region.
@@ -194,18 +193,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
194193
}
195194
}
196195

197-
RegionErrorKind::UnexpectedHiddenRegion {
198-
opaque_type_def_id,
199-
hidden_ty,
200-
member_region,
201-
} => {
196+
RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => {
202197
let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
198+
let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
199+
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
203200
opaque_types::unexpected_hidden_region_diagnostic(
204201
self.infcx.tcx,
205202
Some(region_scope_tree),
206-
opaque_type_def_id,
207-
hidden_ty,
208-
member_region,
203+
span,
204+
named_ty,
205+
named_region,
209206
)
210207
.buffer(&mut self.errors_buffer);
211208
}
@@ -588,6 +585,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
588585
{
589586
found = true;
590587
break;
588+
} else {
589+
// If there's already a lifetime bound, don't
590+
// suggest anything.
591+
return;
591592
}
592593
}
593594
}

src/librustc_mir/borrow_check/region_infer/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
511511
self.check_universal_regions(body, outlives_requirements.as_mut(), &mut errors_buffer);
512512
}
513513

514-
self.check_member_constraints(infcx, &mut errors_buffer);
514+
if errors_buffer.is_empty() {
515+
self.check_member_constraints(infcx, &mut errors_buffer);
516+
}
515517

516518
let outlives_requirements = outlives_requirements.unwrap_or(vec![]);
517519

@@ -1604,7 +1606,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16041606
// If not, report an error.
16051607
let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid));
16061608
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
1607-
opaque_type_def_id: m_c.opaque_type_def_id,
1609+
span: m_c.definition_span,
16081610
hidden_ty: m_c.hidden_ty,
16091611
member_region,
16101612
});

src/librustc_mir/borrow_check/region_infer/opaque_types.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc::infer::InferCtxt;
2-
use rustc::ty;
2+
use rustc::ty::{self, TyCtxt, TypeFoldable};
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_hir::def_id::DefId;
55
use rustc_span::Span;
@@ -119,4 +119,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
119119
})
120120
.collect()
121121
}
122+
123+
/// Map the regions in the type to named regions. This is similar to what
124+
/// `infer_opaque_types` does, but can infer any universal region, not only
125+
/// ones from the substs for the opaque type. It also doesn't double check
126+
/// that the regions produced are in fact equal to the named region they are
127+
/// replaced with. This is fine because this function is only to improve the
128+
/// region names in error messages.
129+
pub(in crate::borrow_check) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
130+
where
131+
T: TypeFoldable<'tcx>,
132+
{
133+
tcx.fold_regions(&ty, &mut false, |region, _| match *region {
134+
ty::ReVar(vid) => {
135+
let upper_bound = self.universal_upper_bound(vid);
136+
self.definitions[upper_bound].external_name.unwrap_or(region)
137+
}
138+
_ => region,
139+
})
140+
}
122141
}

0 commit comments

Comments
 (0)