Skip to content

Commit 937ac2b

Browse files
eddybnrc
authored andcommitted
eddyb's refactoring of coercions/adjustments
1 parent 588d37c commit 937ac2b

25 files changed

+815
-1490
lines changed

src/librustc/middle/astencode.rs

Lines changed: 59 additions & 215 deletions
Large diffs are not rendered by default.

src/librustc/middle/expr_use_visitor.rs

Lines changed: 29 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -787,23 +787,30 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
787787
// process.
788788
fn walk_adjustment(&mut self, expr: &ast::Expr) {
789789
let typer = self.typer;
790-
match typer.adjustments().borrow().get(&expr.id) {
791-
None => { }
792-
Some(adjustment) => {
793-
match *adjustment {
794-
ty::AdjustReifyFnPointer(..) |
795-
ty::AdjustUnsafeFnPointer(..) => {
796-
// Creating a closure/fn-pointer consumes the
797-
// input and stores it into the resulting
798-
// rvalue.
799-
debug!("walk_adjustment(AutoAddEnv|AdjustReifyFnPointer)");
790+
if let Some(adjustment) = typer.adjustments().borrow().get(&expr.id) {
791+
match *adjustment {
792+
ty::AdjustReifyFnPointer |
793+
ty::AdjustUnsafeFnPointer => {
794+
// Creating a closure/fn-pointer or unsizing consumes
795+
// the input and stores it into the resulting rvalue.
796+
debug!("walk_adjustment(AdjustReifyFnPointer|AdjustUnsafeFnPointer)");
797+
let cmt_unadjusted =
798+
return_if_err!(self.mc.cat_expr_unadjusted(expr));
799+
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
800+
}
801+
ty::AdjustDerefRef(ref adj) => {
802+
self.walk_autoderefs(expr, adj.autoderefs);
803+
if let Some(ref r) = adj.autoref {
804+
self.walk_autoref(expr, r, adj.autoderefs);
805+
} else if adj.unsize.is_some() {
806+
assert!(adj.autoderefs == 0,
807+
format!("Expected no derefs with \
808+
unsize AutoRefs, found: {}",
809+
adj.repr(self.tcx())));
800810
let cmt_unadjusted =
801811
return_if_err!(self.mc.cat_expr_unadjusted(expr));
802812
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
803813
}
804-
ty::AdjustDerefRef(ref adj) => {
805-
self.walk_autoderefref(expr, adj);
806-
}
807814
}
808815
}
809816
}
@@ -818,7 +825,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
818825
debug!("walk_autoderefs expr={} autoderefs={}", expr.repr(self.tcx()), autoderefs);
819826

820827
for i in 0..autoderefs {
821-
let deref_id = ty::MethodCall::autoderef(expr.id, i);
828+
let deref_id = ty::MethodCall::autoderef(expr.id, i as u32);
822829
match self.typer.node_method_ty(deref_id) {
823830
None => {}
824831
Some(method_ty) => {
@@ -903,59 +910,22 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
903910
}
904911
};
905912

906-
match *autoref {
907-
ty::AutoPtr(r, m, ref baseref) => {
908-
let cmt_base = self.walk_autoref_recursively(expr, cmt_derefd, baseref);
913+
let cmt_base = self.walk_autoref_recursively(expr, cmt_derefd, baseref);
909914

910-
debug!("walk_autoref: expr.id={} cmt_base={}",
911-
expr.id,
912-
cmt_base.repr(self.tcx()));
915+
debug!("walk_autoref: expr.id={} cmt_base={}",
916+
expr.id,
917+
cmt_base.repr(self.tcx()));
913918

919+
match *autoref {
920+
ty::AutoPtr(r, m) => {
914921
self.delegate.borrow(expr.id,
915922
expr.span,
916-
cmt_base,
917-
r,
923+
cmt_derefd,
924+
*r,
918925
ty::BorrowKind::from_mutbl(m),
919926
AutoRef);
920927
}
921928

922-
ty::AutoUnsize(_) => {
923-
// Converting a `[T; N]` to `[T]` or `T` to `Trait`
924-
// isn't really a borrow, move, etc, in and of itself.
925-
// Also, no recursive step here, this is a base case.
926-
927-
// It may seem a bit odd to return the cmt_derefd
928-
// unmodified here, but in fact I think it's the right
929-
// thing to do. Essentially the unsize transformation
930-
// isn't really relevant to the borrowing rules --
931-
// it's best thought of as a kind of side-modifier to
932-
// the autoref, adding additional data that is
933-
// attached to the pointer that is produced, but not
934-
// affecting the data being borrowed in any other
935-
// way. To see what I mean, consider this example:
936-
//
937-
// fn foo<'a>(&'a self) -> &'a Trait { self }
938-
//
939-
// This is valid because the underlying `self` value
940-
// lives for the lifetime 'a. If we were to treat the
941-
// "unsizing" as e.g. producing an rvalue, that would
942-
// only be valid for the temporary scope, which isn't
943-
// enough to justify the return value, which have the
944-
// lifetime 'a.
945-
//
946-
// Another option would be to add a variant for
947-
// categorization (like downcast) that wraps
948-
// cmt_derefd and represents the unsizing operation.
949-
// But I don't think there is any particular use for
950-
// this (yet). -nmatsakis
951-
return cmt_derefd.clone();
952-
}
953-
954-
ty::AutoUnsizeUniq(_) => {
955-
// these are handled via special case above
956-
self.tcx().sess.span_bug(expr.span, "nexpected AutoUnsizeUniq");
957-
}
958-
959929
ty::AutoUnsafe(m, ref baseref) => {
960930
let cmt_base = self.walk_autoref_recursively(expr, cmt_derefd, baseref);
961931

src/librustc/middle/mem_categorization.rs

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -451,33 +451,23 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
451451

452452
Some(adjustment) => {
453453
match *adjustment {
454-
ty::AdjustReifyFnPointer(..) |
455-
ty::AdjustUnsafeFnPointer(..) => {
456-
debug!("cat_expr(AdjustReifyFnPointer): {}",
457-
expr.repr(self.tcx()));
458-
// Convert a bare fn to a closure by adding NULL env.
459-
// Result is an rvalue.
460-
let expr_ty = try!(self.expr_ty_adjusted(expr));
461-
Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
462-
}
463-
464454
ty::AdjustDerefRef(
465455
ty::AutoDerefRef {
466-
autoref: Some(_), ..}) => {
467-
debug!("cat_expr(AdjustDerefRef): {}",
456+
autoref: None, unsize: None, autoderefs, ..}) => {
457+
// Equivalent to *expr or something similar.
458+
self.cat_expr_autoderefd(expr, autoderefs)
459+
}
460+
461+
ty::AdjustReifyFnPointer |
462+
ty::AdjustUnsafeFnPointer |
463+
ty::AdjustDerefRef(_) => {
464+
debug!("cat_expr({}): {}",
465+
adjustment.repr(self.tcx()),
468466
expr.repr(self.tcx()));
469-
// Equivalent to &*expr or something similar.
470467
// Result is an rvalue.
471468
let expr_ty = try!(self.expr_ty_adjusted(expr));
472469
Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
473470
}
474-
475-
ty::AdjustDerefRef(
476-
ty::AutoDerefRef {
477-
autoref: None, autoderefs}) => {
478-
// Equivalent to *expr or something similar.
479-
self.cat_expr_autoderefd(expr, autoderefs)
480-
}
481471
}
482472
}
483473
}
@@ -928,15 +918,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
928918
deref_cnt: usize,
929919
deref_context: DerefKindContext)
930920
-> McResult<cmt<'tcx>> {
931-
let adjustment = match self.typer.adjustments().borrow().get(&node.id()) {
932-
Some(adj) if ty::adjust_is_object(adj) => ty::AutoObject,
933-
_ if deref_cnt != 0 => ty::AutoDeref(deref_cnt),
934-
_ => ty::NoAdjustment
935-
};
936-
937921
let method_call = ty::MethodCall {
938922
expr_id: node.id(),
939-
adjustment: adjustment
923+
autoderef: deref_cnt as u32
940924
};
941925
let method_ty = self.typer.node_method_ty(method_call);
942926

0 commit comments

Comments
 (0)