]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Auto merge of #88988 - Mark-Simulacrum:avoid-into-ok, r=nagisa
[rust.git] / compiler / rustc_typeck / src / check / fn_ctxt / checks.rs
1 use crate::astconv::AstConv;
2 use crate::check::coercion::CoerceMany;
3 use crate::check::method::MethodCallee;
4 use crate::check::Expectation::*;
5 use crate::check::TupleArgumentsFlag::*;
6 use crate::check::{
7     potentially_plural_count, struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt,
8     LocalTy, Needs, TupleArgumentsFlag,
9 };
10
11 use rustc_ast as ast;
12 use rustc_data_structures::sync::Lrc;
13 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
14 use rustc_hir as hir;
15 use rustc_hir::def::{CtorOf, DefKind, Res};
16 use rustc_hir::def_id::DefId;
17 use rustc_hir::{ExprKind, Node, QPath};
18 use rustc_middle::ty::adjustment::AllowTwoPhase;
19 use rustc_middle::ty::fold::TypeFoldable;
20 use rustc_middle::ty::{self, Ty};
21 use rustc_session::Session;
22 use rustc_span::symbol::Ident;
23 use rustc_span::{self, MultiSpan, Span};
24 use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
25
26 use crate::structured_errors::StructuredDiagnostic;
27 use std::iter;
28 use std::slice;
29
30 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31     pub(in super::super) fn check_casts(&self) {
32         let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
33         debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
34         for cast in deferred_cast_checks.drain(..) {
35             cast.check(self);
36         }
37     }
38
39     pub(in super::super) fn check_method_argument_types(
40         &self,
41         sp: Span,
42         expr: &'tcx hir::Expr<'tcx>,
43         method: Result<MethodCallee<'tcx>, ()>,
44         args_no_rcvr: &'tcx [hir::Expr<'tcx>],
45         tuple_arguments: TupleArgumentsFlag,
46         expected: Expectation<'tcx>,
47     ) -> Ty<'tcx> {
48         let has_error = match method {
49             Ok(method) => method.substs.references_error() || method.sig.references_error(),
50             Err(_) => true,
51         };
52         if has_error {
53             let err_inputs = self.err_args(args_no_rcvr.len());
54
55             let err_inputs = match tuple_arguments {
56                 DontTupleArguments => err_inputs,
57                 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
58             };
59
60             self.check_argument_types(
61                 sp,
62                 expr,
63                 &err_inputs[..],
64                 &[],
65                 args_no_rcvr,
66                 false,
67                 tuple_arguments,
68                 None,
69             );
70             return self.tcx.ty_error();
71         }
72
73         let method = method.unwrap();
74         // HACK(eddyb) ignore self in the definition (see above).
75         let expected_arg_tys = self.expected_inputs_for_expected_output(
76             sp,
77             expected,
78             method.sig.output(),
79             &method.sig.inputs()[1..],
80         );
81         self.check_argument_types(
82             sp,
83             expr,
84             &method.sig.inputs()[1..],
85             &expected_arg_tys[..],
86             args_no_rcvr,
87             method.sig.c_variadic,
88             tuple_arguments,
89             Some(method.def_id),
90         );
91         method.sig.output()
92     }
93
94     /// Generic function that factors out common logic from function calls,
95     /// method calls and overloaded operators.
96     pub(in super::super) fn check_argument_types(
97         &self,
98         sp: Span,
99         expr: &'tcx hir::Expr<'tcx>,
100         fn_inputs: &[Ty<'tcx>],
101         expected_arg_tys: &[Ty<'tcx>],
102         args: &'tcx [hir::Expr<'tcx>],
103         c_variadic: bool,
104         tuple_arguments: TupleArgumentsFlag,
105         def_id: Option<DefId>,
106     ) {
107         let tcx = self.tcx;
108         // Grab the argument types, supplying fresh type variables
109         // if the wrong number of arguments were supplied
110         let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
111
112         // All the input types from the fn signature must outlive the call
113         // so as to validate implied bounds.
114         for (&fn_input_ty, arg_expr) in iter::zip(fn_inputs, args) {
115             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
116         }
117
118         let expected_arg_count = fn_inputs.len();
119
120         let param_count_error = |expected_count: usize,
121                                  arg_count: usize,
122                                  error_code: &str,
123                                  c_variadic: bool,
124                                  sugg_unit: bool| {
125             let (span, start_span, args, ctor_of) = match &expr.kind {
126                 hir::ExprKind::Call(
127                     hir::Expr {
128                         span,
129                         kind:
130                             hir::ExprKind::Path(hir::QPath::Resolved(
131                                 _,
132                                 hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
133                             )),
134                         ..
135                     },
136                     args,
137                 ) => (*span, *span, &args[..], Some(of)),
138                 hir::ExprKind::Call(hir::Expr { span, .. }, args) => {
139                     (*span, *span, &args[..], None)
140                 }
141                 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
142                     *span,
143                     // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
144                     path_segment
145                         .args
146                         .and_then(|args| args.args.iter().last())
147                         // Account for `foo.bar::<T>()`.
148                         .map(|arg| {
149                             // Skip the closing `>`.
150                             tcx.sess
151                                 .source_map()
152                                 .next_point(tcx.sess.source_map().next_point(arg.span()))
153                         })
154                         .unwrap_or(*span),
155                     &args[1..], // Skip the receiver.
156                     None,       // methods are never ctors
157                 ),
158                 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
159             };
160             let arg_spans = if args.is_empty() {
161                 // foo()
162                 // ^^^-- supplied 0 arguments
163                 // |
164                 // expected 2 arguments
165                 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
166             } else {
167                 // foo(1, 2, 3)
168                 // ^^^ -  -  - supplied 3 arguments
169                 // |
170                 // expected 2 arguments
171                 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
172             };
173
174             let mut err = tcx.sess.struct_span_err_with_code(
175                 span,
176                 &format!(
177                     "this {} takes {}{} but {} {} supplied",
178                     match ctor_of {
179                         Some(CtorOf::Struct) => "struct",
180                         Some(CtorOf::Variant) => "enum variant",
181                         None => "function",
182                     },
183                     if c_variadic { "at least " } else { "" },
184                     potentially_plural_count(expected_count, "argument"),
185                     potentially_plural_count(arg_count, "argument"),
186                     if arg_count == 1 { "was" } else { "were" }
187                 ),
188                 DiagnosticId::Error(error_code.to_owned()),
189             );
190             let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
191             for (i, span) in arg_spans.into_iter().enumerate() {
192                 err.span_label(
193                     span,
194                     if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
195                 );
196             }
197
198             if let Some(def_id) = def_id {
199                 if let Some(def_span) = tcx.def_ident_span(def_id) {
200                     let mut spans: MultiSpan = def_span.into();
201
202                     let params = tcx
203                         .hir()
204                         .get_if_local(def_id)
205                         .and_then(|node| node.body_id())
206                         .into_iter()
207                         .map(|id| tcx.hir().body(id).params)
208                         .flatten();
209
210                     for param in params {
211                         spans.push_span_label(param.span, String::new());
212                     }
213
214                     let def_kind = tcx.def_kind(def_id);
215                     err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
216                 }
217             }
218
219             if sugg_unit {
220                 let sugg_span = tcx.sess.source_map().end_point(expr.span);
221                 // remove closing `)` from the span
222                 let sugg_span = sugg_span.shrink_to_lo();
223                 err.span_suggestion(
224                     sugg_span,
225                     "expected the unit value `()`; create it with empty parentheses",
226                     String::from("()"),
227                     Applicability::MachineApplicable,
228                 );
229             } else {
230                 err.span_label(
231                     span,
232                     format!(
233                         "expected {}{}",
234                         if c_variadic { "at least " } else { "" },
235                         potentially_plural_count(expected_count, "argument")
236                     ),
237                 );
238             }
239             err.emit();
240         };
241
242         let mut expected_arg_tys = expected_arg_tys.to_vec();
243
244         let formal_tys = if tuple_arguments == TupleArguments {
245             let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
246             match tuple_type.kind() {
247                 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
248                     param_count_error(arg_types.len(), args.len(), "E0057", false, false);
249                     expected_arg_tys = vec![];
250                     self.err_args(args.len())
251                 }
252                 ty::Tuple(arg_types) => {
253                     expected_arg_tys = match expected_arg_tys.get(0) {
254                         Some(&ty) => match ty.kind() {
255                             ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
256                             _ => vec![],
257                         },
258                         None => vec![],
259                     };
260                     arg_types.iter().map(|k| k.expect_ty()).collect()
261                 }
262                 _ => {
263                     struct_span_err!(
264                         tcx.sess,
265                         sp,
266                         E0059,
267                         "cannot use call notation; the first type parameter \
268                          for the function trait is neither a tuple nor unit"
269                     )
270                     .emit();
271                     expected_arg_tys = vec![];
272                     self.err_args(args.len())
273                 }
274             }
275         } else if expected_arg_count == supplied_arg_count {
276             fn_inputs.to_vec()
277         } else if c_variadic {
278             if supplied_arg_count >= expected_arg_count {
279                 fn_inputs.to_vec()
280             } else {
281                 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
282                 expected_arg_tys = vec![];
283                 self.err_args(supplied_arg_count)
284             }
285         } else {
286             // is the missing argument of type `()`?
287             let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
288                 self.resolve_vars_if_possible(expected_arg_tys[0]).is_unit()
289             } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
290                 self.resolve_vars_if_possible(fn_inputs[0]).is_unit()
291             } else {
292                 false
293             };
294             param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
295
296             expected_arg_tys = vec![];
297             self.err_args(supplied_arg_count)
298         };
299
300         debug!(
301             "check_argument_types: formal_tys={:?}",
302             formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
303         );
304
305         // If there is no expectation, expect formal_tys.
306         let expected_arg_tys =
307             if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
308
309         let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
310
311         // Check the arguments.
312         // We do this in a pretty awful way: first we type-check any arguments
313         // that are not closures, then we type-check the closures. This is so
314         // that we have more information about the types of arguments when we
315         // type-check the functions. This isn't really the right way to do this.
316         for check_closures in [false, true] {
317             debug!("check_closures={}", check_closures);
318
319             // More awful hacks: before we check argument types, try to do
320             // an "opportunistic" trait resolution of any trait bounds on
321             // the call. This helps coercions.
322             if check_closures {
323                 self.select_obligations_where_possible(false, |errors| {
324                     self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
325                     self.point_at_arg_instead_of_call_if_possible(
326                         errors,
327                         &final_arg_types[..],
328                         expr,
329                         sp,
330                         &args,
331                     );
332                 })
333             }
334
335             // For C-variadic functions, we don't have a declared type for all of
336             // the arguments hence we only do our usual type checking with
337             // the arguments who's types we do know.
338             let t = if c_variadic {
339                 expected_arg_count
340             } else if tuple_arguments == TupleArguments {
341                 args.len()
342             } else {
343                 supplied_arg_count
344             };
345             for (i, arg) in args.iter().take(t).enumerate() {
346                 // Warn only for the first loop (the "no closures" one).
347                 // Closure arguments themselves can't be diverging, but
348                 // a previous argument can, e.g., `foo(panic!(), || {})`.
349                 if !check_closures {
350                     self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
351                 }
352
353                 let is_closure = matches!(arg.kind, ExprKind::Closure(..));
354
355                 if is_closure != check_closures {
356                     continue;
357                 }
358
359                 let formal_ty = formal_tys[i];
360                 debug!("checking argument {}: {:?} = {:?}", i, arg, formal_ty);
361
362                 // The special-cased logic below has three functions:
363                 // 1. Provide as good of an expected type as possible.
364                 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
365
366                 let checked_ty = self.check_expr_with_expectation(&arg, expected);
367
368                 // 2. Coerce to the most detailed type that could be coerced
369                 //    to, which is `expected_ty` if `rvalue_hint` returns an
370                 //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
371                 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
372
373                 // Cause selection errors caused by resolving a single argument to point at the
374                 // argument and not the call. This is otherwise redundant with the `demand_coerce`
375                 // call immediately after, but it lets us customize the span pointed to in the
376                 // fulfillment error to be more accurate.
377                 let _ = self.resolve_vars_with_obligations_and_mutate_fulfillment(
378                     coerce_ty,
379                     |errors| {
380                         // This is not coming from a macro or a `derive`.
381                         if sp.desugaring_kind().is_none()
382                         && !arg.span.from_expansion()
383                         // Do not change the spans of `async fn`s.
384                         && !matches!(
385                             expr.kind,
386                             hir::ExprKind::Call(
387                                 hir::Expr {
388                                     kind: hir::ExprKind::Path(hir::QPath::LangItem(_, _)),
389                                     ..
390                                 },
391                                 _
392                             )
393                         ) {
394                             for error in errors {
395                                 error.obligation.cause.make_mut().span = arg.span;
396                                 let code = error.obligation.cause.code.clone();
397                                 error.obligation.cause.make_mut().code =
398                                     ObligationCauseCode::FunctionArgumentObligation {
399                                         arg_hir_id: arg.hir_id,
400                                         call_hir_id: expr.hir_id,
401                                         parent_code: Lrc::new(code),
402                                     };
403                             }
404                         }
405                     },
406                 );
407
408                 // We're processing function arguments so we definitely want to use
409                 // two-phase borrows.
410                 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
411                 final_arg_types.push((i, checked_ty, coerce_ty));
412
413                 // 3. Relate the expected type and the formal one,
414                 //    if the expected type was used for the coercion.
415                 self.demand_suptype(arg.span, formal_ty, coerce_ty);
416             }
417         }
418
419         // We also need to make sure we at least write the ty of the other
420         // arguments which we skipped above.
421         if c_variadic {
422             fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
423                 use crate::structured_errors::MissingCastForVariadicArg;
424
425                 MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit()
426             }
427
428             for arg in args.iter().skip(expected_arg_count) {
429                 let arg_ty = self.check_expr(&arg);
430
431                 // There are a few types which get autopromoted when passed via varargs
432                 // in C but we just error out instead and require explicit casts.
433                 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
434                 match arg_ty.kind() {
435                     ty::Float(ty::FloatTy::F32) => {
436                         variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
437                     }
438                     ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
439                         variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
440                     }
441                     ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
442                         variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
443                     }
444                     ty::FnDef(..) => {
445                         let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
446                         let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
447                         variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
448                     }
449                     _ => {}
450                 }
451             }
452         }
453     }
454
455     // AST fragment checking
456     pub(in super::super) fn check_lit(
457         &self,
458         lit: &hir::Lit,
459         expected: Expectation<'tcx>,
460     ) -> Ty<'tcx> {
461         let tcx = self.tcx;
462
463         match lit.node {
464             ast::LitKind::Str(..) => tcx.mk_static_str(),
465             ast::LitKind::ByteStr(ref v) => {
466                 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
467             }
468             ast::LitKind::Byte(_) => tcx.types.u8,
469             ast::LitKind::Char(_) => tcx.types.char,
470             ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(ty::int_ty(t)),
471             ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(ty::uint_ty(t)),
472             ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
473                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
474                     ty::Int(_) | ty::Uint(_) => Some(ty),
475                     ty::Char => Some(tcx.types.u8),
476                     ty::RawPtr(..) => Some(tcx.types.usize),
477                     ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
478                     _ => None,
479                 });
480                 opt_ty.unwrap_or_else(|| self.next_int_var())
481             }
482             ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => {
483                 tcx.mk_mach_float(ty::float_ty(t))
484             }
485             ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
486                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
487                     ty::Float(_) => Some(ty),
488                     _ => None,
489                 });
490                 opt_ty.unwrap_or_else(|| self.next_float_var())
491             }
492             ast::LitKind::Bool(_) => tcx.types.bool,
493             ast::LitKind::Err(_) => tcx.ty_error(),
494         }
495     }
496
497     pub fn check_struct_path(
498         &self,
499         qpath: &QPath<'_>,
500         hir_id: hir::HirId,
501     ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
502         let path_span = qpath.span();
503         let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
504         let variant = match def {
505             Res::Err => {
506                 self.set_tainted_by_errors();
507                 return None;
508             }
509             Res::Def(DefKind::Variant, _) => match ty.kind() {
510                 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
511                 _ => bug!("unexpected type: {:?}", ty),
512             },
513             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
514             | Res::SelfTy(..) => match ty.kind() {
515                 ty::Adt(adt, substs) if !adt.is_enum() => {
516                     Some((adt.non_enum_variant(), adt.did, substs))
517                 }
518                 _ => None,
519             },
520             _ => bug!("unexpected definition: {:?}", def),
521         };
522
523         if let Some((variant, did, substs)) = variant {
524             debug!("check_struct_path: did={:?} substs={:?}", did, substs);
525             self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
526
527             // Check bounds on type arguments used in the path.
528             let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
529             let cause =
530                 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
531             self.add_obligations_for_parameters(cause, bounds);
532
533             Some((variant, ty))
534         } else {
535             match ty.kind() {
536                 ty::Error(_) => {
537                     // E0071 might be caused by a spelling error, which will have
538                     // already caused an error message and probably a suggestion
539                     // elsewhere. Refrain from emitting more unhelpful errors here
540                     // (issue #88844).
541                 }
542                 _ => {
543                     struct_span_err!(
544                         self.tcx.sess,
545                         path_span,
546                         E0071,
547                         "expected struct, variant or union type, found {}",
548                         ty.sort_string(self.tcx)
549                     )
550                     .span_label(path_span, "not a struct")
551                     .emit();
552                 }
553             }
554             None
555         }
556     }
557
558     pub fn check_decl_initializer(
559         &self,
560         local: &'tcx hir::Local<'tcx>,
561         init: &'tcx hir::Expr<'tcx>,
562     ) -> Ty<'tcx> {
563         // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
564         // for #42640 (default match binding modes).
565         //
566         // See #44848.
567         let ref_bindings = local.pat.contains_explicit_ref_binding();
568
569         let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
570         if let Some(m) = ref_bindings {
571             // Somewhat subtle: if we have a `ref` binding in the pattern,
572             // we want to avoid introducing coercions for the RHS. This is
573             // both because it helps preserve sanity and, in the case of
574             // ref mut, for soundness (issue #23116). In particular, in
575             // the latter case, we need to be clear that the type of the
576             // referent for the reference that results is *equal to* the
577             // type of the place it is referencing, and not some
578             // supertype thereof.
579             let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
580             self.demand_eqtype(init.span, local_ty, init_ty);
581             init_ty
582         } else {
583             self.check_expr_coercable_to_type(init, local_ty, None)
584         }
585     }
586
587     /// Type check a `let` statement.
588     pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
589         // Determine and write the type which we'll check the pattern against.
590         let ty = self.local_ty(local.span, local.hir_id).decl_ty;
591         self.write_ty(local.hir_id, ty);
592
593         // Type check the initializer.
594         if let Some(ref init) = local.init {
595             let init_ty = self.check_decl_initializer(local, &init);
596             self.overwrite_local_ty_if_err(local, ty, init_ty);
597         }
598
599         // Does the expected pattern type originate from an expression and what is the span?
600         let (origin_expr, ty_span) = match (local.ty, local.init) {
601             (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
602             (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
603             _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
604         };
605
606         // Type check the pattern. Override if necessary to avoid knock-on errors.
607         self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
608         let pat_ty = self.node_ty(local.pat.hir_id);
609         self.overwrite_local_ty_if_err(local, ty, pat_ty);
610     }
611
612     pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>, is_last: bool) {
613         // Don't do all the complex logic below for `DeclItem`.
614         match stmt.kind {
615             hir::StmtKind::Item(..) => return,
616             hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
617         }
618
619         self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
620
621         // Hide the outer diverging and `has_errors` flags.
622         let old_diverges = self.diverges.replace(Diverges::Maybe);
623         let old_has_errors = self.has_errors.replace(false);
624
625         match stmt.kind {
626             hir::StmtKind::Local(ref l) => {
627                 self.check_decl_local(&l);
628             }
629             // Ignore for now.
630             hir::StmtKind::Item(_) => {}
631             hir::StmtKind::Expr(ref expr) => {
632                 // Check with expected type of `()`.
633                 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
634                     if expr.can_have_side_effects() {
635                         self.suggest_semicolon_at_end(expr.span, err);
636                     }
637                 });
638             }
639             hir::StmtKind::Semi(ref expr) => {
640                 // All of this is equivalent to calling `check_expr`, but it is inlined out here
641                 // in order to capture the fact that this `match` is the last statement in its
642                 // function. This is done for better suggestions to remove the `;`.
643                 let expectation = match expr.kind {
644                     hir::ExprKind::Match(..) if is_last => IsLast(stmt.span),
645                     _ => NoExpectation,
646                 };
647                 self.check_expr_with_expectation(expr, expectation);
648             }
649         }
650
651         // Combine the diverging and `has_error` flags.
652         self.diverges.set(self.diverges.get() | old_diverges);
653         self.has_errors.set(self.has_errors.get() | old_has_errors);
654     }
655
656     pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
657         let unit = self.tcx.mk_unit();
658         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
659
660         // if the block produces a `!` value, that can always be
661         // (effectively) coerced to unit.
662         if !ty.is_never() {
663             self.demand_suptype(blk.span, unit, ty);
664         }
665     }
666
667     pub(in super::super) fn check_block_with_expected(
668         &self,
669         blk: &'tcx hir::Block<'tcx>,
670         expected: Expectation<'tcx>,
671     ) -> Ty<'tcx> {
672         let prev = self.ps.replace(self.ps.get().recurse(blk));
673
674         // In some cases, blocks have just one exit, but other blocks
675         // can be targeted by multiple breaks. This can happen both
676         // with labeled blocks as well as when we desugar
677         // a `try { ... }` expression.
678         //
679         // Example 1:
680         //
681         //    'a: { if true { break 'a Err(()); } Ok(()) }
682         //
683         // Here we would wind up with two coercions, one from
684         // `Err(())` and the other from the tail expression
685         // `Ok(())`. If the tail expression is omitted, that's a
686         // "forced unit" -- unless the block diverges, in which
687         // case we can ignore the tail expression (e.g., `'a: {
688         // break 'a 22; }` would not force the type of the block
689         // to be `()`).
690         let tail_expr = blk.expr.as_ref();
691         let coerce_to_ty = expected.coercion_target_type(self, blk.span);
692         let coerce = if blk.targeted_by_break {
693             CoerceMany::new(coerce_to_ty)
694         } else {
695             let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
696                 Some(e) => slice::from_ref(e),
697                 None => &[],
698             };
699             CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
700         };
701
702         let prev_diverges = self.diverges.get();
703         let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
704
705         let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
706             for (pos, s) in blk.stmts.iter().enumerate() {
707                 self.check_stmt(s, blk.stmts.len() - 1 == pos);
708             }
709
710             // check the tail expression **without** holding the
711             // `enclosing_breakables` lock below.
712             let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
713
714             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
715             let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
716             let coerce = ctxt.coerce.as_mut().unwrap();
717             if let Some(tail_expr_ty) = tail_expr_ty {
718                 let tail_expr = tail_expr.unwrap();
719                 let span = self.get_expr_coercion_span(tail_expr);
720                 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
721                 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
722             } else {
723                 // Subtle: if there is no explicit tail expression,
724                 // that is typically equivalent to a tail expression
725                 // of `()` -- except if the block diverges. In that
726                 // case, there is no value supplied from the tail
727                 // expression (assuming there are no other breaks,
728                 // this implies that the type of the block will be
729                 // `!`).
730                 //
731                 // #41425 -- label the implicit `()` as being the
732                 // "found type" here, rather than the "expected type".
733                 if !self.diverges.get().is_always() {
734                     // #50009 -- Do not point at the entire fn block span, point at the return type
735                     // span, as it is the cause of the requirement, and
736                     // `consider_hint_about_removing_semicolon` will point at the last expression
737                     // if it were a relevant part of the error. This improves usability in editors
738                     // that highlight errors inline.
739                     let mut sp = blk.span;
740                     let mut fn_span = None;
741                     if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
742                         let ret_sp = decl.output.span();
743                         if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
744                             // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
745                             // output would otherwise be incorrect and even misleading. Make sure
746                             // the span we're aiming at correspond to a `fn` body.
747                             if block_sp == blk.span {
748                                 sp = ret_sp;
749                                 fn_span = Some(ident.span);
750                             }
751                         }
752                     }
753                     coerce.coerce_forced_unit(
754                         self,
755                         &self.misc(sp),
756                         &mut |err| {
757                             if let Some(expected_ty) = expected.only_has_type(self) {
758                                 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
759                             }
760                             if let Some(fn_span) = fn_span {
761                                 err.span_label(
762                                     fn_span,
763                                     "implicitly returns `()` as its body has no tail or `return` \
764                                      expression",
765                                 );
766                             }
767                         },
768                         false,
769                     );
770                 }
771             }
772         });
773
774         if ctxt.may_break {
775             // If we can break from the block, then the block's exit is always reachable
776             // (... as long as the entry is reachable) - regardless of the tail of the block.
777             self.diverges.set(prev_diverges);
778         }
779
780         let mut ty = ctxt.coerce.unwrap().complete(self);
781
782         if self.has_errors.get() || ty.references_error() {
783             ty = self.tcx.ty_error()
784         }
785
786         self.write_ty(blk.hir_id, ty);
787
788         self.ps.set(prev);
789         ty
790     }
791
792     /// A common error is to add an extra semicolon:
793     ///
794     /// ```
795     /// fn foo() -> usize {
796     ///     22;
797     /// }
798     /// ```
799     ///
800     /// This routine checks if the final statement in a block is an
801     /// expression with an explicit semicolon whose type is compatible
802     /// with `expected_ty`. If so, it suggests removing the semicolon.
803     fn consider_hint_about_removing_semicolon(
804         &self,
805         blk: &'tcx hir::Block<'tcx>,
806         expected_ty: Ty<'tcx>,
807         err: &mut DiagnosticBuilder<'_>,
808     ) {
809         if let Some((span_semi, boxed)) = self.could_remove_semicolon(blk, expected_ty) {
810             if let StatementAsExpression::NeedsBoxing = boxed {
811                 err.span_suggestion_verbose(
812                     span_semi,
813                     "consider removing this semicolon and boxing the expression",
814                     String::new(),
815                     Applicability::HasPlaceholders,
816                 );
817             } else {
818                 err.span_suggestion_short(
819                     span_semi,
820                     "consider removing this semicolon",
821                     String::new(),
822                     Applicability::MachineApplicable,
823                 );
824             }
825         }
826     }
827
828     fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
829         let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
830         match node {
831             Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
832             | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
833                 let body = self.tcx.hir().body(body_id);
834                 if let ExprKind::Block(block, _) = &body.value.kind {
835                     return Some(block.span);
836                 }
837             }
838             _ => {}
839         }
840         None
841     }
842
843     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
844     fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
845         let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
846         self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
847     }
848
849     /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
850     /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
851     /// when given code like the following:
852     /// ```text
853     /// if false { return 0i32; } else { 1u32 }
854     /// //                               ^^^^ point at this instead of the whole `if` expression
855     /// ```
856     fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
857         let check_in_progress = |elem: &hir::Expr<'_>| {
858             self.in_progress_typeck_results
859                 .and_then(|typeck_results| typeck_results.borrow().node_type_opt(elem.hir_id))
860                 .and_then(|ty| {
861                     if ty.is_never() {
862                         None
863                     } else {
864                         Some(match elem.kind {
865                             // Point at the tail expression when possible.
866                             hir::ExprKind::Block(block, _) => {
867                                 block.expr.map_or(block.span, |e| e.span)
868                             }
869                             _ => elem.span,
870                         })
871                     }
872                 })
873         };
874
875         if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
876             if let Some(rslt) = check_in_progress(el) {
877                 return rslt;
878             }
879         }
880
881         if let hir::ExprKind::Match(_, arms, _) = expr.kind {
882             let mut iter = arms.iter().filter_map(|arm| check_in_progress(arm.body));
883             if let Some(span) = iter.next() {
884                 if iter.next().is_none() {
885                     return span;
886                 }
887             }
888         }
889
890         expr.span
891     }
892
893     fn overwrite_local_ty_if_err(
894         &self,
895         local: &'tcx hir::Local<'tcx>,
896         decl_ty: Ty<'tcx>,
897         ty: Ty<'tcx>,
898     ) {
899         if ty.references_error() {
900             // Override the types everywhere with `err()` to avoid knock on errors.
901             self.write_ty(local.hir_id, ty);
902             self.write_ty(local.pat.hir_id, ty);
903             let local_ty = LocalTy { decl_ty, revealed_ty: ty };
904             self.locals.borrow_mut().insert(local.hir_id, local_ty);
905             self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
906         }
907     }
908
909     // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
910     // The newly resolved definition is written into `type_dependent_defs`.
911     fn finish_resolving_struct_path(
912         &self,
913         qpath: &QPath<'_>,
914         path_span: Span,
915         hir_id: hir::HirId,
916     ) -> (Res, Ty<'tcx>) {
917         match *qpath {
918             QPath::Resolved(ref maybe_qself, ref path) => {
919                 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
920                 let ty = <dyn AstConv<'_>>::res_to_ty(self, self_ty, path, true);
921                 (path.res, ty)
922             }
923             QPath::TypeRelative(ref qself, ref segment) => {
924                 let ty = self.to_ty(qself);
925
926                 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
927                     path.res
928                 } else {
929                     Res::Err
930                 };
931                 let result = <dyn AstConv<'_>>::associated_path_to_ty(
932                     self, hir_id, path_span, ty, res, segment, true,
933                 );
934                 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
935                 let result = result.map(|(_, kind, def_id)| (kind, def_id));
936
937                 // Write back the new resolution.
938                 self.write_resolution(hir_id, result);
939
940                 (result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
941             }
942             QPath::LangItem(lang_item, span) => {
943                 self.resolve_lang_item_path(lang_item, span, hir_id)
944             }
945         }
946     }
947
948     /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
949     /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
950     /// reference a type argument. The reason to walk also the checked type is that the coerced type
951     /// can be not easily comparable with predicate type (because of coercion). If the types match
952     /// for either checked or coerced type, and there's only *one* argument that does, we point at
953     /// the corresponding argument's expression span instead of the `fn` call path span.
954     fn point_at_arg_instead_of_call_if_possible(
955         &self,
956         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
957         final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
958         expr: &'tcx hir::Expr<'tcx>,
959         call_sp: Span,
960         args: &'tcx [hir::Expr<'tcx>],
961     ) {
962         // We *do not* do this for desugared call spans to keep good diagnostics when involving
963         // the `?` operator.
964         if call_sp.desugaring_kind().is_some() {
965             return;
966         }
967
968         for error in errors {
969             // Only if the cause is somewhere inside the expression we want try to point at arg.
970             // Otherwise, it means that the cause is somewhere else and we should not change
971             // anything because we can break the correct span.
972             if !call_sp.contains(error.obligation.cause.span) {
973                 continue;
974             }
975
976             if let ty::PredicateKind::Trait(predicate) =
977                 error.obligation.predicate.kind().skip_binder()
978             {
979                 // Collect the argument position for all arguments that could have caused this
980                 // `FulfillmentError`.
981                 let mut referenced_in = final_arg_types
982                     .iter()
983                     .map(|&(i, checked_ty, _)| (i, checked_ty))
984                     .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
985                     .flat_map(|(i, ty)| {
986                         let ty = self.resolve_vars_if_possible(ty);
987                         // We walk the argument type because the argument's type could have
988                         // been `Option<T>`, but the `FulfillmentError` references `T`.
989                         if ty.walk(self.tcx).any(|arg| arg == predicate.self_ty().into()) {
990                             Some(i)
991                         } else {
992                             None
993                         }
994                     })
995                     .collect::<Vec<usize>>();
996
997                 // Both checked and coerced types could have matched, thus we need to remove
998                 // duplicates.
999
1000                 // We sort primitive type usize here and can use unstable sort
1001                 referenced_in.sort_unstable();
1002                 referenced_in.dedup();
1003
1004                 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
1005                     // We make sure that only *one* argument matches the obligation failure
1006                     // and we assign the obligation's span to its expression's.
1007                     error.obligation.cause.make_mut().span = args[ref_in].span;
1008                     let code = error.obligation.cause.code.clone();
1009                     error.obligation.cause.make_mut().code =
1010                         ObligationCauseCode::FunctionArgumentObligation {
1011                             arg_hir_id: args[ref_in].hir_id,
1012                             call_hir_id: expr.hir_id,
1013                             parent_code: Lrc::new(code),
1014                         };
1015                 }
1016             }
1017         }
1018     }
1019
1020     /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
1021     /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
1022     /// were caused by them. If they were, we point at the corresponding type argument's span
1023     /// instead of the `fn` call path span.
1024     fn point_at_type_arg_instead_of_call_if_possible(
1025         &self,
1026         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1027         call_expr: &'tcx hir::Expr<'tcx>,
1028     ) {
1029         if let hir::ExprKind::Call(path, _) = &call_expr.kind {
1030             if let hir::ExprKind::Path(qpath) = &path.kind {
1031                 if let hir::QPath::Resolved(_, path) = &qpath {
1032                     for error in errors {
1033                         if let ty::PredicateKind::Trait(predicate) =
1034                             error.obligation.predicate.kind().skip_binder()
1035                         {
1036                             // If any of the type arguments in this path segment caused the
1037                             // `FulfillmentError`, point at its span (#61860).
1038                             for arg in path
1039                                 .segments
1040                                 .iter()
1041                                 .filter_map(|seg| seg.args.as_ref())
1042                                 .flat_map(|a| a.args.iter())
1043                             {
1044                                 if let hir::GenericArg::Type(hir_ty) = &arg {
1045                                     if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
1046                                         &hir_ty.kind
1047                                     {
1048                                         // Avoid ICE with associated types. As this is best
1049                                         // effort only, it's ok to ignore the case. It
1050                                         // would trigger in `is_send::<T::AssocType>();`
1051                                         // from `typeck-default-trait-impl-assoc-type.rs`.
1052                                     } else {
1053                                         let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, hir_ty);
1054                                         let ty = self.resolve_vars_if_possible(ty);
1055                                         if ty == predicate.self_ty() {
1056                                             error.obligation.cause.make_mut().span = hir_ty.span;
1057                                         }
1058                                     }
1059                                 }
1060                             }
1061                         }
1062                     }
1063                 }
1064             }
1065         }
1066     }
1067 }