]>
Commit | Line | Data |
---|---|---|
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 | 5 | pub mod query; |
74b04a01 | 6 | pub mod select; |
9ffffee4 | 7 | pub mod solve; |
74b04a01 | 8 | pub mod specialization_graph; |
0731742a | 9 | mod structural_impls; |
3c0e092e | 10 | pub mod util; |
1a4d82fc | 11 | |
f9f354fc | 12 | use crate::infer::canonical::Canonical; |
f2b60f7d | 13 | use crate::mir::ConstraintCategory; |
064997fb | 14 | use crate::ty::abstract_const::NotConstEvaluatable; |
add651ee | 15 | use crate::ty::GenericArgsRef; |
781aab86 | 16 | use crate::ty::{self, AdtKind, Ty}; |
74b04a01 | 17 | |
136023e0 | 18 | use rustc_data_structures::sync::Lrc; |
5e7ed085 | 19 | use rustc_errors::{Applicability, Diagnostic}; |
dfeec247 | 20 | use rustc_hir as hir; |
9ffffee4 FG |
21 | use rustc_hir::def_id::DefId; |
22 | use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; | |
f9f354fc | 23 | use rustc_span::symbol::Symbol; |
dfeec247 | 24 | use rustc_span::{Span, DUMMY_SP}; |
74b04a01 | 25 | use smallvec::SmallVec; |
e9174d1e | 26 | |
74b04a01 | 27 | use std::borrow::Cow; |
3c0e092e | 28 | use std::hash::{Hash, Hasher}; |
1a4d82fc | 29 | |
74b04a01 | 30 | pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; |
0731742a | 31 | |
dfeec247 | 32 | pub 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 |
37 | pub 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 | 91 | pub 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. | |
110 | impl 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 |
117 | impl<'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 |
199 | pub 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 |
207 | pub 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 |
213 | impl<'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 |
220 | impl<'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 | ||
233 | impl<'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 | 243 | pub 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 |
464 | pub 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 |
482 | pub 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 | 494 | impl<'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 | 526 | static_assert_size!(ObligationCauseCode<'_>, 48); |
e1599b0c | 527 | |
29967ef6 XL |
528 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
529 | pub enum StatementAsExpression { | |
530 | CorrectType, | |
531 | NeedsBoxing, | |
532 | } | |
533 | ||
781aab86 | 534 | #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] |
9ffffee4 | 535 | #[derive(TypeVisitable, TypeFoldable)] |
e1599b0c | 536 | pub 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 |
551 | pub 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 | 562 | pub 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 | 574 | pub 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 |
597 | pub 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 | |
610 | pub 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 |
643 | pub 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 | 657 | impl<'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 | 709 | pub 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)] |
716 | pub 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 | 739 | TrivialTypeTraversalImpls! { BuiltinImplSource } |
a7813a04 | 740 | |
c295e0f8 | 741 | #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] |
74b04a01 XL |
742 | pub 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 |
763 | impl 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 |
894 | pub 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)] |
922 | pub 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 |
939 | pub 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 | } |