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