diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-01-07 10:53:09 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-01-08 09:19:07 -0500 |
| commit | 0a32010e430006d3850b74976d7d7bf0dda699b4 (patch) | |
| tree | 9a31823b2ff962dd601339a0ca091fee99228b37 | |
| parent | 5364c4853fa61aced8fdf773d9de41b929a0d318 (diff) | |
| download | rust-0a32010e430006d3850b74976d7d7bf0dda699b4.tar.gz rust-0a32010e430006d3850b74976d7d7bf0dda699b4.zip | |
Add comments to autoderef() helper and refactor it to take
an `Option<&Expr>` like everything else.
| -rw-r--r-- | src/librustc_typeck/check/method/confirm.rs | 12 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 49 | ||||
| -rw-r--r-- | src/librustc_typeck/check/regionck.rs | 10 |
4 files changed, 58 insertions, 21 deletions
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 7e72f300f41..79460774859 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -143,7 +143,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // time writing the results into the various tables. let (autoderefd_ty, n, result) = check::autoderef( - self.fcx, self.span, unadjusted_self_ty, Some(self.self_expr.id), NoPreference, + self.fcx, self.span, unadjusted_self_ty, Some(self.self_expr), NoPreference, |_, n| if n == auto_deref_ref.autoderefs { Some(()) } else { None }); assert_eq!(n, auto_deref_ref.autoderefs); assert_eq!(result, Some(())); @@ -492,7 +492,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { exprs.repr(self.tcx())); // Fix up autoderefs and derefs. - for (i, expr) in exprs.iter().rev().enumerate() { + for (i, &expr) in exprs.iter().rev().enumerate() { // Count autoderefs. let autoderef_count = match self.fcx .inh @@ -512,8 +512,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { if autoderef_count > 0 { check::autoderef(self.fcx, expr.span, - self.fcx.expr_ty(*expr), - Some(expr.id), + self.fcx.expr_ty(expr), + Some(expr), PreferMutLvalue, |_, autoderefs| { if autoderefs == autoderef_count + 1 { @@ -567,7 +567,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { let result = check::try_index_step( self.fcx, MethodCall::expr(expr.id), - *expr, + expr, &**base_expr, adjusted_base_ty, base_adjustment, @@ -577,7 +577,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { if let Some((input_ty, return_ty)) = result { demand::suptype(self.fcx, index_expr.span, input_ty, index_expr_ty); - let expr_ty = self.fcx.expr_ty(&**expr); + let expr_ty = self.fcx.expr_ty(&*expr); demand::suptype(self.fcx, expr.span, expr_ty, return_ty); } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index bb000742def..0c53a16a811 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -102,9 +102,9 @@ pub fn lookup<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, Ok(confirm::confirm(fcx, span, self_expr, call_expr, self_ty, pick, supplied_method_types)) } -pub fn lookup_in_trait<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, +pub fn lookup_in_trait<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span: Span, - self_expr: Option<&'a ast::Expr>, + self_expr: Option<&ast::Expr>, m_name: ast::Name, trait_def_id: DefId, self_ty: Ty<'tcx>, @@ -125,9 +125,9 @@ pub fn lookup_in_trait<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, /// method-lookup code. In particular, autoderef on index is basically identical to autoderef with /// normal probes, except that the test also looks for built-in indexing. Also, the second half of /// this method is basically the same as confirmation. -pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, +pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span: Span, - self_expr: Option<&'a ast::Expr>, + self_expr: Option<&ast::Expr>, m_name: ast::Name, trait_def_id: DefId, autoderefref: ty::AutoDerefRef<'tcx>, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index b98b327100c..4ade11a9a83 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2263,17 +2263,36 @@ pub enum LvaluePreference { /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide /// whether to terminate the loop. Returns the final type and number of derefs that it performed. /// +<<<<<<< HEAD /// Note: this method does not modify the adjustments table. The caller is responsible for /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods. pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, +||||||| merged common ancestors +/// Note: this method does not modify the adjustments table. The caller is responsible for +/// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods. +pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, +======= +/// Note: this method does not modify the adjustments table. The +/// caller is responsible for inserting an AutoAdjustment record into +/// the `fcx` using one of the suitable methods. However, if +/// `opt_expr` is not `None`, it *will* insert the appropriate method +/// entries for the overloaded deref call. +pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, + sp: Span, +>>>>>>> Add comments to autoderef() helper and refactor it to take base_ty: Ty<'tcx>, - expr_id: Option<ast::NodeId>, + opt_expr: Option<&ast::Expr>, mut lvalue_pref: LvaluePreference, mut should_stop: F) - -> (Ty<'tcx>, uint, Option<T>) where - F: FnMut(Ty<'tcx>, uint) -> Option<T>, + -> (Ty<'tcx>, uint, Option<T>) + where F: FnMut(Ty<'tcx>, uint) -> Option<T>, { + debug!("autoderef(base_ty={}, opt_expr={}, lvalue_pref={})", + base_ty.repr(fcx.tcx()), + opt_expr, + lvalue_pref); + let mut t = base_ty; for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) { let resolved_t = structurally_resolved_type(fcx, sp, t); @@ -2291,7 +2310,19 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, let mt = match ty::deref(resolved_t, false) { Some(mt) => Some(mt), None => { - let method_call = expr_id.map(|id| MethodCall::autoderef(id, autoderefs)); + let method_call = opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs)); + + // Super subtle: it might seem as though we should + // pass `opt_expr` to `try_overloaded_deref`, so that + // the (implicit) autoref of using an overloaded deref + // would get added to the adjustment table. However we + // do not do that, because it's kind of a + // "meta-adjustment" -- instead, we just leave it + // unrecorded and know that there "will be" an + // autoref. regionck and other bits of the code base, + // when they encounter an overloaded autoderef, have + // to do some reconstructive surgery. This is a pretty + // complex mess that is begging for a proper MIR. try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref) } }; @@ -2324,7 +2355,7 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // Try DerefMut first, if preferred. let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) { (PreferMutLvalue, Some(trait_did)) => { - method::lookup_in_trait(fcx, span, base_expr.map(|x| &*x), + method::lookup_in_trait(fcx, span, base_expr, token::intern("deref_mut"), trait_did, base_ty, None) } @@ -2334,7 +2365,7 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // Otherwise, fall back to Deref. let method = match (method, fcx.tcx().lang_items.deref_trait()) { (None, Some(trait_did)) => { - method::lookup_in_trait(fcx, span, base_expr.map(|x| &*x), + method::lookup_in_trait(fcx, span, base_expr, token::intern("deref"), trait_did, base_ty, None) } @@ -2390,7 +2421,7 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, // consolidated. let (ty, autoderefs, final_mt) = - autoderef(fcx, base_expr.span, base_ty, Some(base_expr.id), lvalue_pref, |adj_ty, idx| { + autoderef(fcx, base_expr.span, base_ty, Some(base_expr), lvalue_pref, |adj_ty, idx| { let autoderefref = ty::AutoDerefRef { autoderefs: idx, autoref: None }; step(adj_ty, autoderefref) }); @@ -3360,7 +3391,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.expr_ty(base)); // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop. let (_, autoderefs, field_ty) = - autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| { + autoderef(fcx, expr.span, expr_t, Some(base), lvalue_pref, |base_t, _| { match base_t.sty { ty::ty_struct(base_id, substs) => { debug!("struct named {}", ppaux::ty_to_string(tcx, base_t)); @@ -3421,7 +3452,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let mut tuple_like = false; // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop. let (_, autoderefs, field_ty) = - autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| { + autoderef(fcx, expr.span, expr_t, Some(base), lvalue_pref, |base_t, _| { match base_t.sty { ty::ty_struct(base_id, substs) => { tuple_like = ty::is_tuple_struct(tcx, base_id); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 112e0053642..c74612d3aa8 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1049,13 +1049,16 @@ fn type_of_node_must_outlive<'a, 'tcx>( /// Computes the guarantor for an expression `&base` and then ensures that the lifetime of the /// resulting pointer is linked to the lifetime of its guarantor (if any). fn link_addr_of(rcx: &mut Rcx, expr: &ast::Expr, - mutability: ast::Mutability, base: &ast::Expr) { - debug!("link_addr_of(base=?)"); + mutability: ast::Mutability, base: &ast::Expr) { + debug!("link_addr_of(expr={}, base={})", expr.repr(rcx.tcx()), base.repr(rcx.tcx())); let cmt = { let mc = mc::MemCategorizationContext::new(rcx.fcx); ignore_err!(mc.cat_expr(base)) }; + + debug!("link_addr_of: cmt={}", cmt.repr(rcx.tcx())); + link_region_from_node_type(rcx, expr.span, expr.id, mutability, cmt); } @@ -1182,6 +1185,9 @@ fn link_region_from_node_type<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, id: ast::NodeId, mutbl: ast::Mutability, cmt_borrowed: mc::cmt<'tcx>) { + debug!("link_region_from_node_type(id={}, mutbl={}, cmt_borrowed={})", + id, mutbl, cmt_borrowed.repr(rcx.tcx())); + let rptr_ty = rcx.resolve_node_type(id); if !ty::type_is_error(rptr_ty) { let tcx = rcx.fcx.ccx.tcx; |
