Skip to content

Commit e26bb1d

Browse files
authored
Unrolled build for rust-lang#132297
Rollup merge of rust-lang#132297 - compiler-errors:check-expr-tweaks, r=lcnr Document some `check_expr` methods, and other misc `hir_typeck` tweaks Most importantly, make sure that all of the expression checking functions that are called from `check_expr_kind` start with `check_expr_*`. This is super useful to me personally, since I grep these functions all the time, and the ones that *aren't* named consistently are incredibly hard to find. Also document more of the `check_expr_*` functions, and squash two args for passing data about a call expr into one `Option`.
2 parents 81eef2d + 86da250 commit e26bb1d

File tree

6 files changed

+63
-53
lines changed

6 files changed

+63
-53
lines changed

compiler/rustc_hir_typeck/src/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{Diverges, Expectation, FnCtxt, Needs};
1515

1616
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1717
#[instrument(skip(self), level = "debug", ret)]
18-
pub(crate) fn check_match(
18+
pub(crate) fn check_expr_match(
1919
&self,
2020
expr: &'tcx hir::Expr<'tcx>,
2121
scrut: &'tcx hir::Expr<'tcx>,

compiler/rustc_hir_typeck/src/callee.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ enum CallStep<'tcx> {
6262
}
6363

6464
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
65-
pub(crate) fn check_call(
65+
pub(crate) fn check_expr_call(
6666
&self,
6767
call_expr: &'tcx hir::Expr<'tcx>,
6868
callee_expr: &'tcx hir::Expr<'tcx>,
@@ -74,8 +74,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7474
.check_expr_with_expectation_and_args(
7575
callee_expr,
7676
Expectation::NoExpectation,
77-
arg_exprs,
78-
Some(call_expr),
77+
Some((call_expr, arg_exprs)),
7978
),
8079
_ => self.check_expr(callee_expr),
8180
};

compiler/rustc_hir_typeck/src/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub(super) fn check_fn<'a, 'tcx>(
137137
}
138138

139139
fcx.is_whole_body.set(true);
140-
fcx.check_return_expr(body.value, false);
140+
fcx.check_return_or_body_tail(body.value, false);
141141

142142
// Finalize the return check by taking the LUB of the return types
143143
// we saw and assigning it to the expected return type. This isn't

compiler/rustc_hir_typeck/src/expr.rs

+53-42
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ use crate::{
5555
};
5656

5757
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
58+
/// Check an expr with an expectation type, and also demand that the expr's
59+
/// evaluated type is a subtype of the expectation at the end. This is a
60+
/// *hard* requirement.
5861
pub(crate) fn check_expr_has_type_or_error(
5962
&self,
6063
expr: &'tcx hir::Expr<'tcx>,
@@ -97,6 +100,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
97100
ty
98101
}
99102

103+
/// Check an expr with an expectation type, and also demand that the expr's
104+
/// evaluated type is a coercible to the expectation at the end. This is a
105+
/// *hard* requirement.
100106
pub(super) fn check_expr_coercible_to_type(
101107
&self,
102108
expr: &'tcx hir::Expr<'tcx>,
@@ -128,6 +134,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128134
}
129135
}
130136

137+
/// Check an expr with an expectation type. Don't actually enforce that expectation
138+
/// is related to the expr's evaluated type via subtyping or coercion. This is
139+
/// usually called because we want to do that subtype/coerce call manually for better
140+
/// diagnostics.
131141
pub(super) fn check_expr_with_hint(
132142
&self,
133143
expr: &'tcx hir::Expr<'tcx>,
@@ -136,6 +146,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
136146
self.check_expr_with_expectation(expr, ExpectHasType(expected))
137147
}
138148

149+
/// Check an expr with an expectation type, and also [`Needs`] which will
150+
/// prompt typeck to convert any implicit immutable derefs to mutable derefs.
139151
fn check_expr_with_expectation_and_needs(
140152
&self,
141153
expr: &'tcx hir::Expr<'tcx>,
@@ -153,10 +165,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
153165
ty
154166
}
155167

168+
/// Check an expr with no expectations.
156169
pub(super) fn check_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
157170
self.check_expr_with_expectation(expr, NoExpectation)
158171
}
159172

173+
/// Check an expr with no expectations, but with [`Needs`] which will
174+
/// prompt typeck to convert any implicit immutable derefs to mutable derefs.
160175
pub(super) fn check_expr_with_needs(
161176
&self,
162177
expr: &'tcx hir::Expr<'tcx>,
@@ -165,33 +180,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
165180
self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
166181
}
167182

168-
/// Invariant:
169-
/// If an expression has any sub-expressions that result in a type error,
170-
/// inspecting that expression's type with `ty.references_error()` will return
171-
/// true. Likewise, if an expression is known to diverge, inspecting its
172-
/// type with `ty::type_is_bot` will return true (n.b.: since Rust is
173-
/// strict, _|_ can appear in the type of an expression that does not,
174-
/// itself, diverge: for example, fn() -> _|_.)
175-
/// Note that inspecting a type's structure *directly* may expose the fact
176-
/// that there are actually multiple representations for `Error`, so avoid
177-
/// that when err needs to be handled differently.
183+
/// Check an expr with an expectation type which may be used to eagerly
184+
/// guide inference when evaluating that expr.
178185
#[instrument(skip(self, expr), level = "debug")]
179186
pub(super) fn check_expr_with_expectation(
180187
&self,
181188
expr: &'tcx hir::Expr<'tcx>,
182189
expected: Expectation<'tcx>,
183190
) -> Ty<'tcx> {
184-
self.check_expr_with_expectation_and_args(expr, expected, &[], None)
191+
self.check_expr_with_expectation_and_args(expr, expected, None)
185192
}
186193

187-
/// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
188-
/// `ExprKind::Call` when evaluating its callee when it is an `ExprKind::Path`.
194+
/// Same as [`Self::check_expr_with_expectation`], but allows us to pass in
195+
/// the arguments of a [`ExprKind::Call`] when evaluating its callee that
196+
/// is an [`ExprKind::Path`]. We use this to refine the spans for certain
197+
/// well-formedness guarantees for the path expr.
189198
pub(super) fn check_expr_with_expectation_and_args(
190199
&self,
191200
expr: &'tcx hir::Expr<'tcx>,
192201
expected: Expectation<'tcx>,
193-
args: &'tcx [hir::Expr<'tcx>],
194-
call: Option<&'tcx hir::Expr<'tcx>>,
202+
call_expr_and_args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
195203
) -> Ty<'tcx> {
196204
if self.tcx().sess.verbose_internals() {
197205
// make this code only run with -Zverbose-internals because it is probably slow
@@ -236,9 +244,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
236244
};
237245

238246
let ty = ensure_sufficient_stack(|| match &expr.kind {
247+
// Intercept the callee path expr and give it better spans.
239248
hir::ExprKind::Path(
240249
qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
241-
) => self.check_expr_path(qpath, expr, Some(args), call),
250+
) => self.check_expr_path(qpath, expr, call_expr_and_args),
242251
_ => self.check_expr_kind(expr, expected),
243252
});
244253
let ty = self.resolve_vars_if_possible(ty);
@@ -472,28 +481,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
472481

473482
let tcx = self.tcx;
474483
match expr.kind {
475-
ExprKind::Lit(ref lit) => self.check_lit(lit, expected),
476-
ExprKind::Binary(op, lhs, rhs) => self.check_binop(expr, op, lhs, rhs, expected),
484+
ExprKind::Lit(ref lit) => self.check_expr_lit(lit, expected),
485+
ExprKind::Binary(op, lhs, rhs) => self.check_expr_binop(expr, op, lhs, rhs, expected),
477486
ExprKind::Assign(lhs, rhs, span) => {
478487
self.check_expr_assign(expr, expected, lhs, rhs, span)
479488
}
480489
ExprKind::AssignOp(op, lhs, rhs) => {
481-
self.check_binop_assign(expr, op, lhs, rhs, expected)
490+
self.check_expr_binop_assign(expr, op, lhs, rhs, expected)
482491
}
483-
ExprKind::Unary(unop, oprnd) => self.check_expr_unary(unop, oprnd, expected, expr),
492+
ExprKind::Unary(unop, oprnd) => self.check_expr_unop(unop, oprnd, expected, expr),
484493
ExprKind::AddrOf(kind, mutbl, oprnd) => {
485494
self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
486495
}
487496
ExprKind::Path(QPath::LangItem(lang_item, _)) => {
488497
self.check_lang_item_path(lang_item, expr)
489498
}
490-
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None, None),
499+
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None),
491500
ExprKind::InlineAsm(asm) => {
492501
// We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
493502
self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
494503
self.check_expr_asm(asm)
495504
}
496-
ExprKind::OffsetOf(container, fields) => self.check_offset_of(container, fields, expr),
505+
ExprKind::OffsetOf(container, fields) => {
506+
self.check_expr_offset_of(container, fields, expr)
507+
}
497508
ExprKind::Break(destination, ref expr_opt) => {
498509
self.check_expr_break(destination, expr_opt.as_deref(), expr)
499510
}
@@ -512,13 +523,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
512523
self.check_expr_loop(body, source, expected, expr)
513524
}
514525
ExprKind::Match(discrim, arms, match_src) => {
515-
self.check_match(expr, discrim, arms, expected, match_src)
526+
self.check_expr_match(expr, discrim, arms, expected, match_src)
516527
}
517528
ExprKind::Closure(closure) => self.check_expr_closure(closure, expr.span, expected),
518-
ExprKind::Block(body, _) => self.check_block_with_expected(body, expected),
519-
ExprKind::Call(callee, args) => self.check_call(expr, callee, args, expected),
529+
ExprKind::Block(body, _) => self.check_expr_block(body, expected),
530+
ExprKind::Call(callee, args) => self.check_expr_call(expr, callee, args, expected),
520531
ExprKind::MethodCall(segment, receiver, args, _) => {
521-
self.check_method_call(expr, segment, receiver, args, expected)
532+
self.check_expr_method_call(expr, segment, receiver, args, expected)
522533
}
523534
ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
524535
ExprKind::Type(e, t) => {
@@ -528,7 +539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
528539
ascribed_ty
529540
}
530541
ExprKind::If(cond, then_expr, opt_else_expr) => {
531-
self.check_then_else(cond, then_expr, opt_else_expr, expr.span, expected)
542+
self.check_expr_if(cond, then_expr, opt_else_expr, expr.span, expected)
532543
}
533544
ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
534545
ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
@@ -540,7 +551,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
540551
ExprKind::Struct(qpath, fields, ref base_expr) => {
541552
self.check_expr_struct(expr, expected, qpath, fields, base_expr)
542553
}
543-
ExprKind::Field(base, field) => self.check_field(expr, base, field, expected),
554+
ExprKind::Field(base, field) => self.check_expr_field(expr, base, field, expected),
544555
ExprKind::Index(base, idx, brackets_span) => {
545556
self.check_expr_index(base, idx, expr, brackets_span)
546557
}
@@ -549,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
549560
}
550561
}
551562

552-
fn check_expr_unary(
563+
fn check_expr_unop(
553564
&self,
554565
unop: hir::UnOp,
555566
oprnd: &'tcx hir::Expr<'tcx>,
@@ -699,8 +710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
699710
&self,
700711
qpath: &'tcx hir::QPath<'tcx>,
701712
expr: &'tcx hir::Expr<'tcx>,
702-
args: Option<&'tcx [hir::Expr<'tcx>]>,
703-
call: Option<&'tcx hir::Expr<'tcx>>,
713+
call_expr_and_args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
704714
) -> Ty<'tcx> {
705715
let tcx = self.tcx;
706716
let (res, opt_ty, segs) =
@@ -730,7 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
730740
segs,
731741
opt_ty,
732742
res,
733-
call.map_or(expr.span, |e| e.span),
743+
call_expr_and_args.map_or(expr.span, |(e, _)| e.span),
734744
expr.span,
735745
expr.hir_id,
736746
)
@@ -769,7 +779,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
769779
// We just want to check sizedness, so instead of introducing
770780
// placeholder lifetimes with probing, we just replace higher lifetimes
771781
// with fresh vars.
772-
let span = args.and_then(|args| args.get(i)).map_or(expr.span, |arg| arg.span);
782+
let span = call_expr_and_args
783+
.and_then(|(_, args)| args.get(i))
784+
.map_or(expr.span, |arg| arg.span);
773785
let input = self.instantiate_binder_with_fresh_vars(
774786
span,
775787
infer::BoundRegionConversionTime::FnCall,
@@ -795,7 +807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
795807
);
796808
self.require_type_is_sized_deferred(
797809
output,
798-
call.map_or(expr.span, |e| e.span),
810+
call_expr_and_args.map_or(expr.span, |(e, _)| e.span),
799811
ObligationCauseCode::SizedCallReturnType,
800812
);
801813
}
@@ -972,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
972984
if self.ret_coercion_span.get().is_none() {
973985
self.ret_coercion_span.set(Some(e.span));
974986
}
975-
self.check_return_expr(e, true);
987+
self.check_return_or_body_tail(e, true);
976988
} else {
977989
let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
978990
if self.ret_coercion_span.get().is_none() {
@@ -1035,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10351047
///
10361048
/// `explicit_return` is `true` if we're checking an explicit `return expr`,
10371049
/// and `false` if we're checking a trailing expression.
1038-
pub(super) fn check_return_expr(
1050+
pub(super) fn check_return_or_body_tail(
10391051
&self,
10401052
return_expr: &'tcx hir::Expr<'tcx>,
10411053
explicit_return: bool,
@@ -1259,7 +1271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12591271

12601272
// A generic function for checking the 'then' and 'else' clauses in an 'if'
12611273
// or 'if-else' expression.
1262-
fn check_then_else(
1274+
fn check_expr_if(
12631275
&self,
12641276
cond_expr: &'tcx hir::Expr<'tcx>,
12651277
then_expr: &'tcx hir::Expr<'tcx>,
@@ -1542,7 +1554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15421554
}
15431555

15441556
/// Checks a method call.
1545-
fn check_method_call(
1557+
fn check_expr_method_call(
15461558
&self,
15471559
expr: &'tcx hir::Expr<'tcx>,
15481560
segment: &'tcx hir::PathSegment<'tcx>,
@@ -2594,7 +2606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25942606
}
25952607

25962608
// Check field access expressions
2597-
fn check_field(
2609+
fn check_expr_field(
25982610
&self,
25992611
expr: &'tcx hir::Expr<'tcx>,
26002612
base: &'tcx hir::Expr<'tcx>,
@@ -3535,8 +3547,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35353547
let previous_diverges = self.diverges.get();
35363548

35373549
// The label blocks should have unit return value or diverge.
3538-
let ty =
3539-
self.check_block_with_expected(block, ExpectHasType(self.tcx.types.unit));
3550+
let ty = self.check_expr_block(block, ExpectHasType(self.tcx.types.unit));
35403551
if !ty.is_never() {
35413552
self.demand_suptype(block.span, self.tcx.types.unit, ty);
35423553
diverge = false;
@@ -3551,7 +3562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35513562
if diverge { self.tcx.types.never } else { self.tcx.types.unit }
35523563
}
35533564

3554-
fn check_offset_of(
3565+
fn check_expr_offset_of(
35553566
&self,
35563567
container: &'tcx hir::Ty<'tcx>,
35573568
fields: &[Ident],

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1565,7 +1565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15651565
}
15661566

15671567
// AST fragment checking
1568-
pub(in super::super) fn check_lit(
1568+
pub(in super::super) fn check_expr_lit(
15691569
&self,
15701570
lit: &hir::Lit,
15711571
expected: Expectation<'tcx>,
@@ -1747,7 +1747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17471747

17481748
if let Some(blk) = decl.origin.try_get_else() {
17491749
let previous_diverges = self.diverges.get();
1750-
let else_ty = self.check_block_with_expected(blk, NoExpectation);
1750+
let else_ty = self.check_expr_block(blk, NoExpectation);
17511751
let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
17521752
if let Err(err) = self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty)
17531753
{
@@ -1805,7 +1805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18051805

18061806
pub(crate) fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
18071807
let unit = self.tcx.types.unit;
1808-
let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
1808+
let ty = self.check_expr_block(blk, ExpectHasType(unit));
18091809

18101810
// if the block produces a `!` value, that can always be
18111811
// (effectively) coerced to unit.
@@ -1814,7 +1814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18141814
}
18151815
}
18161816

1817-
pub(in super::super) fn check_block_with_expected(
1817+
pub(in super::super) fn check_expr_block(
18181818
&self,
18191819
blk: &'tcx hir::Block<'tcx>,
18201820
expected: Expectation<'tcx>,

compiler/rustc_hir_typeck/src/op.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::Expectation;
2626

2727
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2828
/// Checks a `a <op>= b`
29-
pub(crate) fn check_binop_assign(
29+
pub(crate) fn check_expr_binop_assign(
3030
&self,
3131
expr: &'tcx hir::Expr<'tcx>,
3232
op: hir::BinOp,
@@ -85,7 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8585
}
8686

8787
/// Checks a potentially overloaded binary operator.
88-
pub(crate) fn check_binop(
88+
pub(crate) fn check_expr_binop(
8989
&self,
9090
expr: &'tcx hir::Expr<'tcx>,
9191
op: hir::BinOp,

0 commit comments

Comments
 (0)