Skip to content

Commit 9ff30a7

Browse files
committed
Auto merge of #67464 - Centril:rollup-j3mkl1m, r=Centril
Rollup of 6 pull requests Successful merges: - #67130 (Const prop should finish propagation into user defined variables) - #67163 (Split up ptr/mod.rs in libcore...) - #67314 (Don't suppress move errors for union fields) - #67392 (Fix unresolved type span inside async object) - #67404 (Separate region inference logic from error handling better) - #67428 (`is_binding_pat`: use explicit match & include or-pats in grammar) Failed merges: r? @ghost
2 parents ccd2383 + f465f95 commit 9ff30a7

File tree

18 files changed

+2090
-1828
lines changed

18 files changed

+2090
-1828
lines changed

src/libcore/ptr/const_ptr.rs

+755
Large diffs are not rendered by default.

src/libcore/ptr/mod.rs

+5-1,691
Large diffs are not rendered by default.

src/libcore/ptr/mut_ptr.rs

+925
Large diffs are not rendered by default.

src/librustc/hir/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,16 @@ impl fmt::Display for YieldSource {
18571857
}
18581858
}
18591859

1860+
impl From<GeneratorKind> for YieldSource {
1861+
fn from(kind: GeneratorKind) -> Self {
1862+
match kind {
1863+
// Guess based on the kind of the current generator.
1864+
GeneratorKind::Gen => Self::Yield,
1865+
GeneratorKind::Async(_) => Self::Await,
1866+
}
1867+
}
1868+
}
1869+
18601870
// N.B., if you change this, you'll probably want to change the corresponding
18611871
// type structure in middle/ty.rs as well.
18621872
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]

src/librustc/middle/region.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,7 @@ fn resolve_local<'tcx>(
11731173
/// | VariantName(..., P&, ...)
11741174
/// | [ ..., P&, ... ]
11751175
/// | ( ..., P&, ... )
1176+
/// | ... "|" P& "|" ...
11761177
/// | box P&
11771178
fn is_binding_pat(pat: &hir::Pat) -> bool {
11781179
// Note that the code below looks for *explicit* refs only, that is, it won't
@@ -1212,6 +1213,7 @@ fn resolve_local<'tcx>(
12121213
pats3.iter().any(|p| is_binding_pat(&p))
12131214
}
12141215

1216+
PatKind::Or(ref subpats) |
12151217
PatKind::TupleStruct(_, ref subpats, _) |
12161218
PatKind::Tuple(ref subpats, _) => {
12171219
subpats.iter().any(|p| is_binding_pat(&p))
@@ -1221,7 +1223,13 @@ fn resolve_local<'tcx>(
12211223
is_binding_pat(&subpat)
12221224
}
12231225

1224-
_ => false,
1226+
PatKind::Ref(_, _) |
1227+
PatKind::Binding(hir::BindingAnnotation::Unannotated, ..) |
1228+
PatKind::Binding(hir::BindingAnnotation::Mutable, ..) |
1229+
PatKind::Wild |
1230+
PatKind::Path(_) |
1231+
PatKind::Lit(_) |
1232+
PatKind::Range(_, _, _) => false,
12251233
}
12261234
}
12271235

src/librustc_mir/borrow_check/diagnostics/region_errors.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
//! Error reporting machinery for lifetime errors.
22
33
use rustc::hir::def_id::DefId;
4-
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
5-
use rustc::infer::InferCtxt;
6-
use rustc::infer::NLLRegionVariableOrigin;
7-
use rustc::mir::{ConstraintCategory, Local, Location, Body};
4+
use rustc::infer::{
5+
error_reporting::nice_region_error::NiceRegionError,
6+
InferCtxt, NLLRegionVariableOrigin,
7+
};
8+
use rustc::mir::{
9+
ConstraintCategory, Local, Location, Body,
10+
};
811
use rustc::ty::{self, RegionVid};
912
use rustc_index::vec::IndexVec;
1013
use rustc_errors::DiagnosticBuilder;
@@ -93,6 +96,32 @@ pub struct ErrorConstraintInfo {
9396
}
9497

9598
impl<'tcx> RegionInferenceContext<'tcx> {
99+
/// Converts a region inference variable into a `ty::Region` that
100+
/// we can use for error reporting. If `r` is universally bound,
101+
/// then we use the name that we have on record for it. If `r` is
102+
/// existentially bound, then we check its inferred value and try
103+
/// to find a good name from that. Returns `None` if we can't find
104+
/// one (e.g., this is just some random part of the CFG).
105+
pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
106+
self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
107+
}
108+
109+
/// Returns the [RegionVid] corresponding to the region returned by
110+
/// `to_error_region`.
111+
pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
112+
if self.universal_regions.is_universal_region(r) {
113+
Some(r)
114+
} else {
115+
let r_scc = self.constraint_sccs.scc(r);
116+
let upper_bound = self.universal_upper_bound(r);
117+
if self.scc_values.contains(r_scc, upper_bound) {
118+
self.to_error_region_vid(upper_bound)
119+
} else {
120+
None
121+
}
122+
}
123+
}
124+
96125
/// Tries to find the best constraint to blame for the fact that
97126
/// `R: from_region`, where `R` is some region that meets
98127
/// `target_test`. This works by following the constraint graph,

src/librustc_mir/borrow_check/region_infer/mod.rs

+63-84
Original file line numberDiff line numberDiff line change
@@ -928,32 +928,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
928928
}
929929
}
930930

931-
/// Converts a region inference variable into a `ty::Region` that
932-
/// we can use for error reporting. If `r` is universally bound,
933-
/// then we use the name that we have on record for it. If `r` is
934-
/// existentially bound, then we check its inferred value and try
935-
/// to find a good name from that. Returns `None` if we can't find
936-
/// one (e.g., this is just some random part of the CFG).
937-
pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
938-
self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
939-
}
940-
941-
/// Returns the [RegionVid] corresponding to the region returned by
942-
/// `to_error_region`.
943-
pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
944-
if self.universal_regions.is_universal_region(r) {
945-
Some(r)
946-
} else {
947-
let r_scc = self.constraint_sccs.scc(r);
948-
let upper_bound = self.universal_upper_bound(r);
949-
if self.scc_values.contains(r_scc, upper_bound) {
950-
self.to_error_region_vid(upper_bound)
951-
} else {
952-
None
953-
}
954-
}
955-
}
956-
957931
/// Invoked when we have some type-test (e.g., `T: 'X`) that we cannot
958932
/// prove to be satisfied. If this is a closure, we will attempt to
959933
/// "promote" this type-test into our `ClosureRegionRequirements` and
@@ -1164,7 +1138,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11641138
/// include the CFG anyhow.
11651139
/// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
11661140
/// a result `'y`.
1167-
fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
1141+
pub (in crate::borrow_check) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
11681142
debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
11691143

11701144
// Find the smallest universal region that contains all other
@@ -1458,19 +1432,34 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14581432
debug!("check_polonius_subset_errors: subset_error longer_fr={:?},\
14591433
shorter_fr={:?}", longer_fr, shorter_fr);
14601434

1461-
self.report_or_propagate_universal_region_error(
1435+
let propagated = self.try_propagate_universal_region_error(
14621436
*longer_fr,
14631437
*shorter_fr,
1464-
infcx,
14651438
body,
1466-
local_names,
1467-
upvars,
1468-
mir_def_id,
14691439
&mut propagated_outlives_requirements,
1470-
&mut outlives_suggestion,
1471-
errors_buffer,
1472-
region_naming,
14731440
);
1441+
if !propagated {
1442+
// If we are not in a context where we can't propagate errors, or we
1443+
// could not shrink `fr` to something smaller, then just report an
1444+
// error.
1445+
//
1446+
// Note: in this case, we use the unapproximated regions to report the
1447+
// error. This gives better error messages in some cases.
1448+
let db = self.report_error(
1449+
body,
1450+
local_names,
1451+
upvars,
1452+
infcx,
1453+
mir_def_id,
1454+
*longer_fr,
1455+
NLLRegionVariableOrigin::FreeRegion,
1456+
*shorter_fr,
1457+
&mut outlives_suggestion,
1458+
region_naming,
1459+
);
1460+
1461+
db.buffer(errors_buffer);
1462+
}
14741463
}
14751464

14761465
// Handle the placeholder errors as usual, until the chalk-rustc-polonius triumvirate has
@@ -1594,48 +1583,59 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15941583
return None;
15951584
}
15961585

1597-
self.report_or_propagate_universal_region_error(
1586+
let propagated = self.try_propagate_universal_region_error(
15981587
longer_fr,
15991588
shorter_fr,
1600-
infcx,
16011589
body,
1602-
local_names,
1603-
upvars,
1604-
mir_def_id,
16051590
propagated_outlives_requirements,
1606-
outlives_suggestion,
1607-
errors_buffer,
1608-
region_naming,
1609-
)
1591+
);
1592+
1593+
if propagated {
1594+
None
1595+
} else {
1596+
// If we are not in a context where we can't propagate errors, or we
1597+
// could not shrink `fr` to something smaller, then just report an
1598+
// error.
1599+
//
1600+
// Note: in this case, we use the unapproximated regions to report the
1601+
// error. This gives better error messages in some cases.
1602+
let db = self.report_error(
1603+
body,
1604+
local_names,
1605+
upvars,
1606+
infcx,
1607+
mir_def_id,
1608+
longer_fr,
1609+
NLLRegionVariableOrigin::FreeRegion,
1610+
shorter_fr,
1611+
outlives_suggestion,
1612+
region_naming,
1613+
);
1614+
1615+
db.buffer(errors_buffer);
1616+
1617+
Some(ErrorReported)
1618+
}
16101619
}
16111620

1612-
fn report_or_propagate_universal_region_error(
1621+
/// Attempt to propagate a region error (e.g. `'a: 'b`) that is not met to a closure's
1622+
/// creator. If we cannot, then the caller should report an error to the user.
1623+
///
1624+
/// Returns `true` if the error was propagated, and `false` otherwise.
1625+
fn try_propagate_universal_region_error(
16131626
&self,
16141627
longer_fr: RegionVid,
16151628
shorter_fr: RegionVid,
1616-
infcx: &InferCtxt<'_, 'tcx>,
16171629
body: &Body<'tcx>,
1618-
local_names: &IndexVec<Local, Option<Symbol>>,
1619-
upvars: &[Upvar],
1620-
mir_def_id: DefId,
16211630
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1622-
outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
1623-
errors_buffer: &mut Vec<Diagnostic>,
1624-
region_naming: &mut RegionErrorNamingCtx,
1625-
) -> Option<ErrorReported> {
1626-
debug!(
1627-
"report_or_propagate_universal_region_error: fr={:?} does not outlive shorter_fr={:?}",
1628-
longer_fr, shorter_fr,
1629-
);
1630-
1631+
) -> bool {
16311632
if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
16321633
// Shrink `longer_fr` until we find a non-local region (if we do).
16331634
// We'll call it `fr-` -- it's ever so slightly smaller than
16341635
// `longer_fr`.
1635-
16361636
if let Some(fr_minus) =
16371637
self.universal_region_relations.non_local_lower_bound(longer_fr) {
1638-
debug!("report_or_propagate_universal_region_error: fr_minus={:?}", fr_minus);
1638+
debug!("try_propagate_universal_region_error: fr_minus={:?}", fr_minus);
16391639

16401640
let blame_span_category =
16411641
self.find_outlives_blame_span(body, longer_fr,
@@ -1648,7 +1648,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16481648
.universal_region_relations
16491649
.non_local_upper_bounds(&shorter_fr);
16501650
debug!(
1651-
"report_or_propagate_universal_region_error: shorter_fr_plus={:?}",
1651+
"try_propagate_universal_region_error: shorter_fr_plus={:?}",
16521652
shorter_fr_plus
16531653
);
16541654
for &&fr in &shorter_fr_plus {
@@ -1660,32 +1660,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16601660
category: blame_span_category.0,
16611661
});
16621662
}
1663-
return None;
1663+
return true;
16641664
}
16651665
}
16661666

1667-
// If we are not in a context where we can't propagate errors, or we
1668-
// could not shrink `fr` to something smaller, then just report an
1669-
// error.
1670-
//
1671-
// Note: in this case, we use the unapproximated regions to report the
1672-
// error. This gives better error messages in some cases.
1673-
let db = self.report_error(
1674-
body,
1675-
local_names,
1676-
upvars,
1677-
infcx,
1678-
mir_def_id,
1679-
longer_fr,
1680-
NLLRegionVariableOrigin::FreeRegion,
1681-
shorter_fr,
1682-
outlives_suggestion,
1683-
region_naming,
1684-
);
1685-
1686-
db.buffer(errors_buffer);
1687-
1688-
Some(ErrorReported)
1667+
false
16891668
}
16901669

16911670
fn check_bound_universal_region(

src/librustc_mir/dataflow/move_paths/builder.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
103103
}
104104
};
105105

106+
// The move path index of the first union that we find. Once this is
107+
// some we stop creating child move paths, since moves from unions
108+
// move the whole thing.
109+
// We continue looking for other move errors though so that moving
110+
// from `*(u.f: &_)` isn't allowed.
111+
let mut union_path = None;
112+
106113
for (i, elem) in place.projection.iter().enumerate() {
107114
let proj_base = &place.projection[..i];
108115
let body = self.builder.body;
@@ -127,9 +134,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
127134
InteriorOfTypeWithDestructor { container_ty: place_ty },
128135
));
129136
}
130-
// move out of union - always move the entire union
131137
ty::Adt(adt, _) if adt.is_union() => {
132-
return Err(MoveError::UnionMove { path: base });
138+
union_path.get_or_insert(base);
133139
}
134140
ty::Slice(_) => {
135141
return Err(MoveError::cannot_move_out_of(
@@ -155,15 +161,22 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
155161
_ => {}
156162
};
157163

158-
base = self.add_move_path(base, elem, |tcx| {
159-
Place {
160-
base: place.base.clone(),
161-
projection: tcx.intern_place_elems(&place.projection[..i+1]),
162-
}
163-
});
164+
if union_path.is_none() {
165+
base = self.add_move_path(base, elem, |tcx| {
166+
Place {
167+
base: place.base.clone(),
168+
projection: tcx.intern_place_elems(&place.projection[..i+1]),
169+
}
170+
});
171+
}
164172
}
165173

166-
Ok(base)
174+
if let Some(base) = union_path {
175+
// Move out of union - always move the entire union.
176+
Err(MoveError::UnionMove { path: base })
177+
} else {
178+
Ok(base)
179+
}
167180
}
168181

169182
fn add_move_path(

0 commit comments

Comments
 (0)