Skip to content

Commit 9131f95

Browse files
committed
typeck/expr.rs: extract out check_expr_path.
1 parent d5cc080 commit 9131f95

File tree

1 file changed

+61
-58
lines changed

1 file changed

+61
-58
lines changed

src/librustc_typeck/check/expr.rs

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4747
);
4848

4949
let tcx = self.tcx;
50-
let id = expr.hir_id;
5150
match expr.node {
5251
ExprKind::Box(ref subexpr) => {
5352
self.check_expr_box(subexpr, expected)
@@ -68,63 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6867
self.check_expr_addr_of(mutbl, oprnd, expected, expr)
6968
}
7069
ExprKind::Path(ref qpath) => {
71-
let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id,
72-
expr.span);
73-
let ty = match res {
74-
Res::Err => {
75-
self.set_tainted_by_errors();
76-
tcx.types.err
77-
}
78-
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
79-
report_unexpected_variant_res(tcx, res, expr.span, qpath);
80-
tcx.types.err
81-
}
82-
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, id).0,
83-
};
84-
85-
if let ty::FnDef(..) = ty.sty {
86-
let fn_sig = ty.fn_sig(tcx);
87-
if !tcx.features().unsized_locals {
88-
// We want to remove some Sized bounds from std functions,
89-
// but don't want to expose the removal to stable Rust.
90-
// i.e., we don't want to allow
91-
//
92-
// ```rust
93-
// drop as fn(str);
94-
// ```
95-
//
96-
// to work in stable even if the Sized bound on `drop` is relaxed.
97-
for i in 0..fn_sig.inputs().skip_binder().len() {
98-
// We just want to check sizedness, so instead of introducing
99-
// placeholder lifetimes with probing, we just replace higher lifetimes
100-
// with fresh vars.
101-
let input = self.replace_bound_vars_with_fresh_vars(
102-
expr.span,
103-
infer::LateBoundRegionConversionTime::FnCall,
104-
&fn_sig.input(i)).0;
105-
self.require_type_is_sized_deferred(input, expr.span,
106-
traits::SizedArgumentType);
107-
}
108-
}
109-
// Here we want to prevent struct constructors from returning unsized types.
110-
// There were two cases this happened: fn pointer coercion in stable
111-
// and usual function call in presense of unsized_locals.
112-
// Also, as we just want to check sizedness, instead of introducing
113-
// placeholder lifetimes with probing, we just replace higher lifetimes
114-
// with fresh vars.
115-
let output = self.replace_bound_vars_with_fresh_vars(
116-
expr.span,
117-
infer::LateBoundRegionConversionTime::FnCall,
118-
&fn_sig.output()).0;
119-
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
120-
}
121-
122-
// We always require that the type provided as the value for
123-
// a type parameter outlives the moment of instantiation.
124-
let substs = self.tables.borrow().node_substs(expr.hir_id);
125-
self.add_wf_bounds(substs, expr);
126-
127-
ty
70+
self.check_expr_path(qpath, expr)
12871
}
12972
ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
13073
for expr in outputs.iter().chain(inputs.iter()) {
@@ -722,4 +665,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
722665
self.tcx.mk_ref(region, tm)
723666
}
724667
}
668+
669+
fn check_expr_path(&self, qpath: &hir::QPath, expr: &'tcx hir::Expr) -> Ty<'tcx> {
670+
let tcx = self.tcx;
671+
let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
672+
let ty = match res {
673+
Res::Err => {
674+
self.set_tainted_by_errors();
675+
tcx.types.err
676+
}
677+
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
678+
report_unexpected_variant_res(tcx, res, expr.span, qpath);
679+
tcx.types.err
680+
}
681+
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
682+
};
683+
684+
if let ty::FnDef(..) = ty.sty {
685+
let fn_sig = ty.fn_sig(tcx);
686+
if !tcx.features().unsized_locals {
687+
// We want to remove some Sized bounds from std functions,
688+
// but don't want to expose the removal to stable Rust.
689+
// i.e., we don't want to allow
690+
//
691+
// ```rust
692+
// drop as fn(str);
693+
// ```
694+
//
695+
// to work in stable even if the Sized bound on `drop` is relaxed.
696+
for i in 0..fn_sig.inputs().skip_binder().len() {
697+
// We just want to check sizedness, so instead of introducing
698+
// placeholder lifetimes with probing, we just replace higher lifetimes
699+
// with fresh vars.
700+
let input = self.replace_bound_vars_with_fresh_vars(
701+
expr.span,
702+
infer::LateBoundRegionConversionTime::FnCall,
703+
&fn_sig.input(i)).0;
704+
self.require_type_is_sized_deferred(input, expr.span,
705+
traits::SizedArgumentType);
706+
}
707+
}
708+
// Here we want to prevent struct constructors from returning unsized types.
709+
// There were two cases this happened: fn pointer coercion in stable
710+
// and usual function call in presense of unsized_locals.
711+
// Also, as we just want to check sizedness, instead of introducing
712+
// placeholder lifetimes with probing, we just replace higher lifetimes
713+
// with fresh vars.
714+
let output = self.replace_bound_vars_with_fresh_vars(
715+
expr.span,
716+
infer::LateBoundRegionConversionTime::FnCall,
717+
&fn_sig.output()).0;
718+
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
719+
}
720+
721+
// We always require that the type provided as the value for
722+
// a type parameter outlives the moment of instantiation.
723+
let substs = self.tables.borrow().node_substs(expr.hir_id);
724+
self.add_wf_bounds(substs, expr);
725+
726+
ty
727+
}
725728
}

0 commit comments

Comments
 (0)