Skip to content

Commit b68fad6

Browse files
committed
universe transition
Remove the leak-check and its associated machinery. Replace with making the solver aware of universes.
1 parent eba2ae5 commit b68fad6

File tree

10 files changed

+144
-799
lines changed

10 files changed

+144
-799
lines changed

src/librustc/infer/higher_ranked/mod.rs

+30-477
Large diffs are not rendered by default.

src/librustc/infer/lexical_region_resolve/mod.rs

+36-5
Original file line numberDiff line numberDiff line change
@@ -215,23 +215,41 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
215215
) -> bool {
216216
debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data);
217217

218-
// Check if this relationship is implied by a given.
219218
match *a_region {
219+
// Check if this relationship is implied by a given.
220220
ty::ReEarlyBound(_) | ty::ReFree(_) => if self.data.givens.contains(&(a_region, b_vid))
221221
{
222222
debug!("given");
223223
return false;
224224
},
225+
225226
_ => {}
226227
}
227228

229+
228230
match *b_data {
229231
VarValue::Value(cur_region) => {
230-
let lub = self.lub_concrete_regions(a_region, cur_region);
232+
let mut lub = self.lub_concrete_regions(a_region, cur_region);
231233
if lub == cur_region {
232234
return false;
233235
}
234236

237+
// Watch out for `'b: !1` relationships, where the
238+
// universe of `'b` can't name the placeholder `!1`. In
239+
// that case, we have to grow `'b` to be `'static` for the
240+
// relationship to hold. This is obviously a kind of sub-optimal
241+
// choice -- in the future, when we incorporate a knowledge
242+
// of the parameter environment, we might be able to find a
243+
// tighter bound than `'static`.
244+
//
245+
// (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.)
246+
let b_universe = self.var_infos[b_vid].universe;
247+
if let ty::RePlaceholder(p) = lub {
248+
if b_universe.cannot_name(p.universe) {
249+
lub = self.tcx().types.re_static;
250+
}
251+
}
252+
235253
debug!(
236254
"Expanding value of {:?} from {:?} to {:?}",
237255
b_vid, cur_region, lub
@@ -554,10 +572,22 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
554572
lower_bounds.sort_by_key(region_order_key);
555573
upper_bounds.sort_by_key(region_order_key);
556574

575+
let node_universe = self.var_infos[node_idx].universe;
576+
557577
for lower_bound in &lower_bounds {
578+
let effective_lower_bound = if let ty::RePlaceholder(p) = lower_bound.region {
579+
if node_universe.cannot_name(p.universe) {
580+
self.tcx().types.re_static
581+
} else {
582+
lower_bound.region
583+
}
584+
} else {
585+
lower_bound.region
586+
};
587+
558588
for upper_bound in &upper_bounds {
559589
if !self.region_rels
560-
.is_subregion_of(lower_bound.region, upper_bound.region)
590+
.is_subregion_of(effective_lower_bound, upper_bound.region)
561591
{
562592
let origin = self.var_infos[node_idx].origin.clone();
563593
debug!(
@@ -580,9 +610,10 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
580610
span_bug!(
581611
self.var_infos[node_idx].origin.span(),
582612
"collect_error_for_expanding_node() could not find \
583-
error for var {:?}, lower_bounds={:?}, \
584-
upper_bounds={:?}",
613+
error for var {:?} in universe {:?}, lower_bounds={:#?}, \
614+
upper_bounds={:#?}",
585615
node_idx,
616+
node_universe,
586617
lower_bounds,
587618
upper_bounds
588619
);

src/librustc/infer/mod.rs

+19-67
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use ty::{FloatVid, IntVid, TyVid};
3232
use util::nodemap::FxHashMap;
3333

3434
use self::combine::CombineFields;
35-
use self::higher_ranked::HrMatchResult;
3635
use self::lexical_region_resolve::LexicalRegionResolutions;
3736
use self::outlives::env::OutlivesEnvironment;
3837
use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound};
@@ -948,39 +947,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
948947
return None;
949948
}
950949

951-
Some(self.commit_if_ok(|snapshot| {
952-
let (
953-
ty::SubtypePredicate {
954-
a_is_expected,
955-
a,
956-
b,
957-
},
958-
placeholder_map,
959-
) = self.replace_bound_vars_with_placeholders(predicate);
950+
let (
951+
ty::SubtypePredicate {
952+
a_is_expected,
953+
a,
954+
b,
955+
},
956+
_,
957+
) = self.replace_bound_vars_with_placeholders(predicate);
960958

961-
let cause_span = cause.span;
962-
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
963-
self.leak_check(false, cause_span, &placeholder_map, snapshot)?;
964-
self.pop_placeholders(placeholder_map, snapshot);
965-
Ok(ok.unit())
966-
}))
959+
Some(
960+
self.at(cause, param_env)
961+
.sub_exp(a_is_expected, a, b)
962+
.map(|ok| ok.unit()),
963+
)
967964
}
968965

969966
pub fn region_outlives_predicate(
970967
&self,
971968
cause: &traits::ObligationCause<'tcx>,
972969
predicate: &ty::PolyRegionOutlivesPredicate<'tcx>,
973-
) -> UnitResult<'tcx> {
974-
self.commit_if_ok(|snapshot| {
975-
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) =
976-
self.replace_bound_vars_with_placeholders(predicate);
977-
let origin = SubregionOrigin::from_obligation_cause(cause, || {
978-
RelateRegionParamBound(cause.span)
979-
});
980-
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
981-
self.leak_check(false, cause.span, &placeholder_map, snapshot)?;
982-
Ok(self.pop_placeholders(placeholder_map, snapshot))
983-
})
970+
) {
971+
let (ty::OutlivesPredicate(r_a, r_b), _) =
972+
self.replace_bound_vars_with_placeholders(predicate);
973+
let origin =
974+
SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span));
975+
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
984976
}
985977

986978
pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
@@ -1389,46 +1381,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
13891381
self.tcx.replace_bound_vars(value, fld_r, fld_t)
13901382
}
13911383

1392-
/// Given a higher-ranked projection predicate like:
1393-
///
1394-
/// for<'a> <T as Fn<&'a u32>>::Output = &'a u32
1395-
///
1396-
/// and a target trait-ref like:
1397-
///
1398-
/// <T as Fn<&'x u32>>
1399-
///
1400-
/// find a substitution `S` for the higher-ranked regions (here,
1401-
/// `['a => 'x]`) such that the predicate matches the trait-ref,
1402-
/// and then return the value (here, `&'a u32`) but with the
1403-
/// substitution applied (hence, `&'x u32`).
1404-
///
1405-
/// See `higher_ranked_match` in `higher_ranked/mod.rs` for more
1406-
/// details.
1407-
pub fn match_poly_projection_predicate(
1408-
&self,
1409-
cause: ObligationCause<'tcx>,
1410-
param_env: ty::ParamEnv<'tcx>,
1411-
match_a: ty::PolyProjectionPredicate<'tcx>,
1412-
match_b: ty::TraitRef<'tcx>,
1413-
) -> InferResult<'tcx, HrMatchResult<Ty<'tcx>>> {
1414-
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
1415-
let trace = TypeTrace {
1416-
cause,
1417-
values: TraitRefs(ExpectedFound::new(
1418-
true,
1419-
match_pair.skip_binder().0,
1420-
match_b,
1421-
)),
1422-
};
1423-
1424-
let mut combine = self.combine_fields(trace, param_env);
1425-
let result = combine.higher_ranked_match(&match_pair, &match_b, true)?;
1426-
Ok(InferOk {
1427-
value: result,
1428-
obligations: combine.obligations,
1429-
})
1430-
}
1431-
14321384
/// See `verify_generic_bound` method in `region_constraints`
14331385
pub fn verify_generic_bound(
14341386
&self,

src/librustc/infer/region_constraints/mod.rs

-31
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ use ty::{Region, RegionVid};
1717
use std::collections::BTreeMap;
1818
use std::{cmp, fmt, mem, u32};
1919

20-
mod taint;
21-
2220
#[derive(Default)]
2321
pub struct RegionConstraintCollector<'tcx> {
2422
/// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
@@ -826,35 +824,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
826824
.collect()
827825
}
828826

829-
/// Computes all regions that have been related to `r0` since the
830-
/// mark `mark` was made---`r0` itself will be the first
831-
/// entry. The `directions` parameter controls what kind of
832-
/// relations are considered. For example, one can say that only
833-
/// "incoming" edges to `r0` are desired, in which case one will
834-
/// get the set of regions `{r|r <= r0}`. This is used when
835-
/// checking whether placeholder regions are being improperly
836-
/// related to other regions.
837-
pub fn tainted(
838-
&self,
839-
tcx: TyCtxt<'_, '_, 'tcx>,
840-
mark: &RegionSnapshot,
841-
r0: Region<'tcx>,
842-
directions: TaintDirections,
843-
) -> FxHashSet<ty::Region<'tcx>> {
844-
debug!(
845-
"tainted(mark={:?}, r0={:?}, directions={:?})",
846-
mark, r0, directions
847-
);
848-
849-
// `result_set` acts as a worklist: we explore all outgoing
850-
// edges and add any new regions we find to result_set. This
851-
// is not a terribly efficient implementation.
852-
let mut taint_set = taint::TaintSet::new(directions, r0);
853-
taint_set.fixed_point(tcx, &self.undo_log[mark.length..], &self.data.verifys);
854-
debug!("tainted: result={:?}", taint_set);
855-
return taint_set.into_set();
856-
}
857-
858827
pub fn region_constraints_added_in_snapshot(&self, mark: &RegionSnapshot) -> bool {
859828
self.undo_log[mark.length..]
860829
.iter()

src/librustc/infer/region_constraints/taint.rs

-85
This file was deleted.

src/librustc/traits/auto_trait.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -771,13 +771,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
771771
}
772772
}
773773
&ty::Predicate::RegionOutlives(ref binder) => {
774-
if select
775-
.infcx()
776-
.region_outlives_predicate(&dummy_cause, binder)
777-
.is_err()
778-
{
779-
return false;
780-
}
774+
let () = select.infcx().region_outlives_predicate(&dummy_cause, binder);
781775
}
782776
&ty::Predicate::TypeOutlives(ref binder) => {
783777
match (

src/librustc/traits/error_reporting.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -728,12 +728,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
728728
}
729729

730730
ty::Predicate::RegionOutlives(ref predicate) => {
731-
let predicate = self.resolve_type_vars_if_possible(predicate);
732-
let err = self.region_outlives_predicate(&obligation.cause,
733-
&predicate).err().unwrap();
734-
struct_span_err!(self.tcx.sess, span, E0279,
735-
"the requirement `{}` is not satisfied (`{}`)",
736-
predicate, err)
731+
// These errors should show up as region
732+
// inference failures.
733+
panic!("region outlives {:?} failed", predicate);
737734
}
738735

739736
ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {

src/librustc/traits/fulfill.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,8 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
331331
}
332332

333333
ty::Predicate::RegionOutlives(ref binder) => {
334-
match self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder) {
335-
Ok(()) => ProcessResult::Changed(vec![]),
336-
Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)),
337-
}
334+
let () = self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder);
335+
ProcessResult::Changed(vec![])
338336
}
339337

340338
ty::Predicate::TypeOutlives(ref binder) => {

0 commit comments

Comments
 (0)