Skip to content

Commit 53eb9e5

Browse files
committed
add Locations::All as a concept
In particular, type annotations given by the user must hold at all points in the program. This doesn't affect current analysis but will affect fact generation later.
1 parent 81905a1 commit 53eb9e5

File tree

4 files changed

+74
-50
lines changed

4 files changed

+74
-50
lines changed

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ mod universal_regions;
3838
use self::region_infer::RegionInferenceContext;
3939
use self::universal_regions::UniversalRegions;
4040

41-
4241
/// Rewrites the regions in the MIR to use NLL variables, also
4342
/// scraping out the set of universal regions (e.g., region parameters)
4443
/// declared on the function. That set will need to be given to

src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use rustc::mir::Mir;
11+
use rustc::mir::{Location, Mir};
1212
use rustc::infer::region_constraints::Constraint;
1313
use rustc::infer::region_constraints::RegionConstraintData;
1414
use rustc::infer::region_constraints::{Verify, VerifyBound};
@@ -65,7 +65,11 @@ impl<'cx, 'tcx> SubtypeConstraintGenerator<'cx, 'tcx> {
6565
givens,
6666
} = data;
6767

68-
let span = self.mir.source_info(locations.from_location).span;
68+
let span = self.mir
69+
.source_info(locations.from_location().unwrap_or(Location::START))
70+
.span;
71+
72+
let at_location = locations.at_location().unwrap_or(Location::START);
6973

7074
for constraint in constraints.keys() {
7175
debug!("generate: constraint: {:?}", constraint);
@@ -83,8 +87,7 @@ impl<'cx, 'tcx> SubtypeConstraintGenerator<'cx, 'tcx> {
8387
// reverse direction, because `regioncx` talks about
8488
// "outlives" (`>=`) whereas the region constraints
8589
// talk about `<=`.
86-
self.regioncx
87-
.add_outlives(span, b_vid, a_vid, locations.at_location);
90+
self.regioncx.add_outlives(span, b_vid, a_vid, at_location);
8891
}
8992

9093
for verify in verifys {
@@ -109,7 +112,7 @@ impl<'cx, 'tcx> SubtypeConstraintGenerator<'cx, 'tcx> {
109112

110113
let lower_bound = self.to_region_vid(verify.region);
111114

112-
let point = locations.at_location;
115+
let point = locations.at_location().unwrap_or(Location::START);
113116

114117
let test = self.verify_bound_to_region_test(&verify.bound);
115118

@@ -149,14 +152,6 @@ impl<'cx, 'tcx> SubtypeConstraintGenerator<'cx, 'tcx> {
149152
}
150153

151154
fn to_region_vid(&self, r: ty::Region<'tcx>) -> ty::RegionVid {
152-
// Every region that we see in the constraints came from the
153-
// MIR or from the parameter environment. If the former, it
154-
// will be a region variable. If the latter, it will be in
155-
// the set of universal regions *somewhere*.
156-
if let ty::ReVar(vid) = r {
157-
*vid
158-
} else {
159-
self.regioncx.to_region_vid(r)
160-
}
155+
self.regioncx.to_region_vid(r)
161156
}
162157
}

src/librustc_mir/borrow_check/nll/type_check/input_output.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::traits::PredicateObligations;
2929

3030
use rustc_data_structures::indexed_vec::Idx;
3131

32-
use super::{AtLocation, TypeChecker};
32+
use super::{Locations, TypeChecker};
3333

3434
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
3535
pub(super) fn equate_inputs_and_outputs(
@@ -47,26 +47,21 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
4747
} = universal_regions;
4848
let infcx = self.infcx;
4949

50-
let start_position = Location {
51-
block: START_BLOCK,
52-
statement_index: 0,
53-
};
54-
5550
// Equate expected input tys with those in the MIR.
5651
let argument_locals = (1..).map(Local::new);
5752
for (&unnormalized_input_ty, local) in unnormalized_input_tys.iter().zip(argument_locals) {
58-
let input_ty = self.normalize(&unnormalized_input_ty, start_position);
53+
let input_ty = self.normalize(&unnormalized_input_ty, Locations::All);
5954
let mir_input_ty = mir.local_decls[local].ty;
60-
self.equate_normalized_input_or_output(start_position, input_ty, mir_input_ty);
55+
self.equate_normalized_input_or_output(input_ty, mir_input_ty);
6156
}
6257

6358
assert!(
6459
mir.yield_ty.is_some() && universal_regions.yield_ty.is_some() ||
6560
mir.yield_ty.is_none() && universal_regions.yield_ty.is_none()
66-
);
61+
);
6762
if let Some(mir_yield_ty) = mir.yield_ty {
6863
let ur_yield_ty = universal_regions.yield_ty.unwrap();
69-
self.equate_normalized_input_or_output(start_position, ur_yield_ty, mir_yield_ty);
64+
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty);
7065
}
7166

7267
// Return types are a bit more complex. They may contain existential `impl Trait`
@@ -75,13 +70,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
7570
"equate_inputs_and_outputs: unnormalized_output_ty={:?}",
7671
unnormalized_output_ty
7772
);
78-
let output_ty = self.normalize(&unnormalized_output_ty, start_position);
73+
let output_ty = self.normalize(&unnormalized_output_ty, Locations::All);
7974
debug!(
8075
"equate_inputs_and_outputs: normalized output_ty={:?}",
8176
output_ty
8277
);
8378
let mir_output_ty = mir.local_decls[RETURN_PLACE].ty;
84-
let anon_type_map = self.fully_perform_op(start_position.at_self(), |cx| {
79+
let anon_type_map = self.fully_perform_op(Locations::All, |cx| {
8580
let mut obligations = ObligationAccumulator::default();
8681

8782
let (output_ty, anon_type_map) = obligations.add(infcx.instantiate_anon_types(
@@ -148,7 +143,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
148143
// prove that `T: Iterator` where `T` is the type we
149144
// instantiated it with).
150145
if let Some(anon_type_map) = anon_type_map {
151-
self.fully_perform_op(start_position.at_self(), |_cx| {
146+
self.fully_perform_op(Locations::All, |_cx| {
152147
infcx.constrain_anon_types(&anon_type_map, universal_regions);
153148
Ok(InferOk {
154149
value: (),
@@ -158,13 +153,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
158153
}
159154
}
160155

161-
fn equate_normalized_input_or_output(&mut self, location: Location, a: Ty<'tcx>, b: Ty<'tcx>) {
156+
fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
162157
debug!("equate_normalized_input_or_output(a={:?}, b={:?})", a, b);
163158

164-
if let Err(terr) = self.eq_types(a, b, location.at_self()) {
159+
if let Err(terr) = self.eq_types(a, b, Locations::All) {
165160
span_mirbug!(
166161
self,
167-
location,
162+
Location::START,
168163
"equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`",
169164
a,
170165
b,

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -619,16 +619,35 @@ pub struct OutlivesSet<'tcx> {
619619
}
620620

621621
#[derive(Copy, Clone, Debug)]
622-
pub struct Locations {
623-
/// The location in the MIR that generated these constraints.
624-
/// This is intended for error reporting and diagnosis; the
625-
/// constraints may *take effect* at a distinct spot.
626-
pub from_location: Location,
627-
628-
/// The constraints must be met at this location. In terms of the
629-
/// NLL RFC, when you have a constraint `R1: R2 @ P`, this field
630-
/// is the `P` value.
631-
pub at_location: Location,
622+
pub enum Locations {
623+
All,
624+
Pair {
625+
/// The location in the MIR that generated these constraints.
626+
/// This is intended for error reporting and diagnosis; the
627+
/// constraints may *take effect* at a distinct spot.
628+
from_location: Location,
629+
630+
/// The constraints must be met at this location. In terms of the
631+
/// NLL RFC, when you have a constraint `R1: R2 @ P`, this field
632+
/// is the `P` value.
633+
at_location: Location,
634+
}
635+
}
636+
637+
impl Locations {
638+
pub fn from_location(&self) -> Option<Location> {
639+
match self {
640+
Locations::All => None,
641+
Locations::Pair { from_location, .. } => Some(*from_location),
642+
}
643+
}
644+
645+
pub fn at_location(&self) -> Option<Location> {
646+
match self {
647+
Locations::All => None,
648+
Locations::Pair { at_location, .. } => Some(*at_location),
649+
}
650+
}
632651
}
633652

634653
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
@@ -770,7 +789,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
770789
"check_stmt: user_assert_ty ty={:?} local_ty={:?}",
771790
ty, local_ty
772791
);
773-
if let Err(terr) = self.eq_types(ty, local_ty, location.at_self()) {
792+
if let Err(terr) = self.eq_types(ty, local_ty, Locations::All) {
774793
span_mirbug!(
775794
self,
776795
stmt,
@@ -820,7 +839,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
820839
let place_ty = location.ty(mir, tcx).to_ty(tcx);
821840
let rv_ty = value.ty(mir, tcx);
822841

823-
let locations = Locations {
842+
let locations = Locations::Pair {
824843
from_location: term_location,
825844
at_location: target.start_location(),
826845
};
@@ -839,7 +858,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
839858
// *both* blocks, so we need to ensure that it holds
840859
// at both locations.
841860
if let Some(unwind) = unwind {
842-
let locations = Locations {
861+
let locations = Locations::Pair {
843862
from_location: term_location,
844863
at_location: unwind.start_location(),
845864
};
@@ -971,7 +990,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
971990
match *destination {
972991
Some((ref dest, target_block)) => {
973992
let dest_ty = dest.ty(mir, tcx).to_ty(tcx);
974-
let locations = Locations {
993+
let locations = Locations::Pair {
975994
from_location: term_location,
976995
at_location: target_block.start_location(),
977996
};
@@ -1375,7 +1394,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13751394
};
13761395
let operand_ty = operand.ty(mir, tcx);
13771396
if let Err(terr) =
1378-
self.sub_types(operand_ty, field_ty, location.at_successor_within_block())
1397+
self.sub_types(operand_ty, field_ty, location.at_self())
13791398
{
13801399
span_mirbug!(
13811400
self,
@@ -1514,12 +1533,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
15141533
}
15151534
}
15161535

1517-
fn normalize<T>(&mut self, value: &T, location: Location) -> T
1536+
fn normalize<T>(&mut self, value: &T, location: impl ToLocations) -> T
15181537
where
15191538
T: fmt::Debug + TypeFoldable<'tcx>,
15201539
{
15211540
debug!("normalize(value={:?}, location={:?})", value, location);
1522-
self.fully_perform_op(location.at_self(), |this| {
1541+
self.fully_perform_op(location.to_locations(), |this| {
15231542
let Normalized { value, obligations } = this.infcx
15241543
.at(&this.misc(this.last_span), this.param_env)
15251544
.normalize(value)
@@ -1585,16 +1604,32 @@ trait AtLocation {
15851604

15861605
impl AtLocation for Location {
15871606
fn at_self(self) -> Locations {
1588-
Locations {
1607+
Locations::Pair {
15891608
from_location: self,
15901609
at_location: self,
15911610
}
15921611
}
15931612

15941613
fn at_successor_within_block(self) -> Locations {
1595-
Locations {
1614+
Locations::Pair {
15961615
from_location: self,
15971616
at_location: self.successor_within_block(),
15981617
}
15991618
}
16001619
}
1620+
1621+
trait ToLocations: fmt::Debug + Copy {
1622+
fn to_locations(self) -> Locations;
1623+
}
1624+
1625+
impl ToLocations for Locations {
1626+
fn to_locations(self) -> Locations {
1627+
self
1628+
}
1629+
}
1630+
1631+
impl ToLocations for Location {
1632+
fn to_locations(self) -> Locations {
1633+
self.at_self()
1634+
}
1635+
}

0 commit comments

Comments
 (0)