Skip to content

Commit 3f310ae

Browse files
committed
cleanup some code, adjust some comments
1 parent e580df6 commit 3f310ae

File tree

3 files changed

+65
-45
lines changed

3 files changed

+65
-45
lines changed

src/librustc/middle/expr_use_visitor.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -848,26 +848,16 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
848848

849849
self.walk_autoderefs(expr, adj.autoderefs);
850850

851-
// Weird hacky special case: AutoUnsizeUniq, which converts
852-
// from a ~T to a ~Trait etc, always comes in a stylized
853-
// fashion. In particular, we want to consume the ~ pointer
854-
// being dereferenced, not the dereferenced content (as the
855-
// content is, at least for upcasts, unsized).
856-
if let Some(ty) = adj.unsize {
857-
if let ty::ty_uniq(_) = ty.sty {
858-
assert!(adj.autoderefs == 0,
859-
format!("Expected no derefs with unsize AutoRefs, found: {}",
860-
adj.repr(self.tcx())));
861-
let cmt_unadjusted =
862-
return_if_err!(self.mc.cat_expr_unadjusted(expr));
863-
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
864-
return;
865-
}
866-
}
851+
let cmt_derefd =
852+
return_if_err!(self.mc.cat_expr_autoderefd(expr, adj.autoderefs));
867853

868-
let cmt_derefd = return_if_err!(
869-
self.mc.cat_expr_autoderefd(expr, adj.autoderefs));
870-
self.walk_autoref(expr, cmt_derefd, adj.autoref);
854+
let cmt_refd =
855+
self.walk_autoref(expr, cmt_derefd, adj.autoref);
856+
857+
if adj.unsize.is_some() {
858+
// Unsizing consumes the thin pointer and produces a fat one.
859+
self.delegate_consume(expr.id, expr.span, cmt_refd);
860+
}
871861
}
872862

873863

src/librustc/middle/ty.rs

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -290,51 +290,77 @@ pub enum AutoAdjustment<'tcx> {
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
293+
/// We transform pointers by following the following steps in order:
294+
/// 1. Deref the pointer `self.autoderefs` times (may be 0).
295+
/// 2. If `autoref` is `Some(_)`, then take the address and produce either a
296+
/// `&` or `*` pointer.
297+
/// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
298+
/// which will do things like convert thin pointers to fat
299+
/// pointers, or convert structs containing thin pointers to
300+
/// structs containing fat pointers, or convert between fat
301+
/// pointers. We don't store the details of how the transform is
302+
/// done (in fact, we don't know that, because it might depend on
303+
/// the precise type parameters). We just store the target
304+
/// type. Trans figures out what has to be done at monomorphization
305+
/// time based on the precise source/target type at hand.
306+
///
307+
/// To make that more concrete, here are some common scenarios:
308+
///
309+
/// 1. The simplest cases are where the pointer is not adjusted fat vs
310+
/// thin. Here the pointer will be dereferenced N times (where a
311+
/// dereference can happen to to raw or borrowed pointers or any smart
312+
/// pointer which implements Deref, including Box<_>). The number of
313+
/// dereferences is given by `autoderefs`. It can then be
314+
/// auto-referenced zero or one times, indicated by `autoref`, to
298315
/// either a raw or borrowed pointer. In these cases unsize is None.
299316
///
300-
/// A DST coercon involves unsizing the underlying data. We start with a thin
317+
/// 2. A thin-to-fat coercon involves unsizing the underlying data. We start with a thin
301318
/// pointer, deref a number of times, unsize the underlying data, then autoref.
302319
/// The 'unsize' phase may change a fixed length array to a dynamically sized one,
303320
/// 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:
321+
/// sized one. E.g., &[i32; 4] -> &[i32] is represented by:
322+
///
323+
/// ```
306324
/// AutoDerefRef {
307325
/// autoderefs: 1, // &[i32; 4] -> [i32; 4]
308-
/// unsize: Some([i32]), // [i32; 4] -> [i32]
309326
/// autoref: Some(AutoPtr), // [i32] -> &[i32]
327+
/// unsize: Some([i32]), // [i32; 4] -> [i32]
310328
/// }
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]`.
329+
/// ```
316330
///
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:
331+
/// Note that for a struct, the 'deep' unsizing of the struct is not
332+
/// recorded. E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32;
333+
/// 4]> to &Foo<[i32]> The autoderef and -ref are the same as in the
334+
/// above example, but the type stored in `unsize` is `Foo<[i32]>`, we
335+
/// don't store any further detail about the underlying conversions
336+
/// from `[i32; 4]` to `[i32]`.
337+
///
338+
/// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special
339+
/// case. In that case, we have the pointer we need coming in, so
340+
/// there are no autoderefs, and no autoref. Instead we just do the
341+
/// `Unsize` transformation. At some point, of course, `Box` should
342+
/// move out of the compiler, in which case this is analogous to
343+
/// transformating a struct. E.g., Box<[i32; 4]> -> Box<[i32]> is
344+
/// 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)]
326354
pub 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

@@ -5831,6 +5857,7 @@ pub fn struct_lockstep_tails<'tcx>(cx: &ctxt<'tcx>,
58315857
source: Ty<'tcx>,
58325858
target: Ty<'tcx>)
58335859
-> (Ty<'tcx>, Ty<'tcx>) {
5860+
// NIT: Maybe move `struct_lockstep_tails` into trans, since it is only used there?
58345861
let (mut a, mut b) = (source, target);
58355862
while let (&ty_struct(a_did, a_substs), &ty_struct(b_did, b_substs)) = (&a.sty, &b.sty) {
58365863
if a_did != b_did {

src/librustc_typeck/check/method/confirm.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
143143
ty::adjust_ty_for_autoref(self.tcx(), target, Some(autoref))
144144
}))
145145
} else {
146-
// No unsizing should be performed without autoref.
146+
// No unsizing should be performed without autoref (at
147+
// least during method dispach). This is because we
148+
// currently only unsize `[T;N]` to `[T]`, and naturally
149+
// that must occur being a reference.
147150
assert!(pick.unsize.is_none());
148151
(None, None)
149152
};

0 commit comments

Comments
 (0)