]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/traits/mod.rs
Rollup merge of #98506 - compiler-errors:object-safety-suggestions, r=oli-obk
[rust.git] / compiler / rustc_middle / src / traits / mod.rs
1 //! Trait Resolution. See the [rustc dev guide] for more information on how this works.
2 //!
3 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
4
5 mod chalk;
6 pub mod query;
7 pub mod select;
8 pub mod specialization_graph;
9 mod structural_impls;
10 pub mod util;
11
12 use crate::infer::canonical::Canonical;
13 use crate::thir::abstract_const::NotConstEvaluatable;
14 use crate::ty::subst::SubstsRef;
15 use crate::ty::{self, AdtKind, Ty, TyCtxt};
16
17 use rustc_data_structures::sync::Lrc;
18 use rustc_errors::{Applicability, Diagnostic};
19 use rustc_hir as hir;
20 use rustc_hir::def_id::{DefId, LocalDefId};
21 use rustc_span::symbol::Symbol;
22 use rustc_span::{Span, DUMMY_SP};
23 use smallvec::SmallVec;
24
25 use std::borrow::Cow;
26 use std::hash::{Hash, Hasher};
27
28 pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
29
30 pub type CanonicalChalkEnvironmentAndGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
31
32 pub use self::ObligationCauseCode::*;
33
34 pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner};
35
36 /// Depending on the stage of compilation, we want projection to be
37 /// more or less conservative.
38 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)]
39 pub enum Reveal {
40     /// At type-checking time, we refuse to project any associated
41     /// type that is marked `default`. Non-`default` ("final") types
42     /// are always projected. This is necessary in general for
43     /// soundness of specialization. However, we *could* allow
44     /// projections in fully-monomorphic cases. We choose not to,
45     /// because we prefer for `default type` to force the type
46     /// definition to be treated abstractly by any consumers of the
47     /// impl. Concretely, that means that the following example will
48     /// fail to compile:
49     ///
50     /// ```compile_fail,E0308
51     /// #![feature(specialization)]
52     /// trait Assoc {
53     ///     type Output;
54     /// }
55     ///
56     /// impl<T> Assoc for T {
57     ///     default type Output = bool;
58     /// }
59     ///
60     /// fn main() {
61     ///     let x: <() as Assoc>::Output = true;
62     /// }
63     /// ```
64     ///
65     /// We also do not reveal the hidden type of opaque types during
66     /// type-checking.
67     UserFacing,
68
69     /// At codegen time, all monomorphic projections will succeed.
70     /// Also, `impl Trait` is normalized to the concrete type,
71     /// which has to be already collected by type-checking.
72     ///
73     /// NOTE: as `impl Trait`'s concrete type should *never*
74     /// be observable directly by the user, `Reveal::All`
75     /// should not be used by checks which may expose
76     /// type equality or type contents to the user.
77     /// There are some exceptions, e.g., around auto traits and
78     /// transmute-checking, which expose some details, but
79     /// not the whole concrete type of the `impl Trait`.
80     All,
81 }
82
83 /// The reason why we incurred this obligation; used for error reporting.
84 ///
85 /// Non-misc `ObligationCauseCode`s are stored on the heap. This gives the
86 /// best trade-off between keeping the type small (which makes copies cheaper)
87 /// while not doing too many heap allocations.
88 ///
89 /// We do not want to intern this as there are a lot of obligation causes which
90 /// only live for a short period of time.
91 #[derive(Clone, Debug, PartialEq, Eq, Lift)]
92 pub struct ObligationCause<'tcx> {
93     pub span: Span,
94
95     /// The ID of the fn body that triggered this obligation. This is
96     /// used for region obligations to determine the precise
97     /// environment in which the region obligation should be evaluated
98     /// (in particular, closures can add new assumptions). See the
99     /// field `region_obligations` of the `FulfillmentContext` for more
100     /// information.
101     pub body_id: hir::HirId,
102
103     code: InternedObligationCauseCode<'tcx>,
104 }
105
106 // This custom hash function speeds up hashing for `Obligation` deduplication
107 // greatly by skipping the `code` field, which can be large and complex. That
108 // shouldn't affect hash quality much since there are several other fields in
109 // `Obligation` which should be unique enough, especially the predicate itself
110 // which is hashed as an interned pointer. See #90996.
111 impl Hash for ObligationCause<'_> {
112     fn hash<H: Hasher>(&self, state: &mut H) {
113         self.body_id.hash(state);
114         self.span.hash(state);
115     }
116 }
117
118 impl<'tcx> ObligationCause<'tcx> {
119     #[inline]
120     pub fn new(
121         span: Span,
122         body_id: hir::HirId,
123         code: ObligationCauseCode<'tcx>,
124     ) -> ObligationCause<'tcx> {
125         ObligationCause { span, body_id, code: code.into() }
126     }
127
128     pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> {
129         ObligationCause::new(span, body_id, MiscObligation)
130     }
131
132     #[inline(always)]
133     pub fn dummy() -> ObligationCause<'tcx> {
134         ObligationCause::dummy_with_span(DUMMY_SP)
135     }
136
137     #[inline(always)]
138     pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> {
139         ObligationCause { span, body_id: hir::CRATE_HIR_ID, code: Default::default() }
140     }
141
142     pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span {
143         match *self.code() {
144             ObligationCauseCode::CompareImplMethodObligation { .. }
145             | ObligationCauseCode::MainFunctionType
146             | ObligationCauseCode::StartFunctionType => {
147                 tcx.sess.source_map().guess_head_span(self.span)
148             }
149             ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
150                 arm_span,
151                 ..
152             }) => arm_span,
153             _ => self.span,
154         }
155     }
156
157     #[inline]
158     pub fn code(&self) -> &ObligationCauseCode<'tcx> {
159         &self.code
160     }
161
162     pub fn map_code(
163         &mut self,
164         f: impl FnOnce(InternedObligationCauseCode<'tcx>) -> ObligationCauseCode<'tcx>,
165     ) {
166         self.code = f(std::mem::take(&mut self.code)).into();
167     }
168
169     pub fn derived_cause(
170         mut self,
171         parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
172         variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,
173     ) -> ObligationCause<'tcx> {
174         /*!
175          * Creates a cause for obligations that are derived from
176          * `obligation` by a recursive search (e.g., for a builtin
177          * bound, or eventually a `auto trait Foo`). If `obligation`
178          * is itself a derived obligation, this is just a clone, but
179          * otherwise we create a "derived obligation" cause so as to
180          * keep track of the original root obligation for error
181          * reporting.
182          */
183
184         // NOTE(flaper87): As of now, it keeps track of the whole error
185         // chain. Ideally, we should have a way to configure this either
186         // by using -Z verbose or just a CLI argument.
187         self.code =
188             variant(DerivedObligationCause { parent_trait_pred, parent_code: self.code }).into();
189         self
190     }
191 }
192
193 #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
194 pub struct UnifyReceiverContext<'tcx> {
195     pub assoc_item: ty::AssocItem,
196     pub param_env: ty::ParamEnv<'tcx>,
197     pub substs: SubstsRef<'tcx>,
198 }
199
200 #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, Default)]
201 pub struct InternedObligationCauseCode<'tcx> {
202     /// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of
203     /// the time). `Some` otherwise.
204     code: Option<Lrc<ObligationCauseCode<'tcx>>>,
205 }
206
207 impl<'tcx> ObligationCauseCode<'tcx> {
208     #[inline(always)]
209     fn into(self) -> InternedObligationCauseCode<'tcx> {
210         InternedObligationCauseCode {
211             code: if let ObligationCauseCode::MiscObligation = self {
212                 None
213             } else {
214                 Some(Lrc::new(self))
215             },
216         }
217     }
218 }
219
220 impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> {
221     type Target = ObligationCauseCode<'tcx>;
222
223     fn deref(&self) -> &Self::Target {
224         self.code.as_deref().unwrap_or(&ObligationCauseCode::MiscObligation)
225     }
226 }
227
228 #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
229 pub enum ObligationCauseCode<'tcx> {
230     /// Not well classified or should be obvious from the span.
231     MiscObligation,
232
233     /// A slice or array is WF only if `T: Sized`.
234     SliceOrArrayElem,
235
236     /// A tuple is WF only if its middle elements are `Sized`.
237     TupleElem,
238
239     /// This is the trait reference from the given projection.
240     ProjectionWf(ty::ProjectionTy<'tcx>),
241
242     /// In an impl of trait `X` for type `Y`, type `Y` must
243     /// also implement all supertraits of `X`.
244     ItemObligation(DefId),
245
246     /// Like `ItemObligation`, but with extra detail on the source of the obligation.
247     BindingObligation(DefId, Span),
248
249     /// A type like `&'a T` is WF only if `T: 'a`.
250     ReferenceOutlivesReferent(Ty<'tcx>),
251
252     /// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
253     ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
254
255     /// Obligation incurred due to an object cast.
256     ObjectCastObligation(/* Object type */ Ty<'tcx>),
257
258     /// Obligation incurred due to a coercion.
259     Coercion {
260         source: Ty<'tcx>,
261         target: Ty<'tcx>,
262     },
263
264     /// Various cases where expressions must be `Sized` / `Copy` / etc.
265     /// `L = X` implies that `L` is `Sized`.
266     AssignmentLhsSized,
267     /// `(x1, .., xn)` must be `Sized`.
268     TupleInitializerSized,
269     /// `S { ... }` must be `Sized`.
270     StructInitializerSized,
271     /// Type of each variable must be `Sized`.
272     VariableType(hir::HirId),
273     /// Argument type must be `Sized`.
274     SizedArgumentType(Option<Span>),
275     /// Return type must be `Sized`.
276     SizedReturnType,
277     /// Yield type must be `Sized`.
278     SizedYieldType,
279     /// Box expression result type must be `Sized`.
280     SizedBoxType,
281     /// Inline asm operand type must be `Sized`.
282     InlineAsmSized,
283     /// `[expr; N]` requires `type_of(expr): Copy`.
284     RepeatElementCopy {
285         /// If element is a `const fn` we display a help message suggesting to move the
286         /// function call to a new `const` item while saying that `T` doesn't implement `Copy`.
287         is_const_fn: bool,
288     },
289
290     /// Types of fields (other than the last, except for packed structs) in a struct must be sized.
291     FieldSized {
292         adt_kind: AdtKind,
293         span: Span,
294         last: bool,
295     },
296
297     /// Constant expressions must be sized.
298     ConstSized,
299
300     /// `static` items must have `Sync` type.
301     SharedStatic,
302
303     BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
304
305     ImplDerivedObligation(Box<ImplDerivedObligationCause<'tcx>>),
306
307     DerivedObligation(DerivedObligationCause<'tcx>),
308
309     FunctionArgumentObligation {
310         /// The node of the relevant argument in the function call.
311         arg_hir_id: hir::HirId,
312         /// The node of the function call.
313         call_hir_id: hir::HirId,
314         /// The obligation introduced by this argument.
315         parent_code: InternedObligationCauseCode<'tcx>,
316     },
317
318     /// Error derived when matching traits/impls; see ObligationCause for more details
319     CompareImplConstObligation,
320
321     /// Error derived when matching traits/impls; see ObligationCause for more details
322     CompareImplMethodObligation {
323         impl_item_def_id: LocalDefId,
324         trait_item_def_id: DefId,
325     },
326
327     /// Error derived when matching traits/impls; see ObligationCause for more details
328     CompareImplTypeObligation {
329         impl_item_def_id: LocalDefId,
330         trait_item_def_id: DefId,
331     },
332
333     /// Checking that the bounds of a trait's associated type hold for a given impl
334     CheckAssociatedTypeBounds {
335         impl_item_def_id: LocalDefId,
336         trait_item_def_id: DefId,
337     },
338
339     /// Checking that this expression can be assigned to its target.
340     ExprAssignable,
341
342     /// Computing common supertype in the arms of a match expression
343     MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
344
345     /// Type error arising from type checking a pattern against an expected type.
346     Pattern {
347         /// The span of the scrutinee or type expression which caused the `root_ty` type.
348         span: Option<Span>,
349         /// The root expected type induced by a scrutinee or type expression.
350         root_ty: Ty<'tcx>,
351         /// Whether the `Span` came from an expression or a type expression.
352         origin_expr: bool,
353     },
354
355     /// Constants in patterns must have `Structural` type.
356     ConstPatternStructural,
357
358     /// Computing common supertype in an if expression
359     IfExpression(Box<IfExpressionCause>),
360
361     /// Computing common supertype of an if expression with no else counter-part
362     IfExpressionWithNoElse,
363
364     /// `main` has wrong type
365     MainFunctionType,
366
367     /// `start` has wrong type
368     StartFunctionType,
369
370     /// Intrinsic has wrong type
371     IntrinsicType,
372
373     /// A let else block does not diverge
374     LetElse,
375
376     /// Method receiver
377     MethodReceiver,
378
379     UnifyReceiver(Box<UnifyReceiverContext<'tcx>>),
380
381     /// `return` with no expression
382     ReturnNoExpression,
383
384     /// `return` with an expression
385     ReturnValue(hir::HirId),
386
387     /// Return type of this function
388     ReturnType,
389
390     /// Opaque return type of this function
391     OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
392
393     /// Block implicit return
394     BlockTailExpression(hir::HirId),
395
396     /// #[feature(trivial_bounds)] is not enabled
397     TrivialBound,
398
399     /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
400     OpaqueType,
401
402     AwaitableExpr(Option<hir::HirId>),
403
404     ForLoopIterator,
405
406     QuestionMark,
407
408     /// Well-formed checking. If a `WellFormedLoc` is provided,
409     /// then it will be used to perform HIR-based wf checking
410     /// after an error occurs, in order to generate a more precise error span.
411     /// This is purely for diagnostic purposes - it is always
412     /// correct to use `MiscObligation` instead, or to specify
413     /// `WellFormed(None)`
414     WellFormed(Option<WellFormedLoc>),
415
416     /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against.
417     MatchImpl(ObligationCause<'tcx>, DefId),
418
419     BinOp {
420         rhs_span: Option<Span>,
421         is_lit: bool,
422     },
423 }
424
425 /// The 'location' at which we try to perform HIR-based wf checking.
426 /// This information is used to obtain an `hir::Ty`, which
427 /// we can walk in order to obtain precise spans for any
428 /// 'nested' types (e.g. `Foo` in `Option<Foo>`).
429 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
430 pub enum WellFormedLoc {
431     /// Use the type of the provided definition.
432     Ty(LocalDefId),
433     /// Use the type of the parameter of the provided function.
434     /// We cannot use `hir::Param`, since the function may
435     /// not have a body (e.g. a trait method definition)
436     Param {
437         /// The function to lookup the parameter in
438         function: LocalDefId,
439         /// The index of the parameter to use.
440         /// Parameters are indexed from 0, with the return type
441         /// being the last 'parameter'
442         param_idx: u16,
443     },
444 }
445
446 #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
447 pub struct ImplDerivedObligationCause<'tcx> {
448     pub derived: DerivedObligationCause<'tcx>,
449     pub impl_def_id: DefId,
450     pub span: Span,
451 }
452
453 impl<'tcx> ObligationCauseCode<'tcx> {
454     // Return the base obligation, ignoring derived obligations.
455     pub fn peel_derives(&self) -> &Self {
456         let mut base_cause = self;
457         while let Some((parent_code, _)) = base_cause.parent() {
458             base_cause = parent_code;
459         }
460         base_cause
461     }
462
463     pub fn parent(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
464         match self {
465             FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)),
466             BuiltinDerivedObligation(derived)
467             | DerivedObligation(derived)
468             | ImplDerivedObligation(box ImplDerivedObligationCause { derived, .. }) => {
469                 Some((&derived.parent_code, Some(derived.parent_trait_pred)))
470             }
471             _ => None,
472         }
473     }
474 }
475
476 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
477 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
478 static_assert_size!(ObligationCauseCode<'_>, 48);
479
480 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
481 pub enum StatementAsExpression {
482     CorrectType,
483     NeedsBoxing,
484 }
485
486 impl<'tcx> ty::Lift<'tcx> for StatementAsExpression {
487     type Lifted = StatementAsExpression;
488     fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option<StatementAsExpression> {
489         Some(self)
490     }
491 }
492
493 #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
494 pub struct MatchExpressionArmCause<'tcx> {
495     pub arm_span: Span,
496     pub scrut_span: Span,
497     pub semi_span: Option<(Span, StatementAsExpression)>,
498     pub source: hir::MatchSource,
499     pub prior_arms: Vec<Span>,
500     pub last_ty: Ty<'tcx>,
501     pub scrut_hir_id: hir::HirId,
502     pub opt_suggest_box_span: Option<Span>,
503 }
504
505 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
506 pub struct IfExpressionCause {
507     pub then: Span,
508     pub else_sp: Span,
509     pub outer: Option<Span>,
510     pub semicolon: Option<(Span, StatementAsExpression)>,
511     pub opt_suggest_box_span: Option<Span>,
512 }
513
514 #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
515 pub struct DerivedObligationCause<'tcx> {
516     /// The trait predicate of the parent obligation that led to the
517     /// current obligation. Note that only trait obligations lead to
518     /// derived obligations, so we just store the trait predicate here
519     /// directly.
520     pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
521
522     /// The parent trait had this cause.
523     pub parent_code: InternedObligationCauseCode<'tcx>,
524 }
525
526 #[derive(Clone, Debug, TypeFoldable, Lift)]
527 pub enum SelectionError<'tcx> {
528     /// The trait is not implemented.
529     Unimplemented,
530     /// After a closure impl has selected, its "outputs" were evaluated
531     /// (which for closures includes the "input" type params) and they
532     /// didn't resolve. See `confirm_poly_trait_refs` for more.
533     OutputTypeParameterMismatch(
534         ty::PolyTraitRef<'tcx>,
535         ty::PolyTraitRef<'tcx>,
536         ty::error::TypeError<'tcx>,
537     ),
538     /// The trait pointed by `DefId` is not object safe.
539     TraitNotObjectSafe(DefId),
540     /// A given constant couldn't be evaluated.
541     NotConstEvaluatable(NotConstEvaluatable),
542     /// Exceeded the recursion depth during type projection.
543     Overflow(OverflowError),
544     /// Signaling that an error has already been emitted, to avoid
545     /// multiple errors being shown.
546     ErrorReporting,
547     /// Multiple applicable `impl`s where found. The `DefId`s correspond to
548     /// all the `impl`s' Items.
549     Ambiguous(Vec<DefId>),
550 }
551
552 /// When performing resolution, it is typically the case that there
553 /// can be one of three outcomes:
554 ///
555 /// - `Ok(Some(r))`: success occurred with result `r`
556 /// - `Ok(None)`: could not definitely determine anything, usually due
557 ///   to inconclusive type inference.
558 /// - `Err(e)`: error `e` occurred
559 pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
560
561 /// Given the successful resolution of an obligation, the `ImplSource`
562 /// indicates where the impl comes from.
563 ///
564 /// For example, the obligation may be satisfied by a specific impl (case A),
565 /// or it may be relative to some bound that is in scope (case B).
566 ///
567 /// ```ignore (illustrative)
568 /// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
569 /// impl<T:Clone> Clone<T> for Box<T> { ... }    // Impl_2
570 /// impl Clone for i32 { ... }                   // Impl_3
571 ///
572 /// fn foo<T: Clone>(concrete: Option<Box<i32>>, param: T, mixed: Option<T>) {
573 ///     // Case A: ImplSource points at a specific impl. Only possible when
574 ///     // type is concretely known. If the impl itself has bounded
575 ///     // type parameters, ImplSource will carry resolutions for those as well:
576 ///     concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
577 ///
578 ///     // Case A: ImplSource points at a specific impl. Only possible when
579 ///     // type is concretely known. If the impl itself has bounded
580 ///     // type parameters, ImplSource will carry resolutions for those as well:
581 ///     concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
582 ///
583 ///     // Case B: ImplSource must be provided by caller. This applies when
584 ///     // type is a type parameter.
585 ///     param.clone();    // ImplSource::Param
586 ///
587 ///     // Case C: A mix of cases A and B.
588 ///     mixed.clone();    // ImplSource(Impl_1, [ImplSource::Param])
589 /// }
590 /// ```
591 ///
592 /// ### The type parameter `N`
593 ///
594 /// See explanation on `ImplSourceUserDefinedData`.
595 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
596 pub enum ImplSource<'tcx, N> {
597     /// ImplSource identifying a particular impl.
598     UserDefined(ImplSourceUserDefinedData<'tcx, N>),
599
600     /// ImplSource for auto trait implementations.
601     /// This carries the information and nested obligations with regards
602     /// to an auto implementation for a trait `Trait`. The nested obligations
603     /// ensure the trait implementation holds for all the constituent types.
604     AutoImpl(ImplSourceAutoImplData<N>),
605
606     /// Successful resolution to an obligation provided by the caller
607     /// for some type parameter. The `Vec<N>` represents the
608     /// obligations incurred from normalizing the where-clause (if
609     /// any).
610     Param(Vec<N>, ty::BoundConstness),
611
612     /// Virtual calls through an object.
613     Object(ImplSourceObjectData<'tcx, N>),
614
615     /// Successful resolution for a builtin trait.
616     Builtin(ImplSourceBuiltinData<N>),
617
618     /// ImplSource for trait upcasting coercion
619     TraitUpcasting(ImplSourceTraitUpcastingData<'tcx, N>),
620
621     /// ImplSource automatically generated for a closure. The `DefId` is the ID
622     /// of the closure expression. This is an `ImplSource::UserDefined` in spirit, but the
623     /// impl is generated by the compiler and does not appear in the source.
624     Closure(ImplSourceClosureData<'tcx, N>),
625
626     /// Same as above, but for a function pointer type with the given signature.
627     FnPointer(ImplSourceFnPointerData<'tcx, N>),
628
629     /// ImplSource for a builtin `DeterminantKind` trait implementation.
630     DiscriminantKind(ImplSourceDiscriminantKindData),
631
632     /// ImplSource for a builtin `Pointee` trait implementation.
633     Pointee(ImplSourcePointeeData),
634
635     /// ImplSource automatically generated for a generator.
636     Generator(ImplSourceGeneratorData<'tcx, N>),
637
638     /// ImplSource for a trait alias.
639     TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
640
641     /// ImplSource for a `const Drop` implementation.
642     ConstDestruct(ImplSourceConstDestructData<N>),
643 }
644
645 impl<'tcx, N> ImplSource<'tcx, N> {
646     pub fn nested_obligations(self) -> Vec<N> {
647         match self {
648             ImplSource::UserDefined(i) => i.nested,
649             ImplSource::Param(n, _) => n,
650             ImplSource::Builtin(i) => i.nested,
651             ImplSource::AutoImpl(d) => d.nested,
652             ImplSource::Closure(c) => c.nested,
653             ImplSource::Generator(c) => c.nested,
654             ImplSource::Object(d) => d.nested,
655             ImplSource::FnPointer(d) => d.nested,
656             ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
657             | ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
658             ImplSource::TraitAlias(d) => d.nested,
659             ImplSource::TraitUpcasting(d) => d.nested,
660             ImplSource::ConstDestruct(i) => i.nested,
661         }
662     }
663
664     pub fn borrow_nested_obligations(&self) -> &[N] {
665         match &self {
666             ImplSource::UserDefined(i) => &i.nested[..],
667             ImplSource::Param(n, _) => &n,
668             ImplSource::Builtin(i) => &i.nested,
669             ImplSource::AutoImpl(d) => &d.nested,
670             ImplSource::Closure(c) => &c.nested,
671             ImplSource::Generator(c) => &c.nested,
672             ImplSource::Object(d) => &d.nested,
673             ImplSource::FnPointer(d) => &d.nested,
674             ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
675             | ImplSource::Pointee(ImplSourcePointeeData) => &[],
676             ImplSource::TraitAlias(d) => &d.nested,
677             ImplSource::TraitUpcasting(d) => &d.nested,
678             ImplSource::ConstDestruct(i) => &i.nested,
679         }
680     }
681
682     pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
683     where
684         F: FnMut(N) -> M,
685     {
686         match self {
687             ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData {
688                 impl_def_id: i.impl_def_id,
689                 substs: i.substs,
690                 nested: i.nested.into_iter().map(f).collect(),
691             }),
692             ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
693             ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData {
694                 nested: i.nested.into_iter().map(f).collect(),
695             }),
696             ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
697                 upcast_trait_ref: o.upcast_trait_ref,
698                 vtable_base: o.vtable_base,
699                 nested: o.nested.into_iter().map(f).collect(),
700             }),
701             ImplSource::AutoImpl(d) => ImplSource::AutoImpl(ImplSourceAutoImplData {
702                 trait_def_id: d.trait_def_id,
703                 nested: d.nested.into_iter().map(f).collect(),
704             }),
705             ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData {
706                 closure_def_id: c.closure_def_id,
707                 substs: c.substs,
708                 nested: c.nested.into_iter().map(f).collect(),
709             }),
710             ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData {
711                 generator_def_id: c.generator_def_id,
712                 substs: c.substs,
713                 nested: c.nested.into_iter().map(f).collect(),
714             }),
715             ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData {
716                 fn_ty: p.fn_ty,
717                 nested: p.nested.into_iter().map(f).collect(),
718             }),
719             ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => {
720                 ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
721             }
722             ImplSource::Pointee(ImplSourcePointeeData) => {
723                 ImplSource::Pointee(ImplSourcePointeeData)
724             }
725             ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
726                 alias_def_id: d.alias_def_id,
727                 substs: d.substs,
728                 nested: d.nested.into_iter().map(f).collect(),
729             }),
730             ImplSource::TraitUpcasting(d) => {
731                 ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
732                     upcast_trait_ref: d.upcast_trait_ref,
733                     vtable_vptr_slot: d.vtable_vptr_slot,
734                     nested: d.nested.into_iter().map(f).collect(),
735                 })
736             }
737             ImplSource::ConstDestruct(i) => {
738                 ImplSource::ConstDestruct(ImplSourceConstDestructData {
739                     nested: i.nested.into_iter().map(f).collect(),
740                 })
741             }
742         }
743     }
744 }
745
746 /// Identifies a particular impl in the source, along with a set of
747 /// substitutions from the impl's type/lifetime parameters. The
748 /// `nested` vector corresponds to the nested obligations attached to
749 /// the impl's type parameters.
750 ///
751 /// The type parameter `N` indicates the type used for "nested
752 /// obligations" that are required by the impl. During type-check, this
753 /// is `Obligation`, as one might expect. During codegen, however, this
754 /// is `()`, because codegen only requires a shallow resolution of an
755 /// impl, and nested obligations are satisfied later.
756 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
757 pub struct ImplSourceUserDefinedData<'tcx, N> {
758     pub impl_def_id: DefId,
759     pub substs: SubstsRef<'tcx>,
760     pub nested: Vec<N>,
761 }
762
763 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
764 pub struct ImplSourceGeneratorData<'tcx, N> {
765     pub generator_def_id: DefId,
766     pub substs: SubstsRef<'tcx>,
767     /// Nested obligations. This can be non-empty if the generator
768     /// signature contains associated types.
769     pub nested: Vec<N>,
770 }
771
772 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
773 pub struct ImplSourceClosureData<'tcx, N> {
774     pub closure_def_id: DefId,
775     pub substs: SubstsRef<'tcx>,
776     /// Nested obligations. This can be non-empty if the closure
777     /// signature contains associated types.
778     pub nested: Vec<N>,
779 }
780
781 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
782 pub struct ImplSourceAutoImplData<N> {
783     pub trait_def_id: DefId,
784     pub nested: Vec<N>,
785 }
786
787 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
788 pub struct ImplSourceTraitUpcastingData<'tcx, N> {
789     /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
790     pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
791
792     /// The vtable is formed by concatenating together the method lists of
793     /// the base object trait and all supertraits, pointers to supertrait vtable will
794     /// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
795     /// within that vtable.
796     pub vtable_vptr_slot: Option<usize>,
797
798     pub nested: Vec<N>,
799 }
800
801 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
802 pub struct ImplSourceBuiltinData<N> {
803     pub nested: Vec<N>,
804 }
805
806 #[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
807 pub struct ImplSourceObjectData<'tcx, N> {
808     /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
809     pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
810
811     /// The vtable is formed by concatenating together the method lists of
812     /// the base object trait and all supertraits, pointers to supertrait vtable will
813     /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
814     /// in that vtable.
815     pub vtable_base: usize,
816
817     pub nested: Vec<N>,
818 }
819
820 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
821 pub struct ImplSourceFnPointerData<'tcx, N> {
822     pub fn_ty: Ty<'tcx>,
823     pub nested: Vec<N>,
824 }
825
826 // FIXME(@lcnr): This should be  refactored and merged with other builtin vtables.
827 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
828 pub struct ImplSourceDiscriminantKindData;
829
830 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
831 pub struct ImplSourcePointeeData;
832
833 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
834 pub struct ImplSourceConstDestructData<N> {
835     pub nested: Vec<N>,
836 }
837
838 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
839 pub struct ImplSourceTraitAliasData<'tcx, N> {
840     pub alias_def_id: DefId,
841     pub substs: SubstsRef<'tcx>,
842     pub nested: Vec<N>,
843 }
844
845 #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
846 pub enum ObjectSafetyViolation {
847     /// `Self: Sized` declared on the trait.
848     SizedSelf(SmallVec<[Span; 1]>),
849
850     /// Supertrait reference references `Self` an in illegal location
851     /// (e.g., `trait Foo : Bar<Self>`).
852     SupertraitSelf(SmallVec<[Span; 1]>),
853
854     /// Method has something illegal.
855     Method(Symbol, MethodViolationCode, Span),
856
857     /// Associated const.
858     AssocConst(Symbol, Span),
859
860     /// GAT
861     GAT(Symbol, Span),
862 }
863
864 impl ObjectSafetyViolation {
865     pub fn error_msg(&self) -> Cow<'static, str> {
866         match self {
867             ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
868             ObjectSafetyViolation::SupertraitSelf(ref spans) => {
869                 if spans.iter().any(|sp| *sp != DUMMY_SP) {
870                     "it uses `Self` as a type parameter".into()
871                 } else {
872                     "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
873                         .into()
874                 }
875             }
876             ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
877                 format!("associated function `{}` has no `self` parameter", name).into()
878             }
879             ObjectSafetyViolation::Method(
880                 name,
881                 MethodViolationCode::ReferencesSelfInput(_),
882                 DUMMY_SP,
883             ) => format!("method `{}` references the `Self` type in its parameters", name).into(),
884             ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfInput(_), _) => {
885                 format!("method `{}` references the `Self` type in this parameter", name).into()
886             }
887             ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => {
888                 format!("method `{}` references the `Self` type in its return type", name).into()
889             }
890             ObjectSafetyViolation::Method(
891                 name,
892                 MethodViolationCode::WhereClauseReferencesSelf,
893                 _,
894             ) => {
895                 format!("method `{}` references the `Self` type in its `where` clause", name).into()
896             }
897             ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => {
898                 format!("method `{}` has generic type parameters", name).into()
899             }
900             ObjectSafetyViolation::Method(
901                 name,
902                 MethodViolationCode::UndispatchableReceiver(_),
903                 _,
904             ) => format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
905             ObjectSafetyViolation::AssocConst(name, DUMMY_SP) => {
906                 format!("it contains associated `const` `{}`", name).into()
907             }
908             ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(),
909             ObjectSafetyViolation::GAT(name, _) => {
910                 format!("it contains the generic associated type `{}`", name).into()
911             }
912         }
913     }
914
915     pub fn solution(&self, err: &mut Diagnostic) {
916         match self {
917             ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {}
918             ObjectSafetyViolation::Method(
919                 name,
920                 MethodViolationCode::StaticMethod(Some((add_self_sugg, make_sized_sugg))),
921                 _,
922             ) => {
923                 err.span_suggestion(
924                     add_self_sugg.1,
925                     format!(
926                         "consider turning `{}` into a method by giving it a `&self` argument",
927                         name
928                     ),
929                     add_self_sugg.0.to_string(),
930                     Applicability::MaybeIncorrect,
931                 );
932                 err.span_suggestion(
933                     make_sized_sugg.1,
934                     format!(
935                         "alternatively, consider constraining `{}` so it does not apply to \
936                              trait objects",
937                         name
938                     ),
939                     make_sized_sugg.0.to_string(),
940                     Applicability::MaybeIncorrect,
941                 );
942             }
943             ObjectSafetyViolation::Method(
944                 name,
945                 MethodViolationCode::UndispatchableReceiver(Some(span)),
946                 _,
947             ) => {
948                 err.span_suggestion(
949                     *span,
950                     &format!(
951                         "consider changing method `{}`'s `self` parameter to be `&self`",
952                         name
953                     ),
954                     "&Self",
955                     Applicability::MachineApplicable,
956                 );
957             }
958             ObjectSafetyViolation::AssocConst(name, _)
959             | ObjectSafetyViolation::GAT(name, _)
960             | ObjectSafetyViolation::Method(name, ..) => {
961                 err.help(&format!("consider moving `{}` to another trait", name));
962             }
963         }
964     }
965
966     pub fn spans(&self) -> SmallVec<[Span; 1]> {
967         // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
968         // diagnostics use a `note` instead of a `span_label`.
969         match self {
970             ObjectSafetyViolation::SupertraitSelf(spans)
971             | ObjectSafetyViolation::SizedSelf(spans) => spans.clone(),
972             ObjectSafetyViolation::AssocConst(_, span)
973             | ObjectSafetyViolation::GAT(_, span)
974             | ObjectSafetyViolation::Method(_, _, span)
975                 if *span != DUMMY_SP =>
976             {
977                 smallvec![*span]
978             }
979             _ => smallvec![],
980         }
981     }
982 }
983
984 /// Reasons a method might not be object-safe.
985 #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
986 pub enum MethodViolationCode {
987     /// e.g., `fn foo()`
988     StaticMethod(Option<(/* add &self */ (String, Span), /* add Self: Sized */ (String, Span))>),
989
990     /// e.g., `fn foo(&self, x: Self)`
991     ReferencesSelfInput(Option<Span>),
992
993     /// e.g., `fn foo(&self) -> Self`
994     ReferencesSelfOutput,
995
996     /// e.g., `fn foo(&self) where Self: Clone`
997     WhereClauseReferencesSelf,
998
999     /// e.g., `fn foo<A>()`
1000     Generic,
1001
1002     /// the method's receiver (`self` argument) can't be dispatched on
1003     UndispatchableReceiver(Option<Span>),
1004 }
1005
1006 /// These are the error cases for `codegen_fulfill_obligation`.
1007 #[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
1008 pub enum CodegenObligationError {
1009     /// Ambiguity can happen when monomorphizing during trans
1010     /// expands to some humongous type that never occurred
1011     /// statically -- this humongous type can then overflow,
1012     /// leading to an ambiguous result. So report this as an
1013     /// overflow bug, since I believe this is the only case
1014     /// where ambiguity can result.
1015     Ambiguity,
1016     /// This can trigger when we probe for the source of a `'static` lifetime requirement
1017     /// on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
1018     /// This can also trigger when we have a global bound that is not actually satisfied,
1019     /// but was included during typeck due to the trivial_bounds feature.
1020     Unimplemented,
1021     FulfillmentError,
1022 }