]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/expr.rs
Make "missing field" error message more natural
[rust.git] / compiler / rustc_typeck / src / check / expr.rs
1 //! Type checking expressions.
2 //!
3 //! See `mod.rs` for more context on type checking in general.
4
5 use crate::astconv::AstConv as _;
6 use crate::check::cast;
7 use crate::check::coercion::CoerceMany;
8 use crate::check::fatally_break_rust;
9 use crate::check::method::{probe, MethodError, SelfSource};
10 use crate::check::report_unexpected_variant_res;
11 use crate::check::BreakableCtxt;
12 use crate::check::Diverges;
13 use crate::check::DynamicCoerceMany;
14 use crate::check::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
15 use crate::check::FnCtxt;
16 use crate::check::Needs;
17 use crate::check::TupleArgumentsFlag::DontTupleArguments;
18 use crate::errors::{
19     FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
20     YieldExprOutsideOfGenerator,
21 };
22 use crate::type_error_struct;
23
24 use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
25 use rustc_ast as ast;
26 use rustc_data_structures::fx::FxHashMap;
27 use rustc_data_structures::stack::ensure_sufficient_stack;
28 use rustc_errors::ErrorReported;
29 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
30 use rustc_hir as hir;
31 use rustc_hir::def::{CtorKind, DefKind, Res};
32 use rustc_hir::def_id::DefId;
33 use rustc_hir::lang_items::LangItem;
34 use rustc_hir::{ExprKind, QPath};
35 use rustc_infer::infer;
36 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
37 use rustc_middle::ty;
38 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
39 use rustc_middle::ty::subst::SubstsRef;
40 use rustc_middle::ty::Ty;
41 use rustc_middle::ty::TypeFoldable;
42 use rustc_middle::ty::{AdtKind, Visibility};
43 use rustc_span::edition::LATEST_STABLE_EDITION;
44 use rustc_span::hygiene::DesugaringKind;
45 use rustc_span::lev_distance::find_best_match_for_name;
46 use rustc_span::source_map::Span;
47 use rustc_span::symbol::{kw, sym, Ident, Symbol};
48 use rustc_trait_selection::traits::{self, ObligationCauseCode};
49
50 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
51     fn check_expr_eq_type(&self, expr: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>) {
52         let ty = self.check_expr_with_hint(expr, expected);
53         self.demand_eqtype(expr.span, expected, ty);
54     }
55
56     pub fn check_expr_has_type_or_error(
57         &self,
58         expr: &'tcx hir::Expr<'tcx>,
59         expected: Ty<'tcx>,
60         extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
61     ) -> Ty<'tcx> {
62         self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected), extend_err)
63     }
64
65     fn check_expr_meets_expectation_or_error(
66         &self,
67         expr: &'tcx hir::Expr<'tcx>,
68         expected: Expectation<'tcx>,
69         extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
70     ) -> Ty<'tcx> {
71         let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
72         let mut ty = self.check_expr_with_expectation(expr, expected);
73
74         // While we don't allow *arbitrary* coercions here, we *do* allow
75         // coercions from ! to `expected`.
76         if ty.is_never() {
77             assert!(
78                 !self.typeck_results.borrow().adjustments().contains_key(expr.hir_id),
79                 "expression with never type wound up being adjusted"
80             );
81             let adj_ty = self.next_diverging_ty_var(TypeVariableOrigin {
82                 kind: TypeVariableOriginKind::AdjustmentType,
83                 span: expr.span,
84             });
85             self.apply_adjustments(
86                 expr,
87                 vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }],
88             );
89             ty = adj_ty;
90         }
91
92         if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
93             let expr = expr.peel_drop_temps();
94             self.suggest_deref_ref_or_into(&mut err, expr, expected_ty, ty, None);
95             extend_err(&mut err);
96             // Error possibly reported in `check_assign` so avoid emitting error again.
97             err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
98         }
99         ty
100     }
101
102     pub(super) fn check_expr_coercable_to_type(
103         &self,
104         expr: &'tcx hir::Expr<'tcx>,
105         expected: Ty<'tcx>,
106         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
107     ) -> Ty<'tcx> {
108         let ty = self.check_expr_with_hint(expr, expected);
109         // checks don't need two phase
110         self.demand_coerce(expr, ty, expected, expected_ty_expr, AllowTwoPhase::No)
111     }
112
113     pub(super) fn check_expr_with_hint(
114         &self,
115         expr: &'tcx hir::Expr<'tcx>,
116         expected: Ty<'tcx>,
117     ) -> Ty<'tcx> {
118         self.check_expr_with_expectation(expr, ExpectHasType(expected))
119     }
120
121     fn check_expr_with_expectation_and_needs(
122         &self,
123         expr: &'tcx hir::Expr<'tcx>,
124         expected: Expectation<'tcx>,
125         needs: Needs,
126     ) -> Ty<'tcx> {
127         let ty = self.check_expr_with_expectation(expr, expected);
128
129         // If the expression is used in a place whether mutable place is required
130         // e.g. LHS of assignment, perform the conversion.
131         if let Needs::MutPlace = needs {
132             self.convert_place_derefs_to_mutable(expr);
133         }
134
135         ty
136     }
137
138     pub(super) fn check_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
139         self.check_expr_with_expectation(expr, NoExpectation)
140     }
141
142     pub(super) fn check_expr_with_needs(
143         &self,
144         expr: &'tcx hir::Expr<'tcx>,
145         needs: Needs,
146     ) -> Ty<'tcx> {
147         self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
148     }
149
150     /// Invariant:
151     /// If an expression has any sub-expressions that result in a type error,
152     /// inspecting that expression's type with `ty.references_error()` will return
153     /// true. Likewise, if an expression is known to diverge, inspecting its
154     /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
155     /// strict, _|_ can appear in the type of an expression that does not,
156     /// itself, diverge: for example, fn() -> _|_.)
157     /// Note that inspecting a type's structure *directly* may expose the fact
158     /// that there are actually multiple representations for `Error`, so avoid
159     /// that when err needs to be handled differently.
160     pub(super) fn check_expr_with_expectation(
161         &self,
162         expr: &'tcx hir::Expr<'tcx>,
163         expected: Expectation<'tcx>,
164     ) -> Ty<'tcx> {
165         debug!(">> type-checking: expr={:?} expected={:?}", expr, expected);
166
167         // True if `expr` is a `Try::from_ok(())` that is a result of desugaring a try block
168         // without the final expr (e.g. `try { return; }`). We don't want to generate an
169         // unreachable_code lint for it since warnings for autogenerated code are confusing.
170         let is_try_block_generated_unit_expr = match expr.kind {
171             ExprKind::Call(_, args) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {
172                 args.len() == 1 && args[0].span.is_desugaring(DesugaringKind::TryBlock)
173             }
174
175             _ => false,
176         };
177
178         // Warn for expressions after diverging siblings.
179         if !is_try_block_generated_unit_expr {
180             self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
181         }
182
183         // Hide the outer diverging and has_errors flags.
184         let old_diverges = self.diverges.replace(Diverges::Maybe);
185         let old_has_errors = self.has_errors.replace(false);
186
187         let ty = ensure_sufficient_stack(|| self.check_expr_kind(expr, expected));
188
189         // Warn for non-block expressions with diverging children.
190         match expr.kind {
191             ExprKind::Block(..) | ExprKind::If(..) | ExprKind::Loop(..) | ExprKind::Match(..) => {}
192             // If `expr` is a result of desugaring the try block and is an ok-wrapped
193             // diverging expression (e.g. it arose from desugaring of `try { return }`),
194             // we skip issuing a warning because it is autogenerated code.
195             ExprKind::Call(..) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {}
196             ExprKind::Call(callee, _) => self.warn_if_unreachable(expr.hir_id, callee.span, "call"),
197             ExprKind::MethodCall(_, ref span, _, _) => {
198                 self.warn_if_unreachable(expr.hir_id, *span, "call")
199             }
200             _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression"),
201         }
202
203         // Any expression that produces a value of type `!` must have diverged
204         if ty.is_never() {
205             self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
206         }
207
208         // Record the type, which applies it effects.
209         // We need to do this after the warning above, so that
210         // we don't warn for the diverging expression itself.
211         self.write_ty(expr.hir_id, ty);
212
213         // Combine the diverging and has_error flags.
214         self.diverges.set(self.diverges.get() | old_diverges);
215         self.has_errors.set(self.has_errors.get() | old_has_errors);
216
217         debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
218         debug!("... {:?}, expected is {:?}", ty, expected);
219
220         ty
221     }
222
223     fn check_expr_kind(
224         &self,
225         expr: &'tcx hir::Expr<'tcx>,
226         expected: Expectation<'tcx>,
227     ) -> Ty<'tcx> {
228         debug!("check_expr_kind(expr={:?}, expected={:?})", expr, expected);
229
230         let tcx = self.tcx;
231         match expr.kind {
232             ExprKind::Box(subexpr) => self.check_expr_box(subexpr, expected),
233             ExprKind::Lit(ref lit) => self.check_lit(&lit, expected),
234             ExprKind::Binary(op, lhs, rhs) => self.check_binop(expr, op, lhs, rhs),
235             ExprKind::Assign(lhs, rhs, ref span) => {
236                 self.check_expr_assign(expr, expected, lhs, rhs, span)
237             }
238             ExprKind::AssignOp(op, lhs, rhs) => self.check_binop_assign(expr, op, lhs, rhs),
239             ExprKind::Unary(unop, oprnd) => self.check_expr_unary(unop, oprnd, expected, expr),
240             ExprKind::AddrOf(kind, mutbl, oprnd) => {
241                 self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
242             }
243             ExprKind::Path(QPath::LangItem(lang_item, _)) => {
244                 self.check_lang_item_path(lang_item, expr)
245             }
246             ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr),
247             ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
248             ExprKind::LlvmInlineAsm(asm) => {
249                 for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) {
250                     self.check_expr(expr);
251                 }
252                 tcx.mk_unit()
253             }
254             ExprKind::Break(destination, ref expr_opt) => {
255                 self.check_expr_break(destination, expr_opt.as_deref(), expr)
256             }
257             ExprKind::Continue(destination) => {
258                 if destination.target_id.is_ok() {
259                     tcx.types.never
260                 } else {
261                     // There was an error; make type-check fail.
262                     tcx.ty_error()
263                 }
264             }
265             ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
266             ExprKind::Loop(body, _, source, _) => {
267                 self.check_expr_loop(body, source, expected, expr)
268             }
269             ExprKind::Match(discrim, arms, match_src) => {
270                 self.check_match(expr, &discrim, arms, expected, match_src)
271             }
272             ExprKind::Closure(capture, decl, body_id, _, gen) => {
273                 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
274             }
275             ExprKind::Block(body, _) => self.check_block_with_expected(&body, expected),
276             ExprKind::Call(callee, args) => self.check_call(expr, &callee, args, expected),
277             ExprKind::MethodCall(segment, span, args, _) => {
278                 self.check_method_call(expr, segment, span, args, expected)
279             }
280             ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
281             ExprKind::Type(e, t) => {
282                 let ty = self.to_ty_saving_user_provided_ty(&t);
283                 self.check_expr_eq_type(&e, ty);
284                 ty
285             }
286             ExprKind::If(cond, then_expr, opt_else_expr) => {
287                 self.check_then_else(cond, then_expr, opt_else_expr, expr.span, expected)
288             }
289             ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
290             ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
291             ExprKind::ConstBlock(ref anon_const) => self.to_const(anon_const).ty,
292             ExprKind::Repeat(element, ref count) => {
293                 self.check_expr_repeat(element, count, expected, expr)
294             }
295             ExprKind::Tup(elts) => self.check_expr_tuple(elts, expected, expr),
296             ExprKind::Struct(qpath, fields, ref base_expr) => {
297                 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
298             }
299             ExprKind::Field(base, field) => self.check_field(expr, &base, field),
300             ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr),
301             ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src),
302             hir::ExprKind::Err => tcx.ty_error(),
303         }
304     }
305
306     fn check_expr_box(&self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>) -> Ty<'tcx> {
307         let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| match ty.kind() {
308             ty::Adt(def, _) if def.is_box() => Expectation::rvalue_hint(self, ty.boxed_ty()),
309             _ => NoExpectation,
310         });
311         let referent_ty = self.check_expr_with_expectation(expr, expected_inner);
312         self.tcx.mk_box(referent_ty)
313     }
314
315     fn check_expr_unary(
316         &self,
317         unop: hir::UnOp,
318         oprnd: &'tcx hir::Expr<'tcx>,
319         expected: Expectation<'tcx>,
320         expr: &'tcx hir::Expr<'tcx>,
321     ) -> Ty<'tcx> {
322         let tcx = self.tcx;
323         let expected_inner = match unop {
324             hir::UnOp::Not | hir::UnOp::Neg => expected,
325             hir::UnOp::Deref => NoExpectation,
326         };
327         let mut oprnd_t = self.check_expr_with_expectation(&oprnd, expected_inner);
328
329         if !oprnd_t.references_error() {
330             oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
331             match unop {
332                 hir::UnOp::Deref => {
333                     if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) {
334                         oprnd_t = ty;
335                     } else {
336                         let mut err = type_error_struct!(
337                             tcx.sess,
338                             expr.span,
339                             oprnd_t,
340                             E0614,
341                             "type `{}` cannot be dereferenced",
342                             oprnd_t,
343                         );
344                         let sp = tcx.sess.source_map().start_point(expr.span);
345                         if let Some(sp) =
346                             tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
347                         {
348                             tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp, None);
349                         }
350                         err.emit();
351                         oprnd_t = tcx.ty_error();
352                     }
353                 }
354                 hir::UnOp::Not => {
355                     let result = self.check_user_unop(expr, oprnd_t, unop);
356                     // If it's builtin, we can reuse the type, this helps inference.
357                     if !(oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool) {
358                         oprnd_t = result;
359                     }
360                 }
361                 hir::UnOp::Neg => {
362                     let result = self.check_user_unop(expr, oprnd_t, unop);
363                     // If it's builtin, we can reuse the type, this helps inference.
364                     if !oprnd_t.is_numeric() {
365                         oprnd_t = result;
366                     }
367                 }
368             }
369         }
370         oprnd_t
371     }
372
373     fn check_expr_addr_of(
374         &self,
375         kind: hir::BorrowKind,
376         mutbl: hir::Mutability,
377         oprnd: &'tcx hir::Expr<'tcx>,
378         expected: Expectation<'tcx>,
379         expr: &'tcx hir::Expr<'tcx>,
380     ) -> Ty<'tcx> {
381         let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
382             match ty.kind() {
383                 ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
384                     if oprnd.is_syntactic_place_expr() {
385                         // Places may legitimately have unsized types.
386                         // For example, dereferences of a fat pointer and
387                         // the last field of a struct can be unsized.
388                         ExpectHasType(ty)
389                     } else {
390                         Expectation::rvalue_hint(self, ty)
391                     }
392                 }
393                 _ => NoExpectation,
394             }
395         });
396         let ty =
397             self.check_expr_with_expectation_and_needs(&oprnd, hint, Needs::maybe_mut_place(mutbl));
398
399         let tm = ty::TypeAndMut { ty, mutbl };
400         match kind {
401             _ if tm.ty.references_error() => self.tcx.ty_error(),
402             hir::BorrowKind::Raw => {
403                 self.check_named_place_expr(oprnd);
404                 self.tcx.mk_ptr(tm)
405             }
406             hir::BorrowKind::Ref => {
407                 // Note: at this point, we cannot say what the best lifetime
408                 // is to use for resulting pointer.  We want to use the
409                 // shortest lifetime possible so as to avoid spurious borrowck
410                 // errors.  Moreover, the longest lifetime will depend on the
411                 // precise details of the value whose address is being taken
412                 // (and how long it is valid), which we don't know yet until
413                 // type inference is complete.
414                 //
415                 // Therefore, here we simply generate a region variable. The
416                 // region inferencer will then select a suitable value.
417                 // Finally, borrowck will infer the value of the region again,
418                 // this time with enough precision to check that the value
419                 // whose address was taken can actually be made to live as long
420                 // as it needs to live.
421                 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
422                 self.tcx.mk_ref(region, tm)
423             }
424         }
425     }
426
427     /// Does this expression refer to a place that either:
428     /// * Is based on a local or static.
429     /// * Contains a dereference
430     /// Note that the adjustments for the children of `expr` should already
431     /// have been resolved.
432     fn check_named_place_expr(&self, oprnd: &'tcx hir::Expr<'tcx>) {
433         let is_named = oprnd.is_place_expr(|base| {
434             // Allow raw borrows if there are any deref adjustments.
435             //
436             // const VAL: (i32,) = (0,);
437             // const REF: &(i32,) = &(0,);
438             //
439             // &raw const VAL.0;            // ERROR
440             // &raw const REF.0;            // OK, same as &raw const (*REF).0;
441             //
442             // This is maybe too permissive, since it allows
443             // `let u = &raw const Box::new((1,)).0`, which creates an
444             // immediately dangling raw pointer.
445             self.typeck_results
446                 .borrow()
447                 .adjustments()
448                 .get(base.hir_id)
449                 .map_or(false, |x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
450         });
451         if !is_named {
452             self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span })
453         }
454     }
455
456     fn check_lang_item_path(
457         &self,
458         lang_item: hir::LangItem,
459         expr: &'tcx hir::Expr<'tcx>,
460     ) -> Ty<'tcx> {
461         self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1
462     }
463
464     fn check_expr_path(&self, qpath: &hir::QPath<'_>, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
465         let tcx = self.tcx;
466         let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
467         let ty = match res {
468             Res::Err => {
469                 self.set_tainted_by_errors();
470                 tcx.ty_error()
471             }
472             Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
473                 report_unexpected_variant_res(tcx, res, expr.span);
474                 tcx.ty_error()
475             }
476             _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
477         };
478
479         if let ty::FnDef(..) = ty.kind() {
480             let fn_sig = ty.fn_sig(tcx);
481             if !tcx.features().unsized_fn_params {
482                 // We want to remove some Sized bounds from std functions,
483                 // but don't want to expose the removal to stable Rust.
484                 // i.e., we don't want to allow
485                 //
486                 // ```rust
487                 // drop as fn(str);
488                 // ```
489                 //
490                 // to work in stable even if the Sized bound on `drop` is relaxed.
491                 for i in 0..fn_sig.inputs().skip_binder().len() {
492                     // We just want to check sizedness, so instead of introducing
493                     // placeholder lifetimes with probing, we just replace higher lifetimes
494                     // with fresh vars.
495                     let input = self
496                         .replace_bound_vars_with_fresh_vars(
497                             expr.span,
498                             infer::LateBoundRegionConversionTime::FnCall,
499                             fn_sig.input(i),
500                         )
501                         .0;
502                     self.require_type_is_sized_deferred(
503                         input,
504                         expr.span,
505                         traits::SizedArgumentType(None),
506                     );
507                 }
508             }
509             // Here we want to prevent struct constructors from returning unsized types.
510             // There were two cases this happened: fn pointer coercion in stable
511             // and usual function call in presence of unsized_locals.
512             // Also, as we just want to check sizedness, instead of introducing
513             // placeholder lifetimes with probing, we just replace higher lifetimes
514             // with fresh vars.
515             let output = self
516                 .replace_bound_vars_with_fresh_vars(
517                     expr.span,
518                     infer::LateBoundRegionConversionTime::FnCall,
519                     fn_sig.output(),
520                 )
521                 .0;
522             self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
523         }
524
525         // We always require that the type provided as the value for
526         // a type parameter outlives the moment of instantiation.
527         let substs = self.typeck_results.borrow().node_substs(expr.hir_id);
528         self.add_wf_bounds(substs, expr);
529
530         ty
531     }
532
533     fn check_expr_break(
534         &self,
535         destination: hir::Destination,
536         expr_opt: Option<&'tcx hir::Expr<'tcx>>,
537         expr: &'tcx hir::Expr<'tcx>,
538     ) -> Ty<'tcx> {
539         let tcx = self.tcx;
540         if let Ok(target_id) = destination.target_id {
541             let (e_ty, cause);
542             if let Some(e) = expr_opt {
543                 // If this is a break with a value, we need to type-check
544                 // the expression. Get an expected type from the loop context.
545                 let opt_coerce_to = {
546                     // We should release `enclosing_breakables` before the `check_expr_with_hint`
547                     // below, so can't move this block of code to the enclosing scope and share
548                     // `ctxt` with the second `encloding_breakables` borrow below.
549                     let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
550                     match enclosing_breakables.opt_find_breakable(target_id) {
551                         Some(ctxt) => ctxt.coerce.as_ref().map(|coerce| coerce.expected_ty()),
552                         None => {
553                             // Avoid ICE when `break` is inside a closure (#65383).
554                             return tcx.ty_error_with_message(
555                                 expr.span,
556                                 "break was outside loop, but no error was emitted",
557                             );
558                         }
559                     }
560                 };
561
562                 // If the loop context is not a `loop { }`, then break with
563                 // a value is illegal, and `opt_coerce_to` will be `None`.
564                 // Just set expectation to error in that case.
565                 let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error());
566
567                 // Recurse without `enclosing_breakables` borrowed.
568                 e_ty = self.check_expr_with_hint(e, coerce_to);
569                 cause = self.misc(e.span);
570             } else {
571                 // Otherwise, this is a break *without* a value. That's
572                 // always legal, and is equivalent to `break ()`.
573                 e_ty = tcx.mk_unit();
574                 cause = self.misc(expr.span);
575             }
576
577             // Now that we have type-checked `expr_opt`, borrow
578             // the `enclosing_loops` field and let's coerce the
579             // type of `expr_opt` into what is expected.
580             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
581             let ctxt = match enclosing_breakables.opt_find_breakable(target_id) {
582                 Some(ctxt) => ctxt,
583                 None => {
584                     // Avoid ICE when `break` is inside a closure (#65383).
585                     return tcx.ty_error_with_message(
586                         expr.span,
587                         "break was outside loop, but no error was emitted",
588                     );
589                 }
590             };
591
592             if let Some(ref mut coerce) = ctxt.coerce {
593                 if let Some(ref e) = expr_opt {
594                     coerce.coerce(self, &cause, e, e_ty);
595                 } else {
596                     assert!(e_ty.is_unit());
597                     let ty = coerce.expected_ty();
598                     coerce.coerce_forced_unit(
599                         self,
600                         &cause,
601                         &mut |mut err| {
602                             self.suggest_mismatched_types_on_tail(
603                                 &mut err, expr, ty, e_ty, cause.span, target_id,
604                             );
605                             if let Some(val) = ty_kind_suggestion(ty) {
606                                 let label = destination
607                                     .label
608                                     .map(|l| format!(" {}", l.ident))
609                                     .unwrap_or_else(String::new);
610                                 err.span_suggestion(
611                                     expr.span,
612                                     "give it a value of the expected type",
613                                     format!("break{} {}", label, val),
614                                     Applicability::HasPlaceholders,
615                                 );
616                             }
617                         },
618                         false,
619                     );
620                 }
621             } else {
622                 // If `ctxt.coerce` is `None`, we can just ignore
623                 // the type of the expression.  This is because
624                 // either this was a break *without* a value, in
625                 // which case it is always a legal type (`()`), or
626                 // else an error would have been flagged by the
627                 // `loops` pass for using break with an expression
628                 // where you are not supposed to.
629                 assert!(expr_opt.is_none() || self.tcx.sess.has_errors());
630             }
631
632             // If we encountered a `break`, then (no surprise) it may be possible to break from the
633             // loop... unless the value being returned from the loop diverges itself, e.g.
634             // `break return 5` or `break loop {}`.
635             ctxt.may_break |= !self.diverges.get().is_always();
636
637             // the type of a `break` is always `!`, since it diverges
638             tcx.types.never
639         } else {
640             // Otherwise, we failed to find the enclosing loop;
641             // this can only happen if the `break` was not
642             // inside a loop at all, which is caught by the
643             // loop-checking pass.
644             let err = self.tcx.ty_error_with_message(
645                 expr.span,
646                 "break was outside loop, but no error was emitted",
647             );
648
649             // We still need to assign a type to the inner expression to
650             // prevent the ICE in #43162.
651             if let Some(e) = expr_opt {
652                 self.check_expr_with_hint(e, err);
653
654                 // ... except when we try to 'break rust;'.
655                 // ICE this expression in particular (see #43162).
656                 if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind {
657                     if path.segments.len() == 1 && path.segments[0].ident.name == sym::rust {
658                         fatally_break_rust(self.tcx.sess);
659                     }
660                 }
661             }
662
663             // There was an error; make type-check fail.
664             err
665         }
666     }
667
668     fn check_expr_return(
669         &self,
670         expr_opt: Option<&'tcx hir::Expr<'tcx>>,
671         expr: &'tcx hir::Expr<'tcx>,
672     ) -> Ty<'tcx> {
673         if self.ret_coercion.is_none() {
674             self.tcx.sess.emit_err(ReturnStmtOutsideOfFnBody { span: expr.span });
675         } else if let Some(e) = expr_opt {
676             if self.ret_coercion_span.get().is_none() {
677                 self.ret_coercion_span.set(Some(e.span));
678             }
679             self.check_return_expr(e);
680         } else {
681             let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
682             if self.ret_coercion_span.get().is_none() {
683                 self.ret_coercion_span.set(Some(expr.span));
684             }
685             let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
686             if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
687                 coercion.coerce_forced_unit(
688                     self,
689                     &cause,
690                     &mut |db| {
691                         let span = fn_decl.output.span();
692                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
693                             db.span_label(
694                                 span,
695                                 format!("expected `{}` because of this return type", snippet),
696                             );
697                         }
698                     },
699                     true,
700                 );
701             } else {
702                 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
703             }
704         }
705         self.tcx.types.never
706     }
707
708     pub(super) fn check_return_expr(&self, return_expr: &'tcx hir::Expr<'tcx>) {
709         let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
710             span_bug!(return_expr.span, "check_return_expr called outside fn body")
711         });
712
713         let ret_ty = ret_coercion.borrow().expected_ty();
714         let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
715         ret_coercion.borrow_mut().coerce(
716             self,
717             &self.cause(return_expr.span, ObligationCauseCode::ReturnValue(return_expr.hir_id)),
718             return_expr,
719             return_expr_ty,
720         );
721     }
722
723     pub(crate) fn check_lhs_assignable(
724         &self,
725         lhs: &'tcx hir::Expr<'tcx>,
726         err_code: &'static str,
727         expr_span: &Span,
728     ) {
729         if lhs.is_syntactic_place_expr() {
730             return;
731         }
732
733         // FIXME: Make this use SessionDiagnostic once error codes can be dynamically set.
734         let mut err = self.tcx.sess.struct_span_err_with_code(
735             *expr_span,
736             "invalid left-hand side of assignment",
737             DiagnosticId::Error(err_code.into()),
738         );
739         err.span_label(lhs.span, "cannot assign to this expression");
740         err.emit();
741     }
742
743     // A generic function for checking the 'then' and 'else' clauses in an 'if'
744     // or 'if-else' expression.
745     fn check_then_else(
746         &self,
747         cond_expr: &'tcx hir::Expr<'tcx>,
748         then_expr: &'tcx hir::Expr<'tcx>,
749         opt_else_expr: Option<&'tcx hir::Expr<'tcx>>,
750         sp: Span,
751         orig_expected: Expectation<'tcx>,
752     ) -> Ty<'tcx> {
753         let cond_ty = self.check_expr_has_type_or_error(cond_expr, self.tcx.types.bool, |_| {});
754
755         self.warn_if_unreachable(cond_expr.hir_id, then_expr.span, "block in `if` expression");
756
757         let cond_diverges = self.diverges.get();
758         self.diverges.set(Diverges::Maybe);
759
760         let expected = orig_expected.adjust_for_branches(self);
761         let then_ty = self.check_expr_with_expectation(then_expr, expected);
762         let then_diverges = self.diverges.get();
763         self.diverges.set(Diverges::Maybe);
764
765         // We've already taken the expected type's preferences
766         // into account when typing the `then` branch. To figure
767         // out the initial shot at a LUB, we thus only consider
768         // `expected` if it represents a *hard* constraint
769         // (`only_has_type`); otherwise, we just go with a
770         // fresh type variable.
771         let coerce_to_ty = expected.coercion_target_type(self, sp);
772         let mut coerce: DynamicCoerceMany<'_> = CoerceMany::new(coerce_to_ty);
773
774         coerce.coerce(self, &self.misc(sp), then_expr, then_ty);
775
776         if let Some(else_expr) = opt_else_expr {
777             let else_ty = self.check_expr_with_expectation(else_expr, expected);
778             let else_diverges = self.diverges.get();
779
780             let opt_suggest_box_span =
781                 self.opt_suggest_box_span(else_expr.span, else_ty, orig_expected);
782             let if_cause =
783                 self.if_cause(sp, then_expr, else_expr, then_ty, else_ty, opt_suggest_box_span);
784
785             coerce.coerce(self, &if_cause, else_expr, else_ty);
786
787             // We won't diverge unless both branches do (or the condition does).
788             self.diverges.set(cond_diverges | then_diverges & else_diverges);
789         } else {
790             self.if_fallback_coercion(sp, then_expr, &mut coerce, |hir_id, span| {
791                 self.maybe_get_coercion_reason_if(hir_id, span)
792             });
793
794             // If the condition is false we can't diverge.
795             self.diverges.set(cond_diverges);
796         }
797
798         let result_ty = coerce.complete(self);
799         if cond_ty.references_error() { self.tcx.ty_error() } else { result_ty }
800     }
801
802     /// Type check assignment expression `expr` of form `lhs = rhs`.
803     /// The expected type is `()` and is passed to the function for the purposes of diagnostics.
804     fn check_expr_assign(
805         &self,
806         expr: &'tcx hir::Expr<'tcx>,
807         expected: Expectation<'tcx>,
808         lhs: &'tcx hir::Expr<'tcx>,
809         rhs: &'tcx hir::Expr<'tcx>,
810         span: &Span,
811     ) -> Ty<'tcx> {
812         let expected_ty = expected.coercion_target_type(self, expr.span);
813         if expected_ty == self.tcx.types.bool {
814             // The expected type is `bool` but this will result in `()` so we can reasonably
815             // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
816             // The likely cause of this is `if foo = bar { .. }`.
817             let actual_ty = self.tcx.mk_unit();
818             let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
819             let lhs_ty = self.check_expr(&lhs);
820             let rhs_ty = self.check_expr(&rhs);
821             let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
822                 (Applicability::MachineApplicable, true)
823             } else {
824                 (Applicability::MaybeIncorrect, false)
825             };
826             if !lhs.is_syntactic_place_expr() {
827                 // Do not suggest `if let x = y` as `==` is way more likely to be the intention.
828                 let mut span_err = || {
829                     // Likely `if let` intended.
830                     err.span_suggestion_verbose(
831                         expr.span.shrink_to_lo(),
832                         "you might have meant to use pattern matching",
833                         "let ".to_string(),
834                         applicability,
835                     );
836                 };
837                 if let hir::Node::Expr(hir::Expr {
838                     kind: ExprKind::Match(_, _, hir::MatchSource::WhileDesugar),
839                     ..
840                 }) = self.tcx.hir().get(
841                     self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
842                 ) {
843                     span_err();
844                 } else if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) =
845                     self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id))
846                 {
847                     span_err();
848                 }
849             }
850             if eq {
851                 err.span_suggestion_verbose(
852                     *span,
853                     "you might have meant to compare for equality",
854                     "==".to_string(),
855                     applicability,
856                 );
857             }
858
859             if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() {
860                 // We already emitted an `if let` suggestion due to an identifier not found.
861                 err.delay_as_bug();
862             } else {
863                 err.emit();
864             }
865             return self.tcx.ty_error();
866         }
867
868         self.check_lhs_assignable(lhs, "E0070", span);
869
870         let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
871         let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
872
873         self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
874
875         if lhs_ty.references_error() || rhs_ty.references_error() {
876             self.tcx.ty_error()
877         } else {
878             self.tcx.mk_unit()
879         }
880     }
881
882     fn check_expr_loop(
883         &self,
884         body: &'tcx hir::Block<'tcx>,
885         source: hir::LoopSource,
886         expected: Expectation<'tcx>,
887         expr: &'tcx hir::Expr<'tcx>,
888     ) -> Ty<'tcx> {
889         let coerce = match source {
890             // you can only use break with a value from a normal `loop { }`
891             hir::LoopSource::Loop => {
892                 let coerce_to = expected.coercion_target_type(self, body.span);
893                 Some(CoerceMany::new(coerce_to))
894             }
895
896             hir::LoopSource::While | hir::LoopSource::WhileLet | hir::LoopSource::ForLoop => None,
897         };
898
899         let ctxt = BreakableCtxt {
900             coerce,
901             may_break: false, // Will get updated if/when we find a `break`.
902         };
903
904         let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
905             self.check_block_no_value(&body);
906         });
907
908         if ctxt.may_break {
909             // No way to know whether it's diverging because
910             // of a `break` or an outer `break` or `return`.
911             self.diverges.set(Diverges::Maybe);
912         }
913
914         // If we permit break with a value, then result type is
915         // the LUB of the breaks (possibly ! if none); else, it
916         // is nil. This makes sense because infinite loops
917         // (which would have type !) are only possible iff we
918         // permit break with a value [1].
919         if ctxt.coerce.is_none() && !ctxt.may_break {
920             // [1]
921             self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
922         }
923         ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
924     }
925
926     /// Checks a method call.
927     fn check_method_call(
928         &self,
929         expr: &'tcx hir::Expr<'tcx>,
930         segment: &hir::PathSegment<'_>,
931         span: Span,
932         args: &'tcx [hir::Expr<'tcx>],
933         expected: Expectation<'tcx>,
934     ) -> Ty<'tcx> {
935         let rcvr = &args[0];
936         let rcvr_t = self.check_expr(&rcvr);
937         // no need to check for bot/err -- callee does that
938         let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
939
940         let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
941             Ok(method) => {
942                 // We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
943                 // trigger this codepath causing `structuraly_resolved_type` to emit an error.
944
945                 self.write_method_call(expr.hir_id, method);
946                 Ok(method)
947             }
948             Err(error) => {
949                 if segment.ident.name != kw::Empty {
950                     self.report_extended_method_error(segment, span, args, rcvr_t, error);
951                 }
952                 Err(())
953             }
954         };
955
956         // Call the generic checker.
957         self.check_method_argument_types(
958             span,
959             expr,
960             method,
961             &args[1..],
962             DontTupleArguments,
963             expected,
964         )
965     }
966
967     fn report_extended_method_error(
968         &self,
969         segment: &hir::PathSegment<'_>,
970         span: Span,
971         args: &'tcx [hir::Expr<'tcx>],
972         rcvr_t: Ty<'tcx>,
973         error: MethodError<'tcx>,
974     ) {
975         let rcvr = &args[0];
976         let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
977             if let Some(new_rcvr_t) = new_rcvr_t {
978                 if let Ok(pick) = self.lookup_probe(
979                     span,
980                     segment.ident,
981                     new_rcvr_t,
982                     rcvr,
983                     probe::ProbeScope::AllTraits,
984                 ) {
985                     debug!("try_alt_rcvr: pick candidate {:?}", pick);
986                     // Make sure the method is defined for the *actual* receiver:
987                     // we don't want to treat `Box<Self>` as a receiver if
988                     // it only works because of an autoderef to `&self`
989                     if pick.autoderefs == 0 {
990                         err.span_label(
991                             pick.item.ident.span,
992                             &format!("the method is available for `{}` here", new_rcvr_t),
993                         );
994                     }
995                 }
996             }
997         };
998
999         if let Some(mut err) = self.report_method_error(
1000             span,
1001             rcvr_t,
1002             segment.ident,
1003             SelfSource::MethodCall(rcvr),
1004             error,
1005             Some(args),
1006         ) {
1007             if let ty::Adt(..) = rcvr_t.kind() {
1008                 // Try alternative arbitrary self types that could fulfill this call.
1009                 // FIXME: probe for all types that *could* be arbitrary self-types, not
1010                 // just this list.
1011                 try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, LangItem::OwnedBox));
1012                 try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, LangItem::Pin));
1013                 try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Arc));
1014                 try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Rc));
1015             }
1016             err.emit();
1017         }
1018     }
1019
1020     fn check_expr_cast(
1021         &self,
1022         e: &'tcx hir::Expr<'tcx>,
1023         t: &'tcx hir::Ty<'tcx>,
1024         expr: &'tcx hir::Expr<'tcx>,
1025     ) -> Ty<'tcx> {
1026         // Find the type of `e`. Supply hints based on the type we are casting to,
1027         // if appropriate.
1028         let t_cast = self.to_ty_saving_user_provided_ty(t);
1029         let t_cast = self.resolve_vars_if_possible(t_cast);
1030         let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
1031         let t_cast = self.resolve_vars_if_possible(t_cast);
1032
1033         // Eagerly check for some obvious errors.
1034         if t_expr.references_error() || t_cast.references_error() {
1035             self.tcx.ty_error()
1036         } else {
1037             // Defer other checks until we're done type checking.
1038             let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1039             match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
1040                 Ok(cast_check) => {
1041                     deferred_cast_checks.push(cast_check);
1042                     t_cast
1043                 }
1044                 Err(ErrorReported) => self.tcx.ty_error(),
1045             }
1046         }
1047     }
1048
1049     fn check_expr_array(
1050         &self,
1051         args: &'tcx [hir::Expr<'tcx>],
1052         expected: Expectation<'tcx>,
1053         expr: &'tcx hir::Expr<'tcx>,
1054     ) -> Ty<'tcx> {
1055         let element_ty = if !args.is_empty() {
1056             let coerce_to = expected
1057                 .to_option(self)
1058                 .and_then(|uty| match *uty.kind() {
1059                     ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
1060                     _ => None,
1061                 })
1062                 .unwrap_or_else(|| {
1063                     self.next_ty_var(TypeVariableOrigin {
1064                         kind: TypeVariableOriginKind::TypeInference,
1065                         span: expr.span,
1066                     })
1067                 });
1068             let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
1069             assert_eq!(self.diverges.get(), Diverges::Maybe);
1070             for e in args {
1071                 let e_ty = self.check_expr_with_hint(e, coerce_to);
1072                 let cause = self.misc(e.span);
1073                 coerce.coerce(self, &cause, e, e_ty);
1074             }
1075             coerce.complete(self)
1076         } else {
1077             self.next_ty_var(TypeVariableOrigin {
1078                 kind: TypeVariableOriginKind::TypeInference,
1079                 span: expr.span,
1080             })
1081         };
1082         self.tcx.mk_array(element_ty, args.len() as u64)
1083     }
1084
1085     fn check_expr_repeat(
1086         &self,
1087         element: &'tcx hir::Expr<'tcx>,
1088         count: &'tcx hir::AnonConst,
1089         expected: Expectation<'tcx>,
1090         _expr: &'tcx hir::Expr<'tcx>,
1091     ) -> Ty<'tcx> {
1092         let tcx = self.tcx;
1093         let count = self.to_const(count);
1094
1095         let uty = match expected {
1096             ExpectHasType(uty) => match *uty.kind() {
1097                 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
1098                 _ => None,
1099             },
1100             _ => None,
1101         };
1102
1103         let (element_ty, t) = match uty {
1104             Some(uty) => {
1105                 self.check_expr_coercable_to_type(&element, uty, None);
1106                 (uty, uty)
1107             }
1108             None => {
1109                 let ty = self.next_ty_var(TypeVariableOrigin {
1110                     kind: TypeVariableOriginKind::MiscVariable,
1111                     span: element.span,
1112                 });
1113                 let element_ty = self.check_expr_has_type_or_error(&element, ty, |_| {});
1114                 (element_ty, ty)
1115             }
1116         };
1117
1118         if element_ty.references_error() {
1119             return tcx.ty_error();
1120         }
1121
1122         tcx.mk_ty(ty::Array(t, count))
1123     }
1124
1125     fn check_expr_tuple(
1126         &self,
1127         elts: &'tcx [hir::Expr<'tcx>],
1128         expected: Expectation<'tcx>,
1129         expr: &'tcx hir::Expr<'tcx>,
1130     ) -> Ty<'tcx> {
1131         let flds = expected.only_has_type(self).and_then(|ty| {
1132             let ty = self.resolve_vars_with_obligations(ty);
1133             match ty.kind() {
1134                 ty::Tuple(flds) => Some(&flds[..]),
1135                 _ => None,
1136             }
1137         });
1138
1139         let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
1140             Some(fs) if i < fs.len() => {
1141                 let ety = fs[i].expect_ty();
1142                 self.check_expr_coercable_to_type(&e, ety, None);
1143                 ety
1144             }
1145             _ => self.check_expr_with_expectation(&e, NoExpectation),
1146         });
1147         let tuple = self.tcx.mk_tup(elt_ts_iter);
1148         if tuple.references_error() {
1149             self.tcx.ty_error()
1150         } else {
1151             self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
1152             tuple
1153         }
1154     }
1155
1156     fn check_expr_struct(
1157         &self,
1158         expr: &hir::Expr<'_>,
1159         expected: Expectation<'tcx>,
1160         qpath: &QPath<'_>,
1161         fields: &'tcx [hir::Field<'tcx>],
1162         base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
1163     ) -> Ty<'tcx> {
1164         // Find the relevant variant
1165         let (variant, adt_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id)
1166         {
1167             variant_ty
1168         } else {
1169             self.check_struct_fields_on_error(fields, base_expr);
1170             return self.tcx.ty_error();
1171         };
1172
1173         // Prohibit struct expressions when non-exhaustive flag is set.
1174         let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
1175         if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
1176             self.tcx
1177                 .sess
1178                 .emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() });
1179         }
1180
1181         let error_happened = self.check_expr_struct_fields(
1182             adt_ty,
1183             expected,
1184             expr.hir_id,
1185             qpath.span(),
1186             variant,
1187             fields,
1188             base_expr.is_none(),
1189         );
1190         if let Some(base_expr) = base_expr {
1191             // If check_expr_struct_fields hit an error, do not attempt to populate
1192             // the fields with the base_expr. This could cause us to hit errors later
1193             // when certain fields are assumed to exist that in fact do not.
1194             if !error_happened {
1195                 self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {});
1196                 match adt_ty.kind() {
1197                     ty::Adt(adt, substs) if adt.is_struct() => {
1198                         let fru_field_types = adt
1199                             .non_enum_variant()
1200                             .fields
1201                             .iter()
1202                             .map(|f| {
1203                                 self.normalize_associated_types_in(
1204                                     expr.span,
1205                                     f.ty(self.tcx, substs),
1206                                 )
1207                             })
1208                             .collect();
1209
1210                         self.typeck_results
1211                             .borrow_mut()
1212                             .fru_field_types_mut()
1213                             .insert(expr.hir_id, fru_field_types);
1214                     }
1215                     _ => {
1216                         self.tcx
1217                             .sess
1218                             .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
1219                     }
1220                 }
1221             }
1222         }
1223         self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
1224         adt_ty
1225     }
1226
1227     fn check_expr_struct_fields(
1228         &self,
1229         adt_ty: Ty<'tcx>,
1230         expected: Expectation<'tcx>,
1231         expr_id: hir::HirId,
1232         span: Span,
1233         variant: &'tcx ty::VariantDef,
1234         ast_fields: &'tcx [hir::Field<'tcx>],
1235         check_completeness: bool,
1236     ) -> bool {
1237         let tcx = self.tcx;
1238
1239         let adt_ty_hint = self
1240             .expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
1241             .get(0)
1242             .cloned()
1243             .unwrap_or(adt_ty);
1244         // re-link the regions that EIfEO can erase.
1245         self.demand_eqtype(span, adt_ty_hint, adt_ty);
1246
1247         let (substs, adt_kind, kind_name) = match adt_ty.kind() {
1248             ty::Adt(adt, substs) => (substs, adt.adt_kind(), adt.variant_descr()),
1249             _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields"),
1250         };
1251
1252         let mut remaining_fields = variant
1253             .fields
1254             .iter()
1255             .enumerate()
1256             .map(|(i, field)| (field.ident.normalize_to_macros_2_0(), (i, field)))
1257             .collect::<FxHashMap<_, _>>();
1258
1259         let mut seen_fields = FxHashMap::default();
1260
1261         let mut error_happened = false;
1262
1263         // Type-check each field.
1264         for field in ast_fields {
1265             let ident = tcx.adjust_ident(field.ident, variant.def_id);
1266             let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
1267                 seen_fields.insert(ident, field.span);
1268                 self.write_field_index(field.hir_id, i);
1269
1270                 // We don't look at stability attributes on
1271                 // struct-like enums (yet...), but it's definitely not
1272                 // a bug to have constructed one.
1273                 if adt_kind != AdtKind::Enum {
1274                     tcx.check_stability(v_field.did, Some(expr_id), field.span);
1275                 }
1276
1277                 self.field_ty(field.span, v_field, substs)
1278             } else {
1279                 error_happened = true;
1280                 if let Some(prev_span) = seen_fields.get(&ident) {
1281                     tcx.sess.emit_err(FieldMultiplySpecifiedInInitializer {
1282                         span: field.ident.span,
1283                         prev_span: *prev_span,
1284                         ident,
1285                     });
1286                 } else {
1287                     self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span);
1288                 }
1289
1290                 tcx.ty_error()
1291             };
1292
1293             // Make sure to give a type to the field even if there's
1294             // an error, so we can continue type-checking.
1295             self.check_expr_coercable_to_type(&field.expr, field_type, None);
1296         }
1297
1298         // Make sure the programmer specified correct number of fields.
1299         if kind_name == "union" {
1300             if ast_fields.len() != 1 {
1301                 tcx.sess.span_err(span, "union expressions should have exactly one field");
1302             }
1303         } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
1304             let no_accessible_remaining_fields = remaining_fields
1305                 .iter()
1306                 .find(|(_, (_, field))| {
1307                     field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
1308                 })
1309                 .is_none();
1310
1311             if no_accessible_remaining_fields {
1312                 self.report_no_accessible_fields(adt_ty, span);
1313             } else {
1314                 self.report_missing_fields(adt_ty, span, remaining_fields);
1315             }
1316         }
1317
1318         error_happened
1319     }
1320
1321     fn check_struct_fields_on_error(
1322         &self,
1323         fields: &'tcx [hir::Field<'tcx>],
1324         base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
1325     ) {
1326         for field in fields {
1327             self.check_expr(&field.expr);
1328         }
1329         if let Some(base) = *base_expr {
1330             self.check_expr(&base);
1331         }
1332     }
1333
1334     /// Report an error for a struct field expression when there are fields which aren't provided.
1335     ///
1336     /// ```text
1337     /// error: missing field `you_can_use_this_field` in initializer of `foo::Foo`
1338     ///  --> src/main.rs:8:5
1339     ///   |
1340     /// 8 |     foo::Foo {};
1341     ///   |     ^^^^^^^^ missing `you_can_use_this_field`
1342     ///
1343     /// error: aborting due to previous error
1344     /// ```
1345     fn report_missing_fields(
1346         &self,
1347         adt_ty: Ty<'tcx>,
1348         span: Span,
1349         remaining_fields: FxHashMap<Ident, (usize, &ty::FieldDef)>,
1350     ) {
1351         let len = remaining_fields.len();
1352
1353         let mut displayable_field_names =
1354             remaining_fields.keys().map(|ident| ident.as_str()).collect::<Vec<_>>();
1355
1356         displayable_field_names.sort();
1357
1358         let mut truncated_fields_error = String::new();
1359         let remaining_fields_names = match &displayable_field_names[..] {
1360             [field1] => format!("`{}`", field1),
1361             [field1, field2] => format!("`{}` and `{}`", field1, field2),
1362             [field1, field2, field3] => format!("`{}`, `{}` and `{}`", field1, field2, field3),
1363             _ => {
1364                 truncated_fields_error =
1365                     format!(" and {} other field{}", len - 3, pluralize!(len - 3));
1366                 displayable_field_names
1367                     .iter()
1368                     .take(3)
1369                     .map(|n| format!("`{}`", n))
1370                     .collect::<Vec<_>>()
1371                     .join(", ")
1372             }
1373         };
1374
1375         struct_span_err!(
1376             self.tcx.sess,
1377             span,
1378             E0063,
1379             "missing field{} {}{} in initializer of `{}`",
1380             pluralize!(len),
1381             remaining_fields_names,
1382             truncated_fields_error,
1383             adt_ty
1384         )
1385         .span_label(span, format!("missing {}{}", remaining_fields_names, truncated_fields_error))
1386         .emit();
1387     }
1388
1389     /// Report an error for a struct field expression when there are no visible fields.
1390     ///
1391     /// ```text
1392     /// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
1393     ///  --> src/main.rs:8:5
1394     ///   |
1395     /// 8 |     foo::Foo {};
1396     ///   |     ^^^^^^^^
1397     ///
1398     /// error: aborting due to previous error
1399     /// ```
1400     fn report_no_accessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
1401         self.tcx.sess.span_err(
1402             span,
1403             &format!(
1404                 "cannot construct `{}` with struct literal syntax due to inaccessible fields",
1405                 adt_ty,
1406             ),
1407         );
1408     }
1409
1410     fn report_unknown_field(
1411         &self,
1412         ty: Ty<'tcx>,
1413         variant: &'tcx ty::VariantDef,
1414         field: &hir::Field<'_>,
1415         skip_fields: &[hir::Field<'_>],
1416         kind_name: &str,
1417         ty_span: Span,
1418     ) {
1419         if variant.is_recovered() {
1420             self.set_tainted_by_errors();
1421             return;
1422         }
1423         let mut err = self.type_error_struct_with_diag(
1424             field.ident.span,
1425             |actual| match ty.kind() {
1426                 ty::Adt(adt, ..) if adt.is_enum() => struct_span_err!(
1427                     self.tcx.sess,
1428                     field.ident.span,
1429                     E0559,
1430                     "{} `{}::{}` has no field named `{}`",
1431                     kind_name,
1432                     actual,
1433                     variant.ident,
1434                     field.ident
1435                 ),
1436                 _ => struct_span_err!(
1437                     self.tcx.sess,
1438                     field.ident.span,
1439                     E0560,
1440                     "{} `{}` has no field named `{}`",
1441                     kind_name,
1442                     actual,
1443                     field.ident
1444                 ),
1445             },
1446             ty,
1447         );
1448         match variant.ctor_kind {
1449             CtorKind::Fn => match ty.kind() {
1450                 ty::Adt(adt, ..) if adt.is_enum() => {
1451                     err.span_label(
1452                         variant.ident.span,
1453                         format!(
1454                             "`{adt}::{variant}` defined here",
1455                             adt = ty,
1456                             variant = variant.ident,
1457                         ),
1458                     );
1459                     err.span_label(field.ident.span, "field does not exist");
1460                     err.span_suggestion(
1461                         ty_span,
1462                         &format!(
1463                             "`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
1464                             adt = ty,
1465                             variant = variant.ident,
1466                         ),
1467                         format!(
1468                             "{adt}::{variant}(/* fields */)",
1469                             adt = ty,
1470                             variant = variant.ident,
1471                         ),
1472                         Applicability::HasPlaceholders,
1473                     );
1474                 }
1475                 _ => {
1476                     err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
1477                     err.span_label(field.ident.span, "field does not exist");
1478                     err.span_suggestion(
1479                         ty_span,
1480                         &format!(
1481                             "`{adt}` is a tuple {kind_name}, use the appropriate syntax",
1482                             adt = ty,
1483                             kind_name = kind_name,
1484                         ),
1485                         format!("{adt}(/* fields */)", adt = ty),
1486                         Applicability::HasPlaceholders,
1487                     );
1488                 }
1489             },
1490             _ => {
1491                 // prevent all specified fields from being suggested
1492                 let skip_fields = skip_fields.iter().map(|x| x.ident.name);
1493                 if let Some(field_name) =
1494                     Self::suggest_field_name(variant, field.ident.name, skip_fields.collect())
1495                 {
1496                     err.span_suggestion(
1497                         field.ident.span,
1498                         "a field with a similar name exists",
1499                         field_name.to_string(),
1500                         Applicability::MaybeIncorrect,
1501                     );
1502                 } else {
1503                     match ty.kind() {
1504                         ty::Adt(adt, ..) => {
1505                             if adt.is_enum() {
1506                                 err.span_label(
1507                                     field.ident.span,
1508                                     format!("`{}::{}` does not have this field", ty, variant.ident),
1509                                 );
1510                             } else {
1511                                 err.span_label(
1512                                     field.ident.span,
1513                                     format!("`{}` does not have this field", ty),
1514                                 );
1515                             }
1516                             let available_field_names = self.available_field_names(variant);
1517                             if !available_field_names.is_empty() {
1518                                 err.note(&format!(
1519                                     "available fields are: {}",
1520                                     self.name_series_display(available_field_names)
1521                                 ));
1522                             }
1523                         }
1524                         _ => bug!("non-ADT passed to report_unknown_field"),
1525                     }
1526                 };
1527             }
1528         }
1529         err.emit();
1530     }
1531
1532     // Return an hint about the closest match in field names
1533     fn suggest_field_name(
1534         variant: &'tcx ty::VariantDef,
1535         field: Symbol,
1536         skip: Vec<Symbol>,
1537     ) -> Option<Symbol> {
1538         let names = variant
1539             .fields
1540             .iter()
1541             .filter_map(|field| {
1542                 // ignore already set fields and private fields from non-local crates
1543                 if skip.iter().any(|&x| x == field.ident.name)
1544                     || (!variant.def_id.is_local() && field.vis != Visibility::Public)
1545                 {
1546                     None
1547                 } else {
1548                     Some(field.ident.name)
1549                 }
1550             })
1551             .collect::<Vec<Symbol>>();
1552
1553         find_best_match_for_name(&names, field, None)
1554     }
1555
1556     fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<Symbol> {
1557         variant
1558             .fields
1559             .iter()
1560             .filter(|field| {
1561                 let def_scope = self
1562                     .tcx
1563                     .adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id)
1564                     .1;
1565                 field.vis.is_accessible_from(def_scope, self.tcx)
1566             })
1567             .map(|field| field.ident.name)
1568             .collect()
1569     }
1570
1571     fn name_series_display(&self, names: Vec<Symbol>) -> String {
1572         // dynamic limit, to never omit just one field
1573         let limit = if names.len() == 6 { 6 } else { 5 };
1574         let mut display =
1575             names.iter().take(limit).map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
1576         if names.len() > limit {
1577             display = format!("{} ... and {} others", display, names.len() - limit);
1578         }
1579         display
1580     }
1581
1582     // Check field access expressions
1583     fn check_field(
1584         &self,
1585         expr: &'tcx hir::Expr<'tcx>,
1586         base: &'tcx hir::Expr<'tcx>,
1587         field: Ident,
1588     ) -> Ty<'tcx> {
1589         debug!("check_field(expr: {:?}, base: {:?}, field: {:?})", expr, base, field);
1590         let expr_t = self.check_expr(base);
1591         let expr_t = self.structurally_resolved_type(base.span, expr_t);
1592         let mut private_candidate = None;
1593         let mut autoderef = self.autoderef(expr.span, expr_t);
1594         while let Some((base_t, _)) = autoderef.next() {
1595             debug!("base_t: {:?}", base_t);
1596             match base_t.kind() {
1597                 ty::Adt(base_def, substs) if !base_def.is_enum() => {
1598                     debug!("struct named {:?}", base_t);
1599                     let (ident, def_scope) =
1600                         self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
1601                     let fields = &base_def.non_enum_variant().fields;
1602                     if let Some(index) =
1603                         fields.iter().position(|f| f.ident.normalize_to_macros_2_0() == ident)
1604                     {
1605                         let field = &fields[index];
1606                         let field_ty = self.field_ty(expr.span, field, substs);
1607                         // Save the index of all fields regardless of their visibility in case
1608                         // of error recovery.
1609                         self.write_field_index(expr.hir_id, index);
1610                         if field.vis.is_accessible_from(def_scope, self.tcx) {
1611                             let adjustments = self.adjust_steps(&autoderef);
1612                             self.apply_adjustments(base, adjustments);
1613                             self.register_predicates(autoderef.into_obligations());
1614
1615                             self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span);
1616                             return field_ty;
1617                         }
1618                         private_candidate = Some((base_def.did, field_ty));
1619                     }
1620                 }
1621                 ty::Tuple(tys) => {
1622                     let fstr = field.as_str();
1623                     if let Ok(index) = fstr.parse::<usize>() {
1624                         if fstr == index.to_string() {
1625                             if let Some(field_ty) = tys.get(index) {
1626                                 let adjustments = self.adjust_steps(&autoderef);
1627                                 self.apply_adjustments(base, adjustments);
1628                                 self.register_predicates(autoderef.into_obligations());
1629
1630                                 self.write_field_index(expr.hir_id, index);
1631                                 return field_ty.expect_ty();
1632                             }
1633                         }
1634                     }
1635                 }
1636                 _ => {}
1637             }
1638         }
1639         self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
1640
1641         if let Some((did, field_ty)) = private_candidate {
1642             self.ban_private_field_access(expr, expr_t, field, did);
1643             return field_ty;
1644         }
1645
1646         if field.name == kw::Empty {
1647         } else if self.method_exists(field, expr_t, expr.hir_id, true) {
1648             self.ban_take_value_of_method(expr, expr_t, field);
1649         } else if !expr_t.is_primitive_ty() {
1650             self.ban_nonexisting_field(field, base, expr, expr_t);
1651         } else {
1652             type_error_struct!(
1653                 self.tcx().sess,
1654                 field.span,
1655                 expr_t,
1656                 E0610,
1657                 "`{}` is a primitive type and therefore doesn't have fields",
1658                 expr_t
1659             )
1660             .emit();
1661         }
1662
1663         self.tcx().ty_error()
1664     }
1665
1666     fn suggest_await_on_field_access(
1667         &self,
1668         err: &mut DiagnosticBuilder<'_>,
1669         field_ident: Ident,
1670         base: &'tcx hir::Expr<'tcx>,
1671         ty: Ty<'tcx>,
1672     ) {
1673         let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
1674             Some(output_ty) => self.resolve_vars_if_possible(output_ty),
1675             _ => return,
1676         };
1677         let mut add_label = true;
1678         if let ty::Adt(def, _) = output_ty.kind() {
1679             // no field access on enum type
1680             if !def.is_enum() {
1681                 if def.non_enum_variant().fields.iter().any(|field| field.ident == field_ident) {
1682                     add_label = false;
1683                     err.span_label(
1684                         field_ident.span,
1685                         "field not available in `impl Future`, but it is available in its `Output`",
1686                     );
1687                     err.span_suggestion_verbose(
1688                         base.span.shrink_to_hi(),
1689                         "consider `await`ing on the `Future` and access the field of its `Output`",
1690                         ".await".to_string(),
1691                         Applicability::MaybeIncorrect,
1692                     );
1693                 }
1694             }
1695         }
1696         if add_label {
1697             err.span_label(field_ident.span, &format!("field not found in `{}`", ty));
1698         }
1699     }
1700
1701     fn ban_nonexisting_field(
1702         &self,
1703         field: Ident,
1704         base: &'tcx hir::Expr<'tcx>,
1705         expr: &'tcx hir::Expr<'tcx>,
1706         expr_t: Ty<'tcx>,
1707     ) {
1708         debug!(
1709             "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, expr_ty={:?}",
1710             field, base, expr, expr_t
1711         );
1712         let mut err = self.no_such_field_err(field, expr_t);
1713
1714         match *expr_t.peel_refs().kind() {
1715             ty::Array(_, len) => {
1716                 self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
1717             }
1718             ty::RawPtr(..) => {
1719                 self.suggest_first_deref_field(&mut err, expr, base, field);
1720             }
1721             ty::Adt(def, _) if !def.is_enum() => {
1722                 self.suggest_fields_on_recordish(&mut err, def, field);
1723             }
1724             ty::Param(param_ty) => {
1725                 self.point_at_param_definition(&mut err, param_ty);
1726             }
1727             ty::Opaque(_, _) => {
1728                 self.suggest_await_on_field_access(&mut err, field, base, expr_t.peel_refs());
1729             }
1730             _ => {}
1731         }
1732
1733         if field.name == kw::Await {
1734             // We know by construction that `<expr>.await` is either on Rust 2015
1735             // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
1736             err.note("to `.await` a `Future`, switch to Rust 2018 or later");
1737             err.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
1738             err.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
1739         }
1740
1741         err.emit();
1742     }
1743
1744     fn ban_private_field_access(
1745         &self,
1746         expr: &hir::Expr<'_>,
1747         expr_t: Ty<'tcx>,
1748         field: Ident,
1749         base_did: DefId,
1750     ) {
1751         let struct_path = self.tcx().def_path_str(base_did);
1752         let kind_name = self.tcx().def_kind(base_did).descr(base_did);
1753         let mut err = struct_span_err!(
1754             self.tcx().sess,
1755             field.span,
1756             E0616,
1757             "field `{}` of {} `{}` is private",
1758             field,
1759             kind_name,
1760             struct_path
1761         );
1762         err.span_label(field.span, "private field");
1763         // Also check if an accessible method exists, which is often what is meant.
1764         if self.method_exists(field, expr_t, expr.hir_id, false) && !self.expr_in_place(expr.hir_id)
1765         {
1766             self.suggest_method_call(
1767                 &mut err,
1768                 &format!("a method `{}` also exists, call it with parentheses", field),
1769                 field,
1770                 expr_t,
1771                 expr,
1772             );
1773         }
1774         err.emit();
1775     }
1776
1777     fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field: Ident) {
1778         let mut err = type_error_struct!(
1779             self.tcx().sess,
1780             field.span,
1781             expr_t,
1782             E0615,
1783             "attempted to take value of method `{}` on type `{}`",
1784             field,
1785             expr_t
1786         );
1787         err.span_label(field.span, "method, not a field");
1788         if !self.expr_in_place(expr.hir_id) {
1789             self.suggest_method_call(
1790                 &mut err,
1791                 "use parentheses to call the method",
1792                 field,
1793                 expr_t,
1794                 expr,
1795             );
1796         } else {
1797             err.help("methods are immutable and cannot be assigned to");
1798         }
1799
1800         err.emit();
1801     }
1802
1803     fn point_at_param_definition(&self, err: &mut DiagnosticBuilder<'_>, param: ty::ParamTy) {
1804         let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
1805         let generic_param = generics.type_param(&param, self.tcx);
1806         if let ty::GenericParamDefKind::Type { synthetic: Some(..), .. } = generic_param.kind {
1807             return;
1808         }
1809         let param_def_id = generic_param.def_id;
1810         let param_hir_id = match param_def_id.as_local() {
1811             Some(x) => self.tcx.hir().local_def_id_to_hir_id(x),
1812             None => return,
1813         };
1814         let param_span = self.tcx.hir().span(param_hir_id);
1815         let param_name = self.tcx.hir().ty_param_name(param_hir_id);
1816
1817         err.span_label(param_span, &format!("type parameter '{}' declared here", param_name));
1818     }
1819
1820     fn suggest_fields_on_recordish(
1821         &self,
1822         err: &mut DiagnosticBuilder<'_>,
1823         def: &'tcx ty::AdtDef,
1824         field: Ident,
1825     ) {
1826         if let Some(suggested_field_name) =
1827             Self::suggest_field_name(def.non_enum_variant(), field.name, vec![])
1828         {
1829             err.span_suggestion(
1830                 field.span,
1831                 "a field with a similar name exists",
1832                 suggested_field_name.to_string(),
1833                 Applicability::MaybeIncorrect,
1834             );
1835         } else {
1836             err.span_label(field.span, "unknown field");
1837             let struct_variant_def = def.non_enum_variant();
1838             let field_names = self.available_field_names(struct_variant_def);
1839             if !field_names.is_empty() {
1840                 err.note(&format!(
1841                     "available fields are: {}",
1842                     self.name_series_display(field_names),
1843                 ));
1844             }
1845         }
1846     }
1847
1848     fn maybe_suggest_array_indexing(
1849         &self,
1850         err: &mut DiagnosticBuilder<'_>,
1851         expr: &hir::Expr<'_>,
1852         base: &hir::Expr<'_>,
1853         field: Ident,
1854         len: &ty::Const<'tcx>,
1855     ) {
1856         if let (Some(len), Ok(user_index)) =
1857             (len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
1858         {
1859             if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
1860                 let help = "instead of using tuple indexing, use array indexing";
1861                 let suggestion = format!("{}[{}]", base, field);
1862                 let applicability = if len < user_index {
1863                     Applicability::MachineApplicable
1864                 } else {
1865                     Applicability::MaybeIncorrect
1866                 };
1867                 err.span_suggestion(expr.span, help, suggestion, applicability);
1868             }
1869         }
1870     }
1871
1872     fn suggest_first_deref_field(
1873         &self,
1874         err: &mut DiagnosticBuilder<'_>,
1875         expr: &hir::Expr<'_>,
1876         base: &hir::Expr<'_>,
1877         field: Ident,
1878     ) {
1879         if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
1880             let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
1881             let suggestion = format!("(*{}).{}", base, field);
1882             err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect);
1883         }
1884     }
1885
1886     fn no_such_field_err(
1887         &self,
1888         field: Ident,
1889         expr_t: &'tcx ty::TyS<'tcx>,
1890     ) -> DiagnosticBuilder<'_> {
1891         let span = field.span;
1892         debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
1893
1894         let mut err = type_error_struct!(
1895             self.tcx().sess,
1896             field.span,
1897             expr_t,
1898             E0609,
1899             "no field `{}` on type `{}`",
1900             field,
1901             expr_t
1902         );
1903
1904         // try to add a suggestion in case the field is a nested field of a field of the Adt
1905         if let Some((fields, substs)) = self.get_field_candidates(span, &expr_t) {
1906             for candidate_field in fields.iter() {
1907                 if let Some(field_path) =
1908                     self.check_for_nested_field(span, field, candidate_field, substs, vec![])
1909                 {
1910                     let field_path_str = field_path
1911                         .iter()
1912                         .map(|id| id.name.to_ident_string())
1913                         .collect::<Vec<String>>()
1914                         .join(".");
1915                     debug!("field_path_str: {:?}", field_path_str);
1916
1917                     err.span_suggestion_verbose(
1918                         field.span.shrink_to_lo(),
1919                         "one of the expressions' fields has a field of the same name",
1920                         format!("{}.", field_path_str),
1921                         Applicability::MaybeIncorrect,
1922                     );
1923                 }
1924             }
1925         }
1926         err
1927     }
1928
1929     fn get_field_candidates(
1930         &self,
1931         span: Span,
1932         base_t: Ty<'tcx>,
1933     ) -> Option<(&Vec<ty::FieldDef>, SubstsRef<'tcx>)> {
1934         debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_t);
1935
1936         let mut autoderef = self.autoderef(span, base_t);
1937         while let Some((base_t, _)) = autoderef.next() {
1938             match base_t.kind() {
1939                 ty::Adt(base_def, substs) if !base_def.is_enum() => {
1940                     let fields = &base_def.non_enum_variant().fields;
1941                     // For compile-time reasons put a limit on number of fields we search
1942                     if fields.len() > 100 {
1943                         return None;
1944                     }
1945                     return Some((fields, substs));
1946                 }
1947                 _ => {}
1948             }
1949         }
1950         None
1951     }
1952
1953     /// This method is called after we have encountered a missing field error to recursively
1954     /// search for the field
1955     fn check_for_nested_field(
1956         &self,
1957         span: Span,
1958         target_field: Ident,
1959         candidate_field: &ty::FieldDef,
1960         subst: SubstsRef<'tcx>,
1961         mut field_path: Vec<Ident>,
1962     ) -> Option<Vec<Ident>> {
1963         debug!(
1964             "check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}",
1965             span, candidate_field, field_path
1966         );
1967
1968         if candidate_field.ident == target_field {
1969             Some(field_path)
1970         } else if field_path.len() > 3 {
1971             // For compile-time reasons and to avoid infinite recursion we only check for fields
1972             // up to a depth of three
1973             None
1974         } else {
1975             // recursively search fields of `candidate_field` if it's a ty::Adt
1976
1977             field_path.push(candidate_field.ident.normalize_to_macros_2_0());
1978             let field_ty = candidate_field.ty(self.tcx, subst);
1979             if let Some((nested_fields, subst)) = self.get_field_candidates(span, &field_ty) {
1980                 for field in nested_fields.iter() {
1981                     let ident = field.ident.normalize_to_macros_2_0();
1982                     if ident == target_field {
1983                         return Some(field_path);
1984                     } else {
1985                         let field_path = field_path.clone();
1986                         if let Some(path) = self.check_for_nested_field(
1987                             span,
1988                             target_field,
1989                             field,
1990                             subst,
1991                             field_path,
1992                         ) {
1993                             return Some(path);
1994                         }
1995                     }
1996                 }
1997             }
1998             None
1999         }
2000     }
2001
2002     fn check_expr_index(
2003         &self,
2004         base: &'tcx hir::Expr<'tcx>,
2005         idx: &'tcx hir::Expr<'tcx>,
2006         expr: &'tcx hir::Expr<'tcx>,
2007     ) -> Ty<'tcx> {
2008         let base_t = self.check_expr(&base);
2009         let idx_t = self.check_expr(&idx);
2010
2011         if base_t.references_error() {
2012             base_t
2013         } else if idx_t.references_error() {
2014             idx_t
2015         } else {
2016             let base_t = self.structurally_resolved_type(base.span, base_t);
2017             match self.lookup_indexing(expr, base, base_t, idx_t) {
2018                 Some((index_ty, element_ty)) => {
2019                     // two-phase not needed because index_ty is never mutable
2020                     self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
2021                     element_ty
2022                 }
2023                 None => {
2024                     let mut err = type_error_struct!(
2025                         self.tcx.sess,
2026                         expr.span,
2027                         base_t,
2028                         E0608,
2029                         "cannot index into a value of type `{}`",
2030                         base_t
2031                     );
2032                     // Try to give some advice about indexing tuples.
2033                     if let ty::Tuple(..) = base_t.kind() {
2034                         let mut needs_note = true;
2035                         // If the index is an integer, we can show the actual
2036                         // fixed expression:
2037                         if let ExprKind::Lit(ref lit) = idx.kind {
2038                             if let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node {
2039                                 let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
2040                                 if let Ok(snip) = snip {
2041                                     err.span_suggestion(
2042                                         expr.span,
2043                                         "to access tuple elements, use",
2044                                         format!("{}.{}", snip, i),
2045                                         Applicability::MachineApplicable,
2046                                     );
2047                                     needs_note = false;
2048                                 }
2049                             }
2050                         }
2051                         if needs_note {
2052                             err.help(
2053                                 "to access tuple elements, use tuple indexing \
2054                                         syntax (e.g., `tuple.0`)",
2055                             );
2056                         }
2057                     }
2058                     err.emit();
2059                     self.tcx.ty_error()
2060                 }
2061             }
2062         }
2063     }
2064
2065     fn check_expr_yield(
2066         &self,
2067         value: &'tcx hir::Expr<'tcx>,
2068         expr: &'tcx hir::Expr<'tcx>,
2069         src: &'tcx hir::YieldSource,
2070     ) -> Ty<'tcx> {
2071         match self.resume_yield_tys {
2072             Some((resume_ty, yield_ty)) => {
2073                 self.check_expr_coercable_to_type(&value, yield_ty, None);
2074
2075                 resume_ty
2076             }
2077             // Given that this `yield` expression was generated as a result of lowering a `.await`,
2078             // we know that the yield type must be `()`; however, the context won't contain this
2079             // information. Hence, we check the source of the yield expression here and check its
2080             // value's type against `()` (this check should always hold).
2081             None if src.is_await() => {
2082                 self.check_expr_coercable_to_type(&value, self.tcx.mk_unit(), None);
2083                 self.tcx.mk_unit()
2084             }
2085             _ => {
2086                 self.tcx.sess.emit_err(YieldExprOutsideOfGenerator { span: expr.span });
2087                 self.tcx.mk_unit()
2088             }
2089         }
2090     }
2091
2092     fn check_expr_asm_operand(&self, expr: &'tcx hir::Expr<'tcx>, is_input: bool) {
2093         let needs = if is_input { Needs::None } else { Needs::MutPlace };
2094         let ty = self.check_expr_with_needs(expr, needs);
2095         self.require_type_is_sized(ty, expr.span, traits::InlineAsmSized);
2096
2097         if !is_input && !expr.is_syntactic_place_expr() {
2098             let mut err = self.tcx.sess.struct_span_err(expr.span, "invalid asm output");
2099             err.span_label(expr.span, "cannot assign to this expression");
2100             err.emit();
2101         }
2102
2103         // If this is an input value, we require its type to be fully resolved
2104         // at this point. This allows us to provide helpful coercions which help
2105         // pass the type candidate list in a later pass.
2106         //
2107         // We don't require output types to be resolved at this point, which
2108         // allows them to be inferred based on how they are used later in the
2109         // function.
2110         if is_input {
2111             let ty = self.structurally_resolved_type(expr.span, &ty);
2112             match *ty.kind() {
2113                 ty::FnDef(..) => {
2114                     let fnptr_ty = self.tcx.mk_fn_ptr(ty.fn_sig(self.tcx));
2115                     self.demand_coerce(expr, ty, fnptr_ty, None, AllowTwoPhase::No);
2116                 }
2117                 ty::Ref(_, base_ty, mutbl) => {
2118                     let ptr_ty = self.tcx.mk_ptr(ty::TypeAndMut { ty: base_ty, mutbl });
2119                     self.demand_coerce(expr, ty, ptr_ty, None, AllowTwoPhase::No);
2120                 }
2121                 _ => {}
2122             }
2123         }
2124     }
2125
2126     fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
2127         for (op, _op_sp) in asm.operands {
2128             match op {
2129                 hir::InlineAsmOperand::In { expr, .. } | hir::InlineAsmOperand::Const { expr } => {
2130                     self.check_expr_asm_operand(expr, true);
2131                 }
2132                 hir::InlineAsmOperand::Out { expr, .. } => {
2133                     if let Some(expr) = expr {
2134                         self.check_expr_asm_operand(expr, false);
2135                     }
2136                 }
2137                 hir::InlineAsmOperand::InOut { expr, .. } => {
2138                     self.check_expr_asm_operand(expr, false);
2139                 }
2140                 hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
2141                     self.check_expr_asm_operand(in_expr, true);
2142                     if let Some(out_expr) = out_expr {
2143                         self.check_expr_asm_operand(out_expr, false);
2144                     }
2145                 }
2146                 hir::InlineAsmOperand::Sym { expr } => {
2147                     self.check_expr(expr);
2148                 }
2149             }
2150         }
2151         if asm.options.contains(ast::InlineAsmOptions::NORETURN) {
2152             self.tcx.types.never
2153         } else {
2154             self.tcx.mk_unit()
2155         }
2156     }
2157 }
2158
2159 pub(super) fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
2160     Some(match ty.kind() {
2161         ty::Bool => "true",
2162         ty::Char => "'a'",
2163         ty::Int(_) | ty::Uint(_) => "42",
2164         ty::Float(_) => "3.14159",
2165         ty::Error(_) | ty::Never => return None,
2166         _ => "value",
2167     })
2168 }