Skip to content

Commit 4b8b0e8

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 f0ca28f commit 4b8b0e8

File tree

7 files changed

+42
-31
lines changed

7 files changed

+42
-31
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,17 +377,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
377377
}
378378

379379
RegionResolutionError::MemberConstraintFailure {
380-
opaque_type_def_id,
381380
hidden_ty,
382381
member_region,
383-
span: _,
384-
choice_regions: _,
382+
span,
385383
} => {
386384
let hidden_ty = self.resolve_vars_if_possible(&hidden_ty);
387385
opaque_types::unexpected_hidden_region_diagnostic(
388386
self.tcx,
389387
Some(region_scope_tree),
390-
opaque_type_def_id,
388+
span,
391389
hidden_ty,
392390
member_region,
393391
)

src/librustc/infer/lexical_region_resolve/mod.rs

Lines changed: 1 addition & 10 deletions
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::bit_set::BitSet;
2322
use rustc_index::vec::{Idx, IndexVec};
2423
use rustc_span::Span;
@@ -86,13 +85,7 @@ pub enum RegionResolutionError<'tcx> {
8685
/// Indicates a failure of a `MemberConstraint`. These arise during
8786
/// impl trait processing explicitly -- basically, the impl trait's hidden type
8887
/// included some region that it was not supposed to.
89-
MemberConstraintFailure {
90-
span: Span,
91-
opaque_type_def_id: DefId,
92-
hidden_ty: Ty<'tcx>,
93-
member_region: Region<'tcx>,
94-
choice_regions: Vec<Region<'tcx>>,
95-
},
88+
MemberConstraintFailure { span: Span, hidden_ty: Ty<'tcx>, member_region: Region<'tcx> },
9689
}
9790

9891
struct RegionAndOrigin<'tcx> {
@@ -584,10 +577,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
584577
let span = self.tcx().def_span(member_constraint.opaque_type_def_id);
585578
errors.push(RegionResolutionError::MemberConstraintFailure {
586579
span,
587-
opaque_type_def_id: member_constraint.opaque_type_def_id,
588580
hidden_ty: member_constraint.hidden_ty,
589581
member_region,
590-
choice_regions: choice_regions.collect(),
591582
});
592583
}
593584
}

src/librustc/infer/opaque_types/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,11 +597,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
597597
pub fn unexpected_hidden_region_diagnostic(
598598
tcx: TyCtxt<'tcx>,
599599
region_scope_tree: Option<&region::ScopeTree>,
600-
opaque_type_def_id: DefId,
600+
span: Span,
601601
hidden_ty: Ty<'tcx>,
602602
hidden_region: ty::Region<'tcx>,
603603
) -> DiagnosticBuilder<'tcx> {
604-
let span = tcx.def_span(opaque_type_def_id);
605604
let mut err = struct_span_err!(
606605
tcx.sess,
607606
span,
@@ -848,7 +847,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
848847
unexpected_hidden_region_diagnostic(
849848
self.tcx,
850849
None,
851-
self.opaque_type_def_id,
850+
self.tcx.def_span(self.opaque_type_def_id),
852851
hidden_ty,
853852
r,
854853
)

src/librustc_mir/borrow_check/diagnostics/region_errors.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc::infer::{
77
use rustc::mir::{Body, ConstraintCategory, Location};
88
use rustc::ty::{self, RegionVid, Ty};
99
use rustc_errors::{Applicability, DiagnosticBuilder};
10-
use rustc_hir::def_id::DefId;
1110
use rustc_index::vec::IndexVec;
1211
use rustc_span::symbol::kw;
1312
use rustc_span::Span;
@@ -82,8 +81,8 @@ crate enum RegionErrorKind<'tcx> {
8281

8382
/// An unexpected hidden region for an opaque type.
8483
UnexpectedHiddenRegion {
85-
/// The def id of the opaque type.
86-
opaque_type_def_id: DefId,
84+
/// The span for the member constraint.
85+
span: Span,
8786
/// The hidden type.
8887
hidden_ty: Ty<'tcx>,
8988
/// The unexpected region.
@@ -784,6 +783,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
784783
{
785784
found = true;
786785
break;
786+
} else {
787+
// If there's already a lifetime bound, don't
788+
// suggest anything.
789+
return;
787790
}
788791
}
789792
}

src/librustc_mir/borrow_check/mod.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,18 +1528,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15281528
.buffer(&mut self.errors_buffer);
15291529
}
15301530

1531-
RegionErrorKind::UnexpectedHiddenRegion {
1532-
opaque_type_def_id,
1533-
hidden_ty,
1534-
member_region,
1535-
} => {
1531+
RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => {
15361532
let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
1533+
let named_ty = self.nonlexical_regioncx.name_regions(self.infcx.tcx, hidden_ty);
1534+
let named_region =
1535+
self.nonlexical_regioncx.name_regions(self.infcx.tcx, member_region);
15371536
opaque_types::unexpected_hidden_region_diagnostic(
15381537
self.infcx.tcx,
15391538
Some(region_scope_tree),
1540-
opaque_type_def_id,
1541-
hidden_ty,
1542-
member_region,
1539+
span,
1540+
named_ty,
1541+
named_region,
15431542
)
15441543
.buffer(&mut self.errors_buffer);
15451544
}

src/librustc_mir/borrow_check/region_infer/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
504504
self.check_universal_regions(body, outlives_requirements.as_mut(), &mut errors_buffer);
505505
}
506506

507-
self.check_member_constraints(infcx, &mut errors_buffer);
507+
if errors_buffer.is_empty() {
508+
self.check_member_constraints(infcx, &mut errors_buffer);
509+
}
508510

509511
let outlives_requirements = outlives_requirements.unwrap_or(vec![]);
510512

@@ -1623,7 +1625,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16231625
// If not, report an error.
16241626
let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid));
16251627
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
1626-
opaque_type_def_id: m_c.opaque_type_def_id,
1628+
span: m_c.definition_span,
16271629
hidden_ty: m_c.hidden_ty,
16281630
member_region,
16291631
});

src/librustc_mir/borrow_check/region_infer/opaque_types.rs

Lines changed: 20 additions & 1 deletion
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)