Skip to content

Commit 1f5f56b

Browse files
committed
Better explanation of AutoDerefRef
1 parent 840aa24 commit 1f5f56b

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

src/librustc/middle/expr_use_visitor.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
849849
self.walk_autoderefs(expr, adj.autoderefs);
850850

851851
// Weird hacky special case: AutoUnsizeUniq, which converts
852-
// from a Box<T> to a Box<Trait> etc, always comes in a stylized
852+
// from a ~T to a ~Trait etc, always comes in a stylized
853853
// fashion. In particular, we want to consume the ~ pointer
854854
// being dereferenced, not the dereferenced content (as the
855855
// content is, at least for upcasts, unsized).
@@ -865,7 +865,6 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
865865
}
866866
}
867867

868-
//let autoref = adj.autoref.as_ref();
869868
let cmt_derefd = return_if_err!(
870869
self.mc.cat_expr_autoderefd(expr, adj.autoderefs));
871870
self.walk_autoref(expr, cmt_derefd, adj.autoref);

src/librustc/middle/ty.rs

+35-4
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,44 @@ pub enum AutoAdjustment<'tcx> {
288288
AdjustDerefRef(AutoDerefRef<'tcx>),
289289
}
290290

291+
/// Represents coercing a pointer to a different kind of pointer - where 'kind'
292+
/// 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.
299+
///
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:
306+
/// AutoDerefRef {
307+
/// autoderefs: 1, // &[i32; 4] -> [i32; 4]
308+
/// unsize: Some([i32]), // [i32; 4] -> [i32]
309+
/// autoref: Some(AutoPtr), // [i32] -> &[i32]
310+
/// }
311+
/// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
312+
/// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
313+
/// The autoderef and -ref are the same as in the above example, but the type
314+
/// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
315+
/// the underlying conversions from `[i32; 4]` to `[i32]`.
316+
///
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:
320+
/// AutoDerefRef {
321+
/// autoderefs: 0,
322+
/// unsize: Some(Box<[i32]>),
323+
/// autoref: None,
324+
/// }
291325
#[derive(Copy, Clone, Debug)]
292326
pub struct AutoDerefRef<'tcx> {
293327
// FIXME with more powerful date structures we could have a better design
294-
// here. Some constraints:
295-
// unsize => autoref
296-
// unsize => autodefs == 0
297-
328+
// here.
298329

299330
/// Apply a number of dereferences, producing an lvalue.
300331
pub autoderefs: usize,

0 commit comments

Comments
 (0)