Part of #49810.
The Binder type is used to represent higher-ranked regions:
|
/// Binder is a binder for higher-ranked lifetimes. It is part of the |
|
/// compiler's representation for things like `for<'a> Fn(&'a isize)` |
|
/// (which would be represented by the type `PolyTraitRef == |
|
/// Binder<TraitRef>`). Note that when we skolemize, instantiate, |
|
/// erase, or otherwise "discharge" these bound regions, we change the |
|
/// type from `Binder<T>` to just `T` (see |
|
/// e.g. `liberate_late_bound_regions`). |
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] |
|
pub struct Binder<T>(pub T); |
I have long wanted to make that field private and thus to force users of Binder to go through the more "high-level" methods (as an aside, it might be nice to move binder to its own module too, so that ty can't use its private fields).
Right now, when we do ty::Binder(value), that means that any things with a debruijn-index of 1 (soon to be zero) in value will be bound by this binder. Maybe we can add a ty::Binder::bind(value) for this.
On the other hand, there are times when we do not expect value to have any bound regions in it -- for those cases we often use ty::Binder(value) today, but it'd be better if used ty::Binder::dummy(value), which adds an assertion.
Similarly, any attempt to directly access the "bound" value (binder.0) is better written with binder.skip_binder(), which makes it more clear what's happening. Better yet is to add an accessor, somewhat like the def_id function defined on Binder<TraitRef<'tcx>>. This is currently written to access the field 0 directly, which is bad, but the good part is that it is "safe" to do, because DefId is a type that never contains a bound name:
|
pub fn def_id(&self) -> DefId { |
|
self.0.def_id |
|
} |
Note that accessing fields which may have bound names should ideally preserve the binding level, like the inputs function on Binder<FnSig<'tcx>>:
|
pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> { |
|
Binder(self.skip_binder().inputs()) |
|
} |
This is saying, given a function like for<'a> fn(&'a u32) -> &'a u32, we get back a list of input types like for<'a> [&'a u32]. Note that the binder is preserved. (Internally, though, it could be rewritten to use the helper Binder::map_bound:
|
pub fn map_bound<F, U>(self, f: F) -> Binder<U> |
|
where F: FnOnce(T) -> U |
|
{ |
|
ty::Binder(f(self.0)) |
|
} |
Part of #49810.
The
Bindertype is used to represent higher-ranked regions:rust/src/librustc/ty/sty.rs
Lines 645 to 653 in 4b9b70c
I have long wanted to make that field private and thus to force users of
Binderto go through the more "high-level" methods (as an aside, it might be nice to move binder to its own module too, so thattycan't use its private fields).Right now, when we do
ty::Binder(value), that means that any things with a debruijn-index of 1 (soon to be zero) invaluewill be bound by this binder. Maybe we can add aty::Binder::bind(value)for this.On the other hand, there are times when we do not expect
valueto have any bound regions in it -- for those cases we often usety::Binder(value)today, but it'd be better if usedty::Binder::dummy(value), which adds an assertion.Similarly, any attempt to directly access the "bound" value (
binder.0) is better written withbinder.skip_binder(), which makes it more clear what's happening. Better yet is to add an accessor, somewhat like thedef_idfunction defined onBinder<TraitRef<'tcx>>. This is currently written to access the field0directly, which is bad, but the good part is that it is "safe" to do, becauseDefIdis a type that never contains a bound name:rust/src/librustc/ty/sty.rs
Lines 573 to 575 in 4b9b70c
Note that accessing fields which may have bound names should ideally preserve the binding level, like the
inputsfunction onBinder<FnSig<'tcx>>:rust/src/librustc/ty/sty.rs
Lines 841 to 843 in 4b9b70c
This is saying, given a function like
for<'a> fn(&'a u32) -> &'a u32, we get back a list of input types likefor<'a> [&'a u32]. Note that the binder is preserved. (Internally, though, it could be rewritten to use the helperBinder::map_bound:rust/src/librustc/ty/sty.rs
Lines 697 to 701 in 4b9b70c