Skip to content

Commit c244fd7

Browse files
committed
kill old-style-lub warnings
1 parent 740117f commit c244fd7

File tree

7 files changed

+4
-317
lines changed

7 files changed

+4
-317
lines changed

src/librustc/infer/glb.rs

+2-22
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use super::Subtype;
1515

1616
use traits::ObligationCause;
1717
use ty::{self, Ty, TyCtxt};
18-
use ty::error::TypeError;
1918
use ty::relate::{Relate, RelateResult, TypeRelation};
2019

2120
/// "Greatest lower bound" (common subtype)
@@ -76,31 +75,12 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
7675
where T: Relate<'tcx>
7776
{
7877
debug!("binders(a={:?}, b={:?})", a, b);
79-
let was_error = self.infcx().probe(|_snapshot| {
80-
// Subtle: use a fresh combine-fields here because we recover
81-
// from Err. Doing otherwise could propagate obligations out
82-
// through our `self.obligations` field.
83-
self.infcx()
84-
.combine_fields(self.fields.trace.clone(), self.fields.param_env)
85-
.higher_ranked_glb(a, b, self.a_is_expected)
86-
.is_err()
87-
});
88-
debug!("binders: was_error={:?}", was_error);
8978

9079
// When higher-ranked types are involved, computing the LUB is
9180
// very challenging, switch to invariance. This is obviously
9281
// overly conservative but works ok in practice.
93-
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
94-
Ok(_) => Ok(a.clone()),
95-
Err(err) => {
96-
debug!("binders: error occurred, was_error={:?}", was_error);
97-
if !was_error {
98-
Err(TypeError::OldStyleLUB(Box::new(err)))
99-
} else {
100-
Err(err)
101-
}
102-
}
103-
}
82+
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
83+
Ok(a.clone())
10484
}
10585
}
10686

src/librustc/infer/higher_ranked/mod.rs

-256
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use super::region_constraints::{TaintDirections};
2222
use ty::{self, TyCtxt, Binder, TypeFoldable};
2323
use ty::error::TypeError;
2424
use ty::relate::{Relate, RelateResult, TypeRelation};
25-
use std::collections::BTreeMap;
2625
use syntax_pos::Span;
2726
use util::nodemap::{FxHashMap, FxHashSet};
2827

@@ -202,261 +201,6 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
202201
Ok(HrMatchResult { value: a_value })
203202
});
204203
}
205-
206-
pub fn higher_ranked_lub<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
207-
-> RelateResult<'tcx, Binder<T>>
208-
where T: Relate<'tcx>
209-
{
210-
// Start a snapshot so we can examine "all bindings that were
211-
// created as part of this type comparison".
212-
return self.infcx.commit_if_ok(|snapshot| {
213-
// Instantiate each bound region with a fresh region variable.
214-
let span = self.trace.cause.span;
215-
let (a_with_fresh, a_map) =
216-
self.infcx.replace_late_bound_regions_with_fresh_var(
217-
span, HigherRankedType, a);
218-
let (b_with_fresh, _) =
219-
self.infcx.replace_late_bound_regions_with_fresh_var(
220-
span, HigherRankedType, b);
221-
222-
// Collect constraints.
223-
let result0 =
224-
self.lub(a_is_expected).relate(&a_with_fresh, &b_with_fresh)?;
225-
let result0 =
226-
self.infcx.resolve_type_vars_if_possible(&result0);
227-
debug!("lub result0 = {:?}", result0);
228-
229-
// Generalize the regions appearing in result0 if possible
230-
let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
231-
let span = self.trace.cause.span;
232-
let result1 =
233-
fold_regions_in(
234-
self.tcx(),
235-
&result0,
236-
|r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn,
237-
&new_vars, &a_map, r));
238-
239-
debug!("lub({:?},{:?}) = {:?}",
240-
a,
241-
b,
242-
result1);
243-
244-
Ok(ty::Binder::bind(result1))
245-
});
246-
247-
fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
248-
span: Span,
249-
snapshot: &CombinedSnapshot<'a, 'tcx>,
250-
debruijn: ty::DebruijnIndex,
251-
new_vars: &[ty::RegionVid],
252-
a_map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
253-
r0: ty::Region<'tcx>)
254-
-> ty::Region<'tcx> {
255-
// Regions that pre-dated the LUB computation stay as they are.
256-
if !is_var_in_set(new_vars, r0) {
257-
assert!(!r0.is_late_bound());
258-
debug!("generalize_region(r0={:?}): not new variable", r0);
259-
return r0;
260-
}
261-
262-
let tainted = infcx.tainted_regions(snapshot, r0, TaintDirections::both());
263-
264-
// Variables created during LUB computation which are
265-
// *related* to regions that pre-date the LUB computation
266-
// stay as they are.
267-
if !tainted.iter().all(|&r| is_var_in_set(new_vars, r)) {
268-
debug!("generalize_region(r0={:?}): \
269-
non-new-variables found in {:?}",
270-
r0, tainted);
271-
assert!(!r0.is_late_bound());
272-
return r0;
273-
}
274-
275-
// Otherwise, the variable must be associated with at
276-
// least one of the variables representing bound regions
277-
// in both A and B. Replace the variable with the "first"
278-
// bound region from A that we find it to be associated
279-
// with.
280-
for (a_br, a_r) in a_map {
281-
if tainted.iter().any(|x| x == a_r) {
282-
debug!("generalize_region(r0={:?}): \
283-
replacing with {:?}, tainted={:?}",
284-
r0, *a_br, tainted);
285-
return infcx.tcx.mk_region(ty::ReLateBound(debruijn, *a_br));
286-
}
287-
}
288-
289-
span_bug!(
290-
span,
291-
"region {:?} is not associated with any bound region from A!",
292-
r0)
293-
}
294-
}
295-
296-
pub fn higher_ranked_glb<T>(&mut self, a: &Binder<T>, b: &Binder<T>, a_is_expected: bool)
297-
-> RelateResult<'tcx, Binder<T>>
298-
where T: Relate<'tcx>
299-
{
300-
debug!("higher_ranked_glb({:?}, {:?})",
301-
a, b);
302-
303-
// Make a snapshot so we can examine "all bindings that were
304-
// created as part of this type comparison".
305-
return self.infcx.commit_if_ok(|snapshot| {
306-
// Instantiate each bound region with a fresh region variable.
307-
let (a_with_fresh, a_map) =
308-
self.infcx.replace_late_bound_regions_with_fresh_var(
309-
self.trace.cause.span, HigherRankedType, a);
310-
let (b_with_fresh, b_map) =
311-
self.infcx.replace_late_bound_regions_with_fresh_var(
312-
self.trace.cause.span, HigherRankedType, b);
313-
let a_vars = var_ids(self, &a_map);
314-
let b_vars = var_ids(self, &b_map);
315-
316-
// Collect constraints.
317-
let result0 =
318-
self.glb(a_is_expected).relate(&a_with_fresh, &b_with_fresh)?;
319-
let result0 =
320-
self.infcx.resolve_type_vars_if_possible(&result0);
321-
debug!("glb result0 = {:?}", result0);
322-
323-
// Generalize the regions appearing in result0 if possible
324-
let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
325-
let span = self.trace.cause.span;
326-
let result1 =
327-
fold_regions_in(
328-
self.tcx(),
329-
&result0,
330-
|r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn,
331-
&new_vars,
332-
&a_map, &a_vars, &b_vars,
333-
r));
334-
335-
debug!("glb({:?},{:?}) = {:?}",
336-
a,
337-
b,
338-
result1);
339-
340-
Ok(ty::Binder::bind(result1))
341-
});
342-
343-
fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
344-
span: Span,
345-
snapshot: &CombinedSnapshot<'a, 'tcx>,
346-
debruijn: ty::DebruijnIndex,
347-
new_vars: &[ty::RegionVid],
348-
a_map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
349-
a_vars: &[ty::RegionVid],
350-
b_vars: &[ty::RegionVid],
351-
r0: ty::Region<'tcx>)
352-
-> ty::Region<'tcx> {
353-
if !is_var_in_set(new_vars, r0) {
354-
assert!(!r0.is_late_bound());
355-
return r0;
356-
}
357-
358-
let tainted = infcx.tainted_regions(snapshot, r0, TaintDirections::both());
359-
360-
let mut a_r = None;
361-
let mut b_r = None;
362-
let mut only_new_vars = true;
363-
for r in &tainted {
364-
if is_var_in_set(a_vars, *r) {
365-
if a_r.is_some() {
366-
return fresh_bound_variable(infcx, debruijn);
367-
} else {
368-
a_r = Some(*r);
369-
}
370-
} else if is_var_in_set(b_vars, *r) {
371-
if b_r.is_some() {
372-
return fresh_bound_variable(infcx, debruijn);
373-
} else {
374-
b_r = Some(*r);
375-
}
376-
} else if !is_var_in_set(new_vars, *r) {
377-
only_new_vars = false;
378-
}
379-
}
380-
381-
// NB---I do not believe this algorithm computes
382-
// (necessarily) the GLB. As written it can
383-
// spuriously fail. In particular, if there is a case
384-
// like: |fn(&a)| and fn(fn(&b)), where a and b are
385-
// free, it will return fn(&c) where c = GLB(a,b). If
386-
// however this GLB is not defined, then the result is
387-
// an error, even though something like
388-
// "fn<X>(fn(&X))" where X is bound would be a
389-
// subtype of both of those.
390-
//
391-
// The problem is that if we were to return a bound
392-
// variable, we'd be computing a lower-bound, but not
393-
// necessarily the *greatest* lower-bound.
394-
//
395-
// Unfortunately, this problem is non-trivial to solve,
396-
// because we do not know at the time of computing the GLB
397-
// whether a GLB(a,b) exists or not, because we haven't
398-
// run region inference (or indeed, even fully computed
399-
// the region hierarchy!). The current algorithm seems to
400-
// works ok in practice.
401-
402-
if a_r.is_some() && b_r.is_some() && only_new_vars {
403-
// Related to exactly one bound variable from each fn:
404-
return rev_lookup(infcx, span, a_map, a_r.unwrap());
405-
} else if a_r.is_none() && b_r.is_none() {
406-
// Not related to bound variables from either fn:
407-
assert!(!r0.is_late_bound());
408-
return r0;
409-
} else {
410-
// Other:
411-
return fresh_bound_variable(infcx, debruijn);
412-
}
413-
}
414-
415-
fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
416-
span: Span,
417-
a_map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
418-
r: ty::Region<'tcx>) -> ty::Region<'tcx>
419-
{
420-
for (a_br, a_r) in a_map {
421-
if *a_r == r {
422-
return infcx.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, *a_br));
423-
}
424-
}
425-
span_bug!(
426-
span,
427-
"could not find original bound region for {:?}",
428-
r);
429-
}
430-
431-
fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
432-
debruijn: ty::DebruijnIndex)
433-
-> ty::Region<'tcx> {
434-
infcx.borrow_region_constraints().new_bound(infcx.tcx, debruijn)
435-
}
436-
}
437-
}
438-
439-
fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
440-
map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
441-
-> Vec<ty::RegionVid> {
442-
map.iter()
443-
.map(|(_, &r)| match *r {
444-
ty::ReVar(r) => { r }
445-
_ => {
446-
span_bug!(
447-
fields.trace.cause.span,
448-
"found non-region-vid: {:?}",
449-
r);
450-
}
451-
})
452-
.collect()
453-
}
454-
455-
fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region<'_>) -> bool {
456-
match *r {
457-
ty::ReVar(ref v) => new_vars.iter().any(|x| x == v),
458-
_ => false
459-
}
460204
}
461205

462206
fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,

src/librustc/infer/lub.rs

+2-22
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use super::Subtype;
1515

1616
use traits::ObligationCause;
1717
use ty::{self, Ty, TyCtxt};
18-
use ty::error::TypeError;
1918
use ty::relate::{Relate, RelateResult, TypeRelation};
2019

2120
/// "Least upper bound" (common supertype)
@@ -76,31 +75,12 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
7675
where T: Relate<'tcx>
7776
{
7877
debug!("binders(a={:?}, b={:?})", a, b);
79-
let was_error = self.infcx().probe(|_snapshot| {
80-
// Subtle: use a fresh combine-fields here because we recover
81-
// from Err. Doing otherwise could propagate obligations out
82-
// through our `self.obligations` field.
83-
self.infcx()
84-
.combine_fields(self.fields.trace.clone(), self.fields.param_env)
85-
.higher_ranked_lub(a, b, self.a_is_expected)
86-
.is_err()
87-
});
88-
debug!("binders: was_error={:?}", was_error);
8978

9079
// When higher-ranked types are involved, computing the LUB is
9180
// very challenging, switch to invariance. This is obviously
9281
// overly conservative but works ok in practice.
93-
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
94-
Ok(_) => Ok(a.clone()),
95-
Err(err) => {
96-
debug!("binders: error occurred, was_error={:?}", was_error);
97-
if !was_error {
98-
Err(TypeError::OldStyleLUB(Box::new(err)))
99-
} else {
100-
Err(err)
101-
}
102-
}
103-
}
82+
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
83+
Ok(a.clone())
10484
}
10585
}
10686

src/librustc/ty/error.rs

-11
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ pub enum TypeError<'tcx> {
5353
ProjectionMismatched(ExpectedFound<DefId>),
5454
ProjectionBoundsLength(ExpectedFound<usize>),
5555
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
56-
57-
OldStyleLUB(Box<TypeError<'tcx>>),
5856
}
5957

6058
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
@@ -166,9 +164,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
166164
report_maybe_different(f, &format!("trait `{}`", values.expected),
167165
&format!("trait `{}`", values.found))
168166
}
169-
OldStyleLUB(ref err) => {
170-
write!(f, "{}", err)
171-
}
172167
}
173168
}
174169
}
@@ -266,12 +261,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
266261
}
267262
}
268263
},
269-
OldStyleLUB(err) => {
270-
db.note("this was previously accepted by the compiler but has been phased out");
271-
db.note("for more information, see https://github.com/rust-lang/rust/issues/45852");
272-
273-
self.note_and_explain_type_err(db, &err, sp);
274-
}
275264
CyclicTy(ty) => {
276265
// Watch out for various cases of cyclic types and try to explain.
277266
if ty.is_closure() || ty.is_generator() {

0 commit comments

Comments
 (0)