Skip to content

Commit f8d9bdc

Browse files
committed
dropck: do not add types with escaped-regions into the breadcrumbs set.
In particular, when we traverse a type like: `(for <'r> Fn(&'r u8), for <'r> Fn(&'r u8))` we should not add the first type `Fn(&'r u8)` to the bread-crumbs set, because that type ends up being structurally equivalent to the *second* `Fn(&'r u8)` type, even though they each should be considered distinct since they occur under distinct `for <'r>` binders. Fix rust-lang#25750.
1 parent 0a8d8fd commit f8d9bdc

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

src/librustc_typeck/check/dropck.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use check::regionck::{self, Rcx};
1313
use middle::infer;
1414
use middle::region;
1515
use middle::subst::{self, Subst};
16-
use middle::ty::{self, Ty};
16+
use middle::ty::{self, Ty, RegionEscape};
1717

1818
use syntax::ast;
1919
use syntax::codemap::{self, Span};
@@ -382,7 +382,32 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
382382
if breadcrumbs.contains(&typ) {
383383
continue;
384384
}
385-
breadcrumbs.push(typ);
385+
386+
// Okay, it looks like we have not seen `typ`, so add it to
387+
// the breadcrumbs set so that we will not recurse on it again
388+
// in the future.
389+
//
390+
// Issues #25750, #27138: on a type `B` within `for <'r> B`,
391+
// occurrences of `'r` within `B` are not globally meaningful.
392+
// Nonetheless they might accidentally be considered equal to
393+
// other occurrences outside of the `for <'r> B`, since they
394+
// will be structurally the same.
395+
//
396+
// This comes up for example in the type:
397+
//
398+
// (for <'r> Fn(&'r u8), for <'r> Fn(&'r u8))
399+
//
400+
// We deal with this by detecting if we are looking at such a
401+
// `B`, and if so, we don't add it to breadcrumbs set.
402+
//
403+
// (A more robust/disciplined way of dealing with this would
404+
// be to add such types *temporarily* to the breadcrumbs set,
405+
// *solely* during the extent of the time that we are
406+
// underneath the `for <'r> ...`; I may look into doing that
407+
// later, but for now I think this simpler measure will suffice.)
408+
if !typ.has_escaping_regions() {
409+
breadcrumbs.push(typ);
410+
}
386411

387412
// If we encounter `PhantomData<T>`, then we should replace it
388413
// with `T`, the type it represents as owned by the

0 commit comments

Comments
 (0)