Skip to content

Commit 11e265c

Browse files
committed
rollup merge of #20707: nikomatsakis/issue-20582
2 parents 373cbab + a70428a commit 11e265c

File tree

12 files changed

+86
-30
lines changed

12 files changed

+86
-30
lines changed

src/librustc/middle/infer/higher_ranked/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
468468
* when higher-ranked things are involved. See `doc.rs` for more details.
469469
*/
470470

471-
let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br, _| {
471+
let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br| {
472472
infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
473473
});
474474

src/librustc/middle/infer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10481048
ty::replace_late_bound_regions(
10491049
self.tcx,
10501050
value,
1051-
|br, _| self.next_region_var(LateBoundRegion(span, br, lbrct)))
1051+
|br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
10521052
}
10531053

10541054
/// See `verify_generic_bound` method in `region_inference`

src/librustc/middle/ty.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6686,7 +6686,7 @@ pub fn liberate_late_bound_regions<'tcx, T>(
66866686
{
66876687
replace_late_bound_regions(
66886688
tcx, value,
6689-
|br, _| ty::ReFree(ty::FreeRegion{scope: scope, bound_region: br})).0
6689+
|br| ty::ReFree(ty::FreeRegion{scope: scope, bound_region: br})).0
66906690
}
66916691

66926692
pub fn count_late_bound_regions<'tcx, T>(
@@ -6695,7 +6695,7 @@ pub fn count_late_bound_regions<'tcx, T>(
66956695
-> uint
66966696
where T : TypeFoldable<'tcx> + Repr<'tcx>
66976697
{
6698-
let (_, skol_map) = replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic);
6698+
let (_, skol_map) = replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
66996699
skol_map.len()
67006700
}
67016701

@@ -6726,7 +6726,7 @@ pub fn erase_late_bound_regions<'tcx, T>(
67266726
-> T
67276727
where T : TypeFoldable<'tcx> + Repr<'tcx>
67286728
{
6729-
replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0
6729+
replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
67306730
}
67316731

67326732
/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
@@ -6744,9 +6744,9 @@ pub fn anonymize_late_bound_regions<'tcx, T>(
67446744
where T : TypeFoldable<'tcx> + Repr<'tcx>,
67456745
{
67466746
let mut counter = 0;
6747-
ty::Binder(replace_late_bound_regions(tcx, sig, |_, db| {
6747+
ty::Binder(replace_late_bound_regions(tcx, sig, |_| {
67486748
counter += 1;
6749-
ReLateBound(db, BrAnon(counter))
6749+
ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
67506750
}).0)
67516751
}
67526752

@@ -6757,7 +6757,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
67576757
mut mapf: F)
67586758
-> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
67596759
where T : TypeFoldable<'tcx> + Repr<'tcx>,
6760-
F : FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
6760+
F : FnMut(BoundRegion) -> ty::Region,
67616761
{
67626762
debug!("replace_late_bound_regions({})", binder.repr(tcx));
67636763

@@ -6769,8 +6769,19 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
67696769
debug!("region={}", region.repr(tcx));
67706770
match region {
67716771
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
6772-
* map.entry(br).get().unwrap_or_else(
6773-
|vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
6772+
let region =
6773+
* map.entry(br).get().unwrap_or_else(
6774+
|vacant_entry| vacant_entry.insert(mapf(br)));
6775+
6776+
if let ty::ReLateBound(debruijn1, br) = region {
6777+
// If the callback returns a late-bound region,
6778+
// that region should always use depth 1. Then we
6779+
// adjust it to the correct depth.
6780+
assert_eq!(debruijn1.depth, 1);
6781+
ty::ReLateBound(debruijn, br)
6782+
} else {
6783+
region
6784+
}
67746785
}
67756786
_ => {
67766787
region

src/librustc/middle/ty_fold.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx>
862862
///////////////////////////////////////////////////////////////////////////
863863
// Region eraser
864864
//
865-
// Replaces all free regions with 'static. Useful in trans.
865+
// Replaces all free regions with 'static. Useful in contexts, such as
866+
// method probing, where precise region relationships are not
867+
// important. Note that in trans you should use
868+
// `common::erase_regions` instead.
866869

867870
pub struct RegionEraser<'a, 'tcx: 'a> {
868871
tcx: &'a ty::ctxt<'tcx>,

src/librustc/util/ppaux.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,8 +1183,8 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
11831183
// the output. We'll probably want to tweak this over time to
11841184
// decide just how much information to give.
11851185
let mut names = Vec::new();
1186-
let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br, debruijn| {
1187-
ty::ReLateBound(debruijn, match br {
1186+
let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br| {
1187+
ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
11881188
ty::BrNamed(_, name) => {
11891189
names.push(token::get_name(name));
11901190
br

src/librustc_trans/trans/base.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,15 @@ pub fn kind_for_unboxed_closure(ccx: &CrateContext, closure_id: ast::DefId)
281281

282282
pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
283283
fn_ty: Ty<'tcx>, name: &str) -> ValueRef {
284+
debug!("decl_rust_fn(fn_ty={}, name={:?})",
285+
fn_ty.repr(ccx.tcx()),
286+
name);
287+
284288
let fn_ty = monomorphize::normalize_associated_type(ccx.tcx(), &fn_ty);
285289

290+
debug!("decl_rust_fn: fn_ty={} (after normalized associated types)",
291+
fn_ty.repr(ccx.tcx()));
292+
286293
let function_type; // placeholder so that the memory ownership works out ok
287294

288295
let (sig, abi, env) = match fn_ty.sty {
@@ -305,10 +312,12 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
305312
let sig = ty::erase_late_bound_regions(ccx.tcx(), sig);
306313
let sig = ty::Binder(sig);
307314

315+
debug!("decl_rust_fn: sig={} (after erasing regions)",
316+
sig.repr(ccx.tcx()));
317+
308318
let llfty = type_of_rust_fn(ccx, env, &sig, abi);
309319

310-
debug!("decl_rust_fn(sig={}, type={})",
311-
sig.repr(ccx.tcx()),
320+
debug!("decl_rust_fn: llfty={}",
312321
ccx.tn().type_to_string(llfty));
313322

314323
let llfn = decl_fn(ccx, name, llvm::CCallConv, llfty, sig.0.output /* (1) */);

src/librustc_trans/trans/callee.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
265265
let _icx = push_ctxt("trans_fn_pointer_shim");
266266
let tcx = ccx.tcx();
267267

268-
let bare_fn_ty = normalize_ty(tcx, bare_fn_ty);
268+
let bare_fn_ty = erase_regions(tcx, &bare_fn_ty);
269269
match ccx.fn_pointer_shims().borrow().get(&bare_fn_ty) {
270270
Some(&llval) => { return llval; }
271271
None => { }

src/librustc_trans/trans/closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
466466

467467
// Normalize type so differences in regions and typedefs don't cause
468468
// duplicate declarations
469-
let function_type = normalize_ty(ccx.tcx(), function_type);
469+
let function_type = erase_regions(ccx.tcx(), &function_type);
470470
let params = match function_type.sty {
471471
ty::ty_unboxed_closure(_, _, ref substs) => substs.types.clone(),
472472
_ => unreachable!()

src/librustc_trans/trans/common.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,21 @@ use util::nodemap::FnvHashSet;
5858

5959
pub use trans::context::CrateContext;
6060

61-
/// Returns an equivalent type with all the typedefs and self regions removed.
62-
pub fn normalize_ty<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
63-
let u = TypeNormalizer(cx).fold_ty(ty);
64-
debug!("normalize_ty({}) = {}",
65-
ty.repr(cx), u.repr(cx));
66-
return u;
61+
/// Returns an equivalent value with all free regions removed (note
62+
/// that late-bound regions remain, because they are important for
63+
/// subtyping, but they are anonymized and normalized as well). This
64+
/// is a stronger, caching version of `ty_fold::erase_regions`.
65+
pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
66+
where T : TypeFoldable<'tcx> + Repr<'tcx>
67+
{
68+
let value1 = value.fold_with(&mut RegionEraser(cx));
69+
debug!("erase_regions({}) = {}",
70+
value.repr(cx), value1.repr(cx));
71+
return value1;
6772

68-
struct TypeNormalizer<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>);
73+
struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>);
6974

70-
impl<'a, 'tcx> TypeFolder<'tcx> for TypeNormalizer<'a, 'tcx> {
75+
impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
7176
fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 }
7277

7378
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
@@ -84,7 +89,6 @@ pub fn normalize_ty<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
8489
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
8590
where T : TypeFoldable<'tcx> + Repr<'tcx>
8691
{
87-
// FIXME(#20526) this should replace `enter_region_binder`/`exit_region_binder`.
8892
let u = ty::anonymize_late_bound_regions(self.tcx(), t);
8993
ty_fold::super_fold_binder(self, &u)
9094
}
@@ -989,7 +993,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
989993
let tcx = ccx.tcx();
990994

991995
// Remove any references to regions; this helps improve caching.
992-
let trait_ref = ty_fold::erase_regions(tcx, trait_ref);
996+
let trait_ref = erase_regions(tcx, &trait_ref);
993997

994998
// First check the cache.
995999
match ccx.trait_cache().borrow().get(&trait_ref) {

src/librustc_trans/trans/monomorphize.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,10 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
313313
{
314314
debug!("normalize_associated_type(t={})", value.repr(tcx));
315315

316+
let value = erase_regions(tcx, value);
317+
316318
if !value.has_projection_types() {
317-
return value.clone();
319+
return value;
318320
}
319321

320322
// FIXME(#20304) -- cache
@@ -324,7 +326,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
324326
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
325327
let cause = traits::ObligationCause::dummy();
326328
let traits::Normalized { value: result, obligations } =
327-
traits::normalize(&mut selcx, cause, value);
329+
traits::normalize(&mut selcx, cause, &value);
328330

329331
debug!("normalize_associated_type: result={} obligations={}",
330332
result.repr(tcx),

src/librustc_trans/trans/type_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
285285
// Rust types are defined as the same LLVM types. If we don't do
286286
// this then, e.g. `Option<{myfield: bool}>` would be a different
287287
// type than `Option<myrec>`.
288-
let t_norm = normalize_ty(cx.tcx(), t);
288+
let t_norm = erase_regions(cx.tcx(), &t);
289289

290290
if t != t_norm {
291291
let llty = type_of(cx, t_norm);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Regression test for #20582. This test caused an ICE related to
12+
// inconsistent region erasure in trans.
13+
14+
struct Foo<'a> {
15+
buf: &'a[u8]
16+
}
17+
18+
impl<'a> Iterator for Foo<'a> {
19+
type Item = &'a[u8];
20+
21+
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
22+
Some(self.buf)
23+
}
24+
}
25+
26+
fn main() {
27+
}

0 commit comments

Comments
 (0)