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