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