From 9131f95c6f0dd849b2f70ef2ded5d90ee4b0e54a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 15 Jun 2019 01:56:10 +0200 Subject: [PATCH] typeck/expr.rs: extract out check_expr_path. --- src/librustc_typeck/check/expr.rs | 119 +++++++++++++++--------------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 4e6282161417b..cb626da0294bb 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -47,7 +47,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let tcx = self.tcx; - let id = expr.hir_id; match expr.node { ExprKind::Box(ref subexpr) => { self.check_expr_box(subexpr, expected) @@ -68,63 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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, - expr.span); - let ty = match res { - Res::Err => { - self.set_tainted_by_errors(); - tcx.types.err - } - Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { - report_unexpected_variant_res(tcx, res, expr.span, qpath); - tcx.types.err - } - _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, id).0, - }; - - if let ty::FnDef(..) = ty.sty { - let fn_sig = ty.fn_sig(tcx); - if !tcx.features().unsized_locals { - // We want to remove some Sized bounds from std functions, - // but don't want to expose the removal to stable Rust. - // i.e., we don't want to allow - // - // ```rust - // drop as fn(str); - // ``` - // - // to work in stable even if the Sized bound on `drop` is relaxed. - for i in 0..fn_sig.inputs().skip_binder().len() { - // We just want to check sizedness, so instead of introducing - // placeholder lifetimes with probing, we just replace higher lifetimes - // with fresh vars. - let input = self.replace_bound_vars_with_fresh_vars( - expr.span, - infer::LateBoundRegionConversionTime::FnCall, - &fn_sig.input(i)).0; - self.require_type_is_sized_deferred(input, expr.span, - traits::SizedArgumentType); - } - } - // Here we want to prevent struct constructors from returning unsized types. - // There were two cases this happened: fn pointer coercion in stable - // and usual function call in presense of unsized_locals. - // Also, as we just want to check sizedness, instead of introducing - // placeholder lifetimes with probing, we just replace higher lifetimes - // with fresh vars. - let output = self.replace_bound_vars_with_fresh_vars( - expr.span, - infer::LateBoundRegionConversionTime::FnCall, - &fn_sig.output()).0; - self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType); - } - - // We always require that the type provided as the value for - // a type parameter outlives the moment of instantiation. - let substs = self.tables.borrow().node_substs(expr.hir_id); - self.add_wf_bounds(substs, expr); - - ty + self.check_expr_path(qpath, expr) } ExprKind::InlineAsm(_, ref outputs, ref inputs) => { for expr in outputs.iter().chain(inputs.iter()) { @@ -722,4 +665,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.mk_ref(region, tm) } } + + fn check_expr_path(&self, qpath: &hir::QPath, expr: &'tcx hir::Expr) -> Ty<'tcx> { + let tcx = self.tcx; + let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span); + let ty = match res { + Res::Err => { + self.set_tainted_by_errors(); + tcx.types.err + } + Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { + report_unexpected_variant_res(tcx, res, expr.span, qpath); + tcx.types.err + } + _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, + }; + + if let ty::FnDef(..) = ty.sty { + let fn_sig = ty.fn_sig(tcx); + if !tcx.features().unsized_locals { + // We want to remove some Sized bounds from std functions, + // but don't want to expose the removal to stable Rust. + // i.e., we don't want to allow + // + // ```rust + // drop as fn(str); + // ``` + // + // to work in stable even if the Sized bound on `drop` is relaxed. + for i in 0..fn_sig.inputs().skip_binder().len() { + // We just want to check sizedness, so instead of introducing + // placeholder lifetimes with probing, we just replace higher lifetimes + // with fresh vars. + let input = self.replace_bound_vars_with_fresh_vars( + expr.span, + infer::LateBoundRegionConversionTime::FnCall, + &fn_sig.input(i)).0; + self.require_type_is_sized_deferred(input, expr.span, + traits::SizedArgumentType); + } + } + // Here we want to prevent struct constructors from returning unsized types. + // There were two cases this happened: fn pointer coercion in stable + // and usual function call in presense of unsized_locals. + // Also, as we just want to check sizedness, instead of introducing + // placeholder lifetimes with probing, we just replace higher lifetimes + // with fresh vars. + let output = self.replace_bound_vars_with_fresh_vars( + expr.span, + infer::LateBoundRegionConversionTime::FnCall, + &fn_sig.output()).0; + self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType); + } + + // We always require that the type provided as the value for + // a type parameter outlives the moment of instantiation. + let substs = self.tables.borrow().node_substs(expr.hir_id); + self.add_wf_bounds(substs, expr); + + ty + } }