From d5cc080b738f25529200f7928bdad0b06011490d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 15 Jun 2019 01:50:33 +0200 Subject: [PATCH] typeck/expr.rs: extract out check_expr_addr_of. --- src/librustc_typeck/check/expr.rs | 86 +++++++++++++++++-------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 5244edebc387..4e6282161417 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -65,44 +65,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_unary(unop, oprnd, expected, needs, expr) } ExprKind::AddrOf(mutbl, ref oprnd) => { - let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { - match ty.sty { - ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { - if oprnd.is_place_expr() { - // Places may legitimately have unsized types. - // For example, dereferences of a fat pointer and - // the last field of a struct can be unsized. - ExpectHasType(ty) - } else { - Expectation::rvalue_hint(self, ty) - } - } - _ => NoExpectation - } - }); - let needs = Needs::maybe_mut_place(mutbl); - let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs); - - let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl }; - if tm.ty.references_error() { - tcx.types.err - } else { - // Note: at this point, we cannot say what the best lifetime - // is to use for resulting pointer. We want to use the - // shortest lifetime possible so as to avoid spurious borrowck - // errors. Moreover, the longest lifetime will depend on the - // precise details of the value whose address is being taken - // (and how long it is valid), which we don't know yet until type - // inference is complete. - // - // Therefore, here we simply generate a region variable. The - // region inferencer will then select the ultimate value. - // Finally, borrowck is charged with guaranteeing that the - // value whose address was taken can actually be made to live - // as long as it needs to live. - let region = self.next_region_var(infer::AddrOfRegion(expr.span)); - tcx.mk_ref(region, tm) - } + self.check_expr_addr_of(mutbl, oprnd, expected, expr) } ExprKind::Path(ref qpath) => { let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, @@ -712,4 +675,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } oprnd_t } + + fn check_expr_addr_of( + &self, + mutbl: hir::Mutability, + oprnd: &'tcx hir::Expr, + expected: Expectation<'tcx>, + expr: &'tcx hir::Expr, + ) -> Ty<'tcx> { + let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { + match ty.sty { + ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { + if oprnd.is_place_expr() { + // Places may legitimately have unsized types. + // For example, dereferences of a fat pointer and + // the last field of a struct can be unsized. + ExpectHasType(ty) + } else { + Expectation::rvalue_hint(self, ty) + } + } + _ => NoExpectation + } + }); + let needs = Needs::maybe_mut_place(mutbl); + let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs); + + let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl }; + if tm.ty.references_error() { + self.tcx.types.err + } else { + // Note: at this point, we cannot say what the best lifetime + // is to use for resulting pointer. We want to use the + // shortest lifetime possible so as to avoid spurious borrowck + // errors. Moreover, the longest lifetime will depend on the + // precise details of the value whose address is being taken + // (and how long it is valid), which we don't know yet until type + // inference is complete. + // + // Therefore, here we simply generate a region variable. The + // region inferencer will then select the ultimate value. + // Finally, borrowck is charged with guaranteeing that the + // value whose address was taken can actually be made to live + // as long as it needs to live. + let region = self.next_region_var(infer::AddrOfRegion(expr.span)); + self.tcx.mk_ref(region, tm) + } + } }