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