]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/mod.rs
Merge commit '370c397ec9169809e5ad270079712e0043514240' into sync_cg_clif-2022-03-20
[rust.git] / compiler / rustc_typeck / src / check / mod.rs
1 /*!
2
3 # typeck: check phase
4
5 Within the check phase of type check, we check each item one at a time
6 (bodies of function expressions are checked as part of the containing
7 function). Inference is used to supply types wherever they are unknown.
8
9 By far the most complex case is checking the body of a function. This
10 can be broken down into several distinct phases:
11
12 - gather: creates type variables to represent the type of each local
13   variable and pattern binding.
14
15 - main: the main pass does the lion's share of the work: it
16   determines the types of all expressions, resolves
17   methods, checks for most invalid conditions, and so forth.  In
18   some cases, where a type is unknown, it may create a type or region
19   variable and use that as the type of an expression.
20
21   In the process of checking, various constraints will be placed on
22   these type variables through the subtyping relationships requested
23   through the `demand` module.  The `infer` module is in charge
24   of resolving those constraints.
25
26 - regionck: after main is complete, the regionck pass goes over all
27   types looking for regions and making sure that they did not escape
28   into places they are not in scope.  This may also influence the
29   final assignments of the various region variables if there is some
30   flexibility.
31
32 - writeback: writes the final types within a function body, replacing
33   type variables with their final inferred types.  These final types
34   are written into the `tcx.node_types` table, which should *never* contain
35   any reference to a type variable.
36
37 ## Intermediate types
38
39 While type checking a function, the intermediate types for the
40 expressions, blocks, and so forth contained within the function are
41 stored in `fcx.node_types` and `fcx.node_substs`.  These types
42 may contain unresolved type variables.  After type checking is
43 complete, the functions in the writeback module are used to take the
44 types from this table, resolve them, and then write them into their
45 permanent home in the type context `tcx`.
46
47 This means that during inferencing you should use `fcx.write_ty()`
48 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
49 nodes within the function.
50
51 The types of top-level items, which never contain unbound type
52 variables, are stored directly into the `tcx` typeck_results.
53
54 N.B., a type variable is not the same thing as a type parameter.  A
55 type variable is an instance of a type parameter. That is,
56 given a generic function `fn foo<T>(t: T)`, while checking the
57 function `foo`, the type `ty_param(0)` refers to the type `T`, which
58 is treated in abstract. However, when `foo()` is called, `T` will be
59 substituted for a fresh type variable `N`.  This variable will
60 eventually be resolved to some concrete type (which might itself be
61 a type parameter).
62
63 */
64
65 pub mod _match;
66 mod autoderef;
67 mod callee;
68 pub mod cast;
69 mod check;
70 mod closure;
71 pub mod coercion;
72 mod compare_method;
73 pub mod demand;
74 mod diverges;
75 pub mod dropck;
76 mod expectation;
77 mod expr;
78 mod fallback;
79 mod fn_ctxt;
80 mod gather_locals;
81 mod generator_interior;
82 mod inherited;
83 pub mod intrinsic;
84 pub mod method;
85 mod op;
86 mod pat;
87 mod place_op;
88 mod regionck;
89 mod upvar;
90 mod wfcheck;
91 pub mod writeback;
92
93 use check::{
94     check_abi, check_fn, check_impl_item_well_formed, check_item_well_formed, check_mod_item_types,
95     check_trait_item_well_formed,
96 };
97 pub use check::{check_item_type, check_wf_new};
98 pub use diverges::Diverges;
99 pub use expectation::Expectation;
100 pub use fn_ctxt::*;
101 pub use inherited::{Inherited, InheritedBuilder};
102
103 use crate::astconv::AstConv;
104 use crate::check::gather_locals::GatherLocalsVisitor;
105 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
106 use rustc_errors::{pluralize, struct_span_err, Applicability};
107 use rustc_hir as hir;
108 use rustc_hir::def::Res;
109 use rustc_hir::def_id::{DefId, LocalDefId};
110 use rustc_hir::intravisit::Visitor;
111 use rustc_hir::itemlikevisit::ItemLikeVisitor;
112 use rustc_hir::{HirIdMap, ImplicitSelfKind, Node};
113 use rustc_index::bit_set::BitSet;
114 use rustc_index::vec::Idx;
115 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
116 use rustc_middle::ty::query::Providers;
117 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
118 use rustc_middle::ty::{self, Ty, TyCtxt, UserType};
119 use rustc_session::config;
120 use rustc_session::parse::feature_err;
121 use rustc_session::Session;
122 use rustc_span::source_map::DUMMY_SP;
123 use rustc_span::symbol::{kw, Ident};
124 use rustc_span::{self, BytePos, MultiSpan, Span};
125 use rustc_target::abi::VariantIdx;
126 use rustc_target::spec::abi::Abi;
127 use rustc_trait_selection::traits;
128 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
129 use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
130
131 use std::cell::{Ref, RefCell, RefMut};
132
133 use crate::require_c_abi_if_c_variadic;
134 use crate::util::common::indenter;
135
136 use self::coercion::DynamicCoerceMany;
137 pub use self::Expectation::*;
138
139 #[macro_export]
140 macro_rules! type_error_struct {
141     ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
142         let mut err = rustc_errors::struct_span_err!($session, $span, $code, $($message)*);
143
144         if $typ.references_error() {
145             err.downgrade_to_delayed_bug();
146         }
147
148         err
149     })
150 }
151
152 /// The type of a local binding, including the revealed type for anon types.
153 #[derive(Copy, Clone, Debug)]
154 pub struct LocalTy<'tcx> {
155     decl_ty: Ty<'tcx>,
156     revealed_ty: Ty<'tcx>,
157 }
158
159 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
160 pub enum Needs {
161     MutPlace,
162     None,
163 }
164
165 impl Needs {
166     fn maybe_mut_place(m: hir::Mutability) -> Self {
167         match m {
168             hir::Mutability::Mut => Needs::MutPlace,
169             hir::Mutability::Not => Needs::None,
170         }
171     }
172 }
173
174 #[derive(Copy, Clone)]
175 pub struct UnsafetyState {
176     pub def: hir::HirId,
177     pub unsafety: hir::Unsafety,
178     from_fn: bool,
179 }
180
181 impl UnsafetyState {
182     pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
183         UnsafetyState { def, unsafety, from_fn: true }
184     }
185
186     pub fn recurse(self, blk: &hir::Block<'_>) -> UnsafetyState {
187         use hir::BlockCheckMode;
188         match self.unsafety {
189             // If this unsafe, then if the outer function was already marked as
190             // unsafe we shouldn't attribute the unsafe'ness to the block. This
191             // way the block can be warned about instead of ignoring this
192             // extraneous block (functions are never warned about).
193             hir::Unsafety::Unsafe if self.from_fn => self,
194
195             unsafety => {
196                 let (unsafety, def) = match blk.rules {
197                     BlockCheckMode::UnsafeBlock(..) => (hir::Unsafety::Unsafe, blk.hir_id),
198                     BlockCheckMode::DefaultBlock => (unsafety, self.def),
199                 };
200                 UnsafetyState { def, unsafety, from_fn: false }
201             }
202         }
203     }
204 }
205
206 #[derive(Debug, Copy, Clone)]
207 pub enum PlaceOp {
208     Deref,
209     Index,
210 }
211
212 pub struct BreakableCtxt<'tcx> {
213     may_break: bool,
214
215     // this is `null` for loops where break with a value is illegal,
216     // such as `while`, `for`, and `while let`
217     coerce: Option<DynamicCoerceMany<'tcx>>,
218 }
219
220 pub struct EnclosingBreakables<'tcx> {
221     stack: Vec<BreakableCtxt<'tcx>>,
222     by_id: HirIdMap<usize>,
223 }
224
225 impl<'tcx> EnclosingBreakables<'tcx> {
226     fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
227         self.opt_find_breakable(target_id).unwrap_or_else(|| {
228             bug!("could not find enclosing breakable with id {}", target_id);
229         })
230     }
231
232     fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
233         match self.by_id.get(&target_id) {
234             Some(ix) => Some(&mut self.stack[*ix]),
235             None => None,
236         }
237     }
238 }
239
240 pub fn provide(providers: &mut Providers) {
241     method::provide(providers);
242     *providers = Providers {
243         typeck_item_bodies,
244         typeck_const_arg,
245         typeck,
246         diagnostic_only_typeck,
247         has_typeck_results,
248         adt_destructor,
249         used_trait_imports,
250         check_item_well_formed,
251         check_trait_item_well_formed,
252         check_impl_item_well_formed,
253         check_mod_item_types,
254         ..*providers
255     };
256 }
257
258 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
259     tcx.calculate_dtor(def_id, dropck::check_drop_impl)
260 }
261
262 /// If this `DefId` is a "primary tables entry", returns
263 /// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`.
264 ///
265 /// If this function returns `Some`, then `typeck_results(def_id)` will
266 /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
267 /// may not succeed. In some cases where this function returns `None`
268 /// (notably closures), `typeck_results(def_id)` would wind up
269 /// redirecting to the owning function.
270 fn primary_body_of(
271     tcx: TyCtxt<'_>,
272     id: hir::HirId,
273 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> {
274     match tcx.hir().get(id) {
275         Node::Item(item) => match item.kind {
276             hir::ItemKind::Const(ty, body) | hir::ItemKind::Static(ty, _, body) => {
277                 Some((body, Some(ty), None))
278             }
279             hir::ItemKind::Fn(ref sig, .., body) => Some((body, None, Some(sig))),
280             _ => None,
281         },
282         Node::TraitItem(item) => match item.kind {
283             hir::TraitItemKind::Const(ty, Some(body)) => Some((body, Some(ty), None)),
284             hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
285                 Some((body, None, Some(sig)))
286             }
287             _ => None,
288         },
289         Node::ImplItem(item) => match item.kind {
290             hir::ImplItemKind::Const(ty, body) => Some((body, Some(ty), None)),
291             hir::ImplItemKind::Fn(ref sig, body) => Some((body, None, Some(sig))),
292             _ => None,
293         },
294         Node::AnonConst(constant) => Some((constant.body, None, None)),
295         _ => None,
296     }
297 }
298
299 fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
300     // Closures' typeck results come from their outermost function,
301     // as they are part of the same "inference environment".
302     let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
303     if typeck_root_def_id != def_id {
304         return tcx.has_typeck_results(typeck_root_def_id);
305     }
306
307     if let Some(def_id) = def_id.as_local() {
308         let id = tcx.hir().local_def_id_to_hir_id(def_id);
309         primary_body_of(tcx, id).is_some()
310     } else {
311         false
312     }
313 }
314
315 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet<LocalDefId> {
316     &*tcx.typeck(def_id).used_trait_imports
317 }
318
319 fn typeck_const_arg<'tcx>(
320     tcx: TyCtxt<'tcx>,
321     (did, param_did): (LocalDefId, DefId),
322 ) -> &ty::TypeckResults<'tcx> {
323     let fallback = move || tcx.type_of(param_did);
324     typeck_with_fallback(tcx, did, fallback)
325 }
326
327 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
328     if let Some(param_did) = tcx.opt_const_param_of(def_id) {
329         tcx.typeck_const_arg((def_id, param_did))
330     } else {
331         let fallback = move || tcx.type_of(def_id.to_def_id());
332         typeck_with_fallback(tcx, def_id, fallback)
333     }
334 }
335
336 /// Used only to get `TypeckResults` for type inference during error recovery.
337 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
338 fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
339     let fallback = move || {
340         let span = tcx.hir().span(tcx.hir().local_def_id_to_hir_id(def_id));
341         tcx.ty_error_with_message(span, "diagnostic only typeck table used")
342     };
343     typeck_with_fallback(tcx, def_id, fallback)
344 }
345
346 fn typeck_with_fallback<'tcx>(
347     tcx: TyCtxt<'tcx>,
348     def_id: LocalDefId,
349     fallback: impl Fn() -> Ty<'tcx> + 'tcx,
350 ) -> &'tcx ty::TypeckResults<'tcx> {
351     // Closures' typeck results come from their outermost function,
352     // as they are part of the same "inference environment".
353     let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local();
354     if typeck_root_def_id != def_id {
355         return tcx.typeck(typeck_root_def_id);
356     }
357
358     let id = tcx.hir().local_def_id_to_hir_id(def_id);
359     let span = tcx.hir().span(id);
360
361     // Figure out what primary body this item has.
362     let (body_id, body_ty, fn_sig) = primary_body_of(tcx, id).unwrap_or_else(|| {
363         span_bug!(span, "can't type-check body of {:?}", def_id);
364     });
365     let body = tcx.hir().body(body_id);
366
367     let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
368         let param_env = tcx.param_env(def_id);
369         let (fcx, wf_tys) = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
370             let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
371                 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
372                 <dyn AstConv<'_>>::ty_of_fn(
373                     &fcx,
374                     id,
375                     header.unsafety,
376                     header.abi,
377                     decl,
378                     &hir::Generics::empty(),
379                     None,
380                     None,
381                 )
382             } else {
383                 tcx.fn_sig(def_id)
384             };
385
386             check_abi(tcx, id, span, fn_sig.abi());
387
388             // When normalizing the function signature, we assume all types are
389             // well-formed. So, we don't need to worry about the obligations
390             // from normalization. We could just discard these, but to align with
391             // compare_method and elsewhere, we just add implied bounds for
392             // these types.
393             let mut wf_tys = FxHashSet::default();
394             // Compute the fty from point of view of inside the fn.
395             let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
396             let fn_sig = inh.normalize_associated_types_in(
397                 body.value.span,
398                 body_id.hir_id,
399                 param_env,
400                 fn_sig,
401             );
402             wf_tys.extend(fn_sig.inputs_and_output.iter());
403
404             let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None, true).0;
405             (fcx, wf_tys)
406         } else {
407             let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
408             let expected_type = body_ty
409                 .and_then(|ty| match ty.kind {
410                     hir::TyKind::Infer => Some(<dyn AstConv<'_>>::ast_ty_to_ty(&fcx, ty)),
411                     _ => None,
412                 })
413                 .unwrap_or_else(|| match tcx.hir().get(id) {
414                     Node::AnonConst(_) => match tcx.hir().get(tcx.hir().get_parent_node(id)) {
415                         Node::Expr(&hir::Expr {
416                             kind: hir::ExprKind::ConstBlock(ref anon_const),
417                             ..
418                         }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
419                             kind: TypeVariableOriginKind::TypeInference,
420                             span,
421                         }),
422                         Node::Ty(&hir::Ty {
423                             kind: hir::TyKind::Typeof(ref anon_const), ..
424                         }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
425                             kind: TypeVariableOriginKind::TypeInference,
426                             span,
427                         }),
428                         Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
429                         | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. })
430                             if asm.operands.iter().any(|(op, _op_sp)| match op {
431                                 hir::InlineAsmOperand::Const { anon_const } => {
432                                     anon_const.hir_id == id
433                                 }
434                                 _ => false,
435                             }) =>
436                         {
437                             // Inline assembly constants must be integers.
438                             fcx.next_int_var()
439                         }
440                         _ => fallback(),
441                     },
442                     _ => fallback(),
443                 });
444
445             let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
446             fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
447
448             // Gather locals in statics (because of block expressions).
449             GatherLocalsVisitor::new(&fcx).visit_body(body);
450
451             fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
452
453             fcx.write_ty(id, expected_type);
454
455             (fcx, FxHashSet::default())
456         };
457
458         let fallback_has_occurred = fcx.type_inference_fallback();
459
460         // Even though coercion casts provide type hints, we check casts after fallback for
461         // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
462         fcx.check_casts();
463         fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
464
465         // Closure and generator analysis may run after fallback
466         // because they don't constrain other type variables.
467         fcx.closure_analyze(body);
468         assert!(fcx.deferred_call_resolutions.borrow().is_empty());
469         fcx.resolve_generator_interiors(def_id.to_def_id());
470
471         for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
472             let ty = fcx.normalize_ty(span, ty);
473             fcx.require_type_is_sized(ty, span, code);
474         }
475
476         fcx.select_all_obligations_or_error();
477
478         if fn_sig.is_some() {
479             fcx.regionck_fn(id, body, span, wf_tys);
480         } else {
481             fcx.regionck_expr(body);
482         }
483
484         fcx.resolve_type_vars_in_body(body)
485     });
486
487     // Consistency check our TypeckResults instance can hold all ItemLocalIds
488     // it will need to hold.
489     assert_eq!(typeck_results.hir_owner, id.owner);
490
491     typeck_results
492 }
493
494 /// When `check_fn` is invoked on a generator (i.e., a body that
495 /// includes yield), it returns back some information about the yield
496 /// points.
497 struct GeneratorTypes<'tcx> {
498     /// Type of generator argument / values returned by `yield`.
499     resume_ty: Ty<'tcx>,
500
501     /// Type of value that is yielded.
502     yield_ty: Ty<'tcx>,
503
504     /// Types that are captured (see `GeneratorInterior` for more).
505     interior: Ty<'tcx>,
506
507     /// Indicates if the generator is movable or static (immovable).
508     movability: hir::Movability,
509 }
510
511 /// Given a `DefId` for an opaque type in return position, find its parent item's return
512 /// expressions.
513 fn get_owner_return_paths<'tcx>(
514     tcx: TyCtxt<'tcx>,
515     def_id: LocalDefId,
516 ) -> Option<(LocalDefId, ReturnsVisitor<'tcx>)> {
517     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
518     let parent_id = tcx.hir().get_parent_item(hir_id);
519     tcx.hir().find_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
520         let body = tcx.hir().body(body_id);
521         let mut visitor = ReturnsVisitor::default();
522         visitor.visit_body(body);
523         (parent_id, visitor)
524     })
525 }
526
527 // Forbid defining intrinsics in Rust code,
528 // as they must always be defined by the compiler.
529 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
530     if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
531         tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
532     }
533 }
534
535 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
536     // Only restricted on wasm target for now
537     if !tcx.sess.target.is_like_wasm {
538         return;
539     }
540
541     // If `#[link_section]` is missing, then nothing to verify
542     let attrs = tcx.codegen_fn_attrs(id);
543     if attrs.link_section.is_none() {
544         return;
545     }
546
547     // For the wasm32 target statics with `#[link_section]` are placed into custom
548     // sections of the final output file, but this isn't link custom sections of
549     // other executable formats. Namely we can only embed a list of bytes,
550     // nothing with pointers to anything else or relocations. If any relocation
551     // show up, reject them here.
552     // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
553     // the consumer's responsibility to ensure all bytes that have been read
554     // have defined values.
555     if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) {
556         if alloc.inner().relocations().len() != 0 {
557             let msg = "statics with a custom `#[link_section]` must be a \
558                            simple list of bytes on the wasm target with no \
559                            extra levels of indirection such as references";
560             tcx.sess.span_err(span, msg);
561         }
562     }
563 }
564
565 fn report_forbidden_specialization(
566     tcx: TyCtxt<'_>,
567     impl_item: &hir::ImplItemRef,
568     parent_impl: DefId,
569 ) {
570     let mut err = struct_span_err!(
571         tcx.sess,
572         impl_item.span,
573         E0520,
574         "`{}` specializes an item from a parent `impl`, but \
575          that item is not marked `default`",
576         impl_item.ident
577     );
578     err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
579
580     match tcx.span_of_impl(parent_impl) {
581         Ok(span) => {
582             err.span_label(span, "parent `impl` is here");
583             err.note(&format!(
584                 "to specialize, `{}` in the parent `impl` must be marked `default`",
585                 impl_item.ident
586             ));
587         }
588         Err(cname) => {
589             err.note(&format!("parent implementation is in crate `{}`", cname));
590         }
591     }
592
593     err.emit();
594 }
595
596 fn missing_items_err(
597     tcx: TyCtxt<'_>,
598     impl_span: Span,
599     missing_items: &[&ty::AssocItem],
600     full_impl_span: Span,
601 ) {
602     let missing_items_msg = missing_items
603         .iter()
604         .map(|trait_item| trait_item.name.to_string())
605         .collect::<Vec<_>>()
606         .join("`, `");
607
608     let mut err = struct_span_err!(
609         tcx.sess,
610         impl_span,
611         E0046,
612         "not all trait items implemented, missing: `{}`",
613         missing_items_msg
614     );
615     err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
616
617     // `Span` before impl block closing brace.
618     let hi = full_impl_span.hi() - BytePos(1);
619     // Point at the place right before the closing brace of the relevant `impl` to suggest
620     // adding the associated item at the end of its body.
621     let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
622     // Obtain the level of indentation ending in `sugg_sp`.
623     let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
624     // Make the whitespace that will make the suggestion have the right indentation.
625     let padding: String = " ".repeat(indentation);
626
627     for trait_item in missing_items {
628         let snippet = suggestion_signature(trait_item, tcx);
629         let code = format!("{}{}\n{}", padding, snippet, padding);
630         let msg = format!("implement the missing item: `{}`", snippet);
631         let appl = Applicability::HasPlaceholders;
632         if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
633             err.span_label(span, format!("`{}` from trait", trait_item.name));
634             err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
635         } else {
636             err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
637         }
638     }
639     err.emit();
640 }
641
642 fn missing_items_must_implement_one_of_err(
643     tcx: TyCtxt<'_>,
644     impl_span: Span,
645     missing_items: &[Ident],
646     annotation_span: Option<Span>,
647 ) {
648     let missing_items_msg =
649         missing_items.iter().map(Ident::to_string).collect::<Vec<_>>().join("`, `");
650
651     let mut err = struct_span_err!(
652         tcx.sess,
653         impl_span,
654         E0046,
655         "not all trait items implemented, missing one of: `{}`",
656         missing_items_msg
657     );
658     err.span_label(impl_span, format!("missing one of `{}` in implementation", missing_items_msg));
659
660     if let Some(annotation_span) = annotation_span {
661         err.span_note(annotation_span, "required because of this annotation");
662     }
663
664     err.emit();
665 }
666
667 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
668 fn bounds_from_generic_predicates<'tcx>(
669     tcx: TyCtxt<'tcx>,
670     predicates: ty::GenericPredicates<'tcx>,
671 ) -> (String, String) {
672     let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
673     let mut projections = vec![];
674     for (predicate, _) in predicates.predicates {
675         debug!("predicate {:?}", predicate);
676         let bound_predicate = predicate.kind();
677         match bound_predicate.skip_binder() {
678             ty::PredicateKind::Trait(trait_predicate) => {
679                 let entry = types.entry(trait_predicate.self_ty()).or_default();
680                 let def_id = trait_predicate.def_id();
681                 if Some(def_id) != tcx.lang_items().sized_trait() {
682                     // Type params are `Sized` by default, do not add that restriction to the list
683                     // if it is a positive requirement.
684                     entry.push(trait_predicate.def_id());
685                 }
686             }
687             ty::PredicateKind::Projection(projection_pred) => {
688                 projections.push(bound_predicate.rebind(projection_pred));
689             }
690             _ => {}
691         }
692     }
693     let generics = if types.is_empty() {
694         "".to_string()
695     } else {
696         format!(
697             "<{}>",
698             types
699                 .keys()
700                 .filter_map(|t| match t.kind() {
701                     ty::Param(_) => Some(t.to_string()),
702                     // Avoid suggesting the following:
703                     // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
704                     _ => None,
705                 })
706                 .collect::<Vec<_>>()
707                 .join(", ")
708         )
709     };
710     let mut where_clauses = vec![];
711     for (ty, bounds) in types {
712         where_clauses
713             .extend(bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))));
714     }
715     for projection in &projections {
716         let p = projection.skip_binder();
717         // FIXME: this is not currently supported syntax, we should be looking at the `types` and
718         // insert the associated types where they correspond, but for now let's be "lazy" and
719         // propose this instead of the following valid resugaring:
720         // `T: Trait, Trait::Assoc = K` â†’ `T: Trait<Assoc = K>`
721         where_clauses.push(format!(
722             "{} = {}",
723             tcx.def_path_str(p.projection_ty.item_def_id),
724             p.term,
725         ));
726     }
727     let where_clauses = if where_clauses.is_empty() {
728         String::new()
729     } else {
730         format!(" where {}", where_clauses.join(", "))
731     };
732     (generics, where_clauses)
733 }
734
735 /// Return placeholder code for the given function.
736 fn fn_sig_suggestion<'tcx>(
737     tcx: TyCtxt<'tcx>,
738     sig: ty::FnSig<'tcx>,
739     ident: Ident,
740     predicates: ty::GenericPredicates<'tcx>,
741     assoc: &ty::AssocItem,
742 ) -> String {
743     let args = sig
744         .inputs()
745         .iter()
746         .enumerate()
747         .map(|(i, ty)| {
748             Some(match ty.kind() {
749                 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
750                 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
751                     let reg = match &format!("{}", reg)[..] {
752                         "'_" | "" => String::new(),
753                         reg => format!("{} ", reg),
754                     };
755                     if assoc.fn_has_self_parameter {
756                         match ref_ty.kind() {
757                             ty::Param(param) if param.name == kw::SelfUpper => {
758                                 format!("&{}{}self", reg, mutability.prefix_str())
759                             }
760
761                             _ => format!("self: {}", ty),
762                         }
763                     } else {
764                         format!("_: {}", ty)
765                     }
766                 }
767                 _ => {
768                     if assoc.fn_has_self_parameter && i == 0 {
769                         format!("self: {}", ty)
770                     } else {
771                         format!("_: {}", ty)
772                     }
773                 }
774             })
775         })
776         .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
777         .flatten()
778         .collect::<Vec<String>>()
779         .join(", ");
780     let output = sig.output();
781     let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() };
782
783     let unsafety = sig.unsafety.prefix_str();
784     let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
785
786     // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
787     // not be present in the `fn` definition, not will we account for renamed
788     // lifetimes between the `impl` and the `trait`, but this should be good enough to
789     // fill in a significant portion of the missing code, and other subsequent
790     // suggestions can help the user fix the code.
791     format!(
792         "{}fn {}{}({}){}{} {{ todo!() }}",
793         unsafety, ident, generics, args, output, where_clauses
794     )
795 }
796
797 /// Return placeholder code for the given associated item.
798 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
799 /// structured suggestion.
800 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
801     match assoc.kind {
802         ty::AssocKind::Fn => {
803             // We skip the binder here because the binder would deanonymize all
804             // late-bound regions, and we don't want method signatures to show up
805             // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
806             // regions just fine, showing `fn(&MyType)`.
807             fn_sig_suggestion(
808                 tcx,
809                 tcx.fn_sig(assoc.def_id).skip_binder(),
810                 assoc.ident(tcx),
811                 tcx.predicates_of(assoc.def_id),
812                 assoc,
813             )
814         }
815         ty::AssocKind::Type => format!("type {} = Type;", assoc.name),
816         ty::AssocKind::Const => {
817             let ty = tcx.type_of(assoc.def_id);
818             let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
819             format!("const {}: {} = {};", assoc.name, ty, val)
820         }
821     }
822 }
823
824 /// Emit an error when encountering two or more variants in a transparent enum.
825 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, did: DefId) {
826     let variant_spans: Vec<_> = adt
827         .variants()
828         .iter()
829         .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
830         .collect();
831     let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
832     let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
833     err.span_label(sp, &msg);
834     if let [start @ .., end] = &*variant_spans {
835         for variant_span in start {
836             err.span_label(*variant_span, "");
837         }
838         err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
839     }
840     err.emit();
841 }
842
843 /// Emit an error when encountering two or more non-zero-sized fields in a transparent
844 /// enum.
845 fn bad_non_zero_sized_fields<'tcx>(
846     tcx: TyCtxt<'tcx>,
847     adt: ty::AdtDef<'tcx>,
848     field_count: usize,
849     field_spans: impl Iterator<Item = Span>,
850     sp: Span,
851 ) {
852     let msg = format!("needs at most one non-zero-sized field, but has {}", field_count);
853     let mut err = struct_span_err!(
854         tcx.sess,
855         sp,
856         E0690,
857         "{}transparent {} {}",
858         if adt.is_enum() { "the variant of a " } else { "" },
859         adt.descr(),
860         msg,
861     );
862     err.span_label(sp, &msg);
863     for sp in field_spans {
864         err.span_label(sp, "this field is non-zero-sized");
865     }
866     err.emit();
867 }
868
869 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
870     struct_span_err!(
871         tcx.sess,
872         span,
873         E0533,
874         "expected unit struct, unit variant or constant, found {}{}",
875         res.descr(),
876         tcx.sess
877             .source_map()
878             .span_to_snippet(span)
879             .map_or_else(|_| String::new(), |s| format!(" `{}`", s)),
880     )
881     .emit();
882 }
883
884 /// Controls whether the arguments are tupled. This is used for the call
885 /// operator.
886 ///
887 /// Tupling means that all call-side arguments are packed into a tuple and
888 /// passed as a single parameter. For example, if tupling is enabled, this
889 /// function:
890 ///
891 ///     fn f(x: (isize, isize))
892 ///
893 /// Can be called as:
894 ///
895 ///     f(1, 2);
896 ///
897 /// Instead of:
898 ///
899 ///     f((1, 2));
900 #[derive(Clone, Eq, PartialEq)]
901 enum TupleArgumentsFlag {
902     DontTupleArguments,
903     TupleArguments,
904 }
905
906 /// A wrapper for `InferCtxt`'s `in_progress_typeck_results` field.
907 #[derive(Copy, Clone)]
908 struct MaybeInProgressTables<'a, 'tcx> {
909     maybe_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
910 }
911
912 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
913     fn borrow(self) -> Ref<'a, ty::TypeckResults<'tcx>> {
914         match self.maybe_typeck_results {
915             Some(typeck_results) => typeck_results.borrow(),
916             None => bug!(
917                 "MaybeInProgressTables: inh/fcx.typeck_results.borrow() with no typeck results"
918             ),
919         }
920     }
921
922     fn borrow_mut(self) -> RefMut<'a, ty::TypeckResults<'tcx>> {
923         match self.maybe_typeck_results {
924             Some(typeck_results) => typeck_results.borrow_mut(),
925             None => bug!(
926                 "MaybeInProgressTables: inh/fcx.typeck_results.borrow_mut() with no typeck results"
927             ),
928         }
929     }
930 }
931
932 struct CheckItemTypesVisitor<'tcx> {
933     tcx: TyCtxt<'tcx>,
934 }
935
936 impl<'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
937     fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
938         check_item_type(self.tcx, i);
939     }
940     fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
941     fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
942     fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
943 }
944
945 fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) {
946     tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id));
947 }
948
949 fn fatally_break_rust(sess: &Session) {
950     let handler = sess.diagnostic();
951     handler.span_bug_no_panic(
952         MultiSpan::new(),
953         "It looks like you're trying to break rust; would you like some ICE?",
954     );
955     handler.note_without_error("the compiler expectedly panicked. this is a feature.");
956     handler.note_without_error(
957         "we would appreciate a joke overview: \
958          https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
959     );
960     handler.note_without_error(&format!(
961         "rustc {} running on {}",
962         option_env!("CFG_VERSION").unwrap_or("unknown_version"),
963         config::host_triple(),
964     ));
965 }
966
967 fn potentially_plural_count(count: usize, word: &str) -> String {
968     format!("{} {}{}", count, word, pluralize!(count))
969 }
970
971 fn has_expected_num_generic_args<'tcx>(
972     tcx: TyCtxt<'tcx>,
973     trait_did: Option<DefId>,
974     expected: usize,
975 ) -> bool {
976     trait_did.map_or(true, |trait_did| {
977         let generics = tcx.generics_of(trait_did);
978         generics.count() == expected + if generics.has_self { 1 } else { 0 }
979     })
980 }