@@ -283,58 +283,84 @@ pub enum Variance {
283283
284284#[ derive( Copy , Clone , Debug ) ]
285285pub enum AutoAdjustment < ' tcx > {
286- AdjustReifyFnPointer , // go from a fn-item type to a fn-pointer type
287- AdjustUnsafeFnPointer , // go from a safe fn pointer to an unsafe fn pointer
286+ AdjustReifyFnPointer , // go from a fn-item type to a fn-pointer type
287+ AdjustUnsafeFnPointer , // go from a safe fn pointer to an unsafe fn pointer
288288 AdjustDerefRef ( AutoDerefRef < ' tcx > ) ,
289289}
290290
291291/// Represents coercing a pointer to a different kind of pointer - where 'kind'
292292/// here means either or both of raw vs borrowed vs unique and fat vs thin.
293- /// The simplest cases are where the pointer is not adjusted fat vs thin. Here
294- /// the pointer will be dereferenced N times (where a dereference can happen to
295- /// to raw or borrowed pointers or any smart pointer which implements Deref,
296- /// including Box<_>). The number of dereferences is given by `autoderefs`.
297- /// It can then be auto-referenced zero or one times, indicated by `autoref`, to
298- /// either a raw or borrowed pointer. In these cases unsize is None.
299293///
300- /// A DST coercon involves unsizing the underlying data. We start with a thin
301- /// pointer, deref a number of times, unsize the underlying data, then autoref.
302- /// The 'unsize' phase may change a fixed length array to a dynamically sized one,
303- /// a concrete object to a trait object, or statically sized struct to a dyncamically
304- /// sized one.
305- /// E.g., &[i32; 4] -> &[i32] is represented by:
294+ /// We transform pointers by following the following steps in order:
295+ /// 1. Deref the pointer `self.autoderefs` times (may be 0).
296+ /// 2. If `autoref` is `Some(_)`, then take the address and produce either a
297+ /// `&` or `*` pointer.
298+ /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
299+ /// which will do things like convert thin pointers to fat
300+ /// pointers, or convert structs containing thin pointers to
301+ /// structs containing fat pointers, or convert between fat
302+ /// pointers. We don't store the details of how the transform is
303+ /// done (in fact, we don't know that, because it might depend on
304+ /// the precise type parameters). We just store the target
305+ /// type. Trans figures out what has to be done at monomorphization
306+ /// time based on the precise source/target type at hand.
307+ ///
308+ /// To make that more concrete, here are some common scenarios:
309+ ///
310+ /// 1. The simplest cases are where the pointer is not adjusted fat vs thin.
311+ /// Here the pointer will be dereferenced N times (where a dereference can
312+ /// happen to to raw or borrowed pointers or any smart pointer which implements
313+ /// Deref, including Box<_>). The number of dereferences is given by
314+ /// `autoderefs`. It can then be auto-referenced zero or one times, indicated
315+ /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
316+ /// None.
317+ ///
318+ /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start
319+ /// with a thin pointer, deref a number of times, unsize the underlying data,
320+ /// then autoref. The 'unsize' phase may change a fixed length array to a
321+ /// dynamically sized one, a concrete object to a trait object, or statically
322+ /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is
323+ /// represented by:
324+ ///
325+ /// ```
306326/// AutoDerefRef {
307327/// autoderefs: 1, // &[i32; 4] -> [i32; 4]
308- /// unsize: Some([i32]), // [i32; 4] -> [i32]
309328/// autoref: Some(AutoPtr), // [i32] -> &[i32]
329+ /// unsize: Some([i32]), // [i32; 4] -> [i32]
310330/// }
331+ /// ```
332+ ///
311333/// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
312334/// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
313335/// The autoderef and -ref are the same as in the above example, but the type
314336/// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
315337/// the underlying conversions from `[i32; 4]` to `[i32]`.
316338///
317- /// Box pointers are treated somewhat differently, the last deref is not counted,
318- /// nor is the 'ref' to a `Box<_>`. Imagine them more like structs.
319- /// E.g., Box<[i32; 4]> -> Box<[i32]> is represented by:
339+ /// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case. In
340+ /// that case, we have the pointer we need coming in, so there are no
341+ /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
342+ /// At some point, of course, `Box` should move out of the compiler, in which
343+ /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> ->
344+ /// Box<[i32]> is represented by:
345+ ///
346+ /// ```
320347/// AutoDerefRef {
321348/// autoderefs: 0,
322- /// unsize: Some(Box<[i32]>),
323349/// autoref: None,
350+ /// unsize: Some(Box<[i32]>),
324351/// }
352+ /// ```
325353#[ derive( Copy , Clone , Debug ) ]
326354pub struct AutoDerefRef < ' tcx > {
327- // FIXME with more powerful date structures we could have a better design
328- // here.
329-
330- /// Apply a number of dereferences, producing an lvalue.
355+ /// Step 1. Apply a number of dereferences, producing an lvalue.
331356 pub autoderefs : usize ,
332357
333- /// Produce a pointer/reference from the value.
358+ /// Step 2. Optionally produce a pointer/reference from the value.
334359 pub autoref : Option < AutoRef < ' tcx > > ,
335360
336- /// Unsize a pointer/reference value, e.g. &[T; n] to &[T].
337- /// The stored type is the target pointer type.
361+ /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to
362+ /// `&[T]`. The stored type is the target pointer type. Note that
363+ /// the source could be a thin or fat pointer.
338364 pub unsize : Option < Ty < ' tcx > > ,
339365}
340366
0 commit comments