1pub mod query;
6pub mod select;
7pub mod solve;
8pub mod specialization_graph;
9mod structural_impls;
10
11use std::borrow::Cow;
12use std::hash::{Hash, Hasher};
13use std::sync::Arc;
14
15use rustc_errors::{Applicability, Diag, EmissionGuarantee, ErrorGuaranteed};
16use rustc_hir as hir;
17use rustc_hir::HirId;
18use rustc_hir::def_id::DefId;
19use rustc_macros::{
20    Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
21};
22use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId};
23use rustc_span::{DUMMY_SP, Span, Symbol};
24use smallvec::{SmallVec, smallvec};
25use thin_vec::ThinVec;
26
27pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
28use crate::mir::ConstraintCategory;
29pub use crate::traits::solve::BuiltinImplSource;
30use crate::ty::abstract_const::NotConstEvaluatable;
31use crate::ty::{self, AdtKind, GenericArgsRef, Ty};
32
33#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
42#[derive(TypeVisitable, TypeFoldable)]
43pub struct ObligationCause<'tcx> {
44    pub span: Span,
45
46    pub body_id: LocalDefId,
53
54    code: ObligationCauseCodeHandle<'tcx>,
55}
56
57impl Hash for ObligationCause<'_> {
63    fn hash<H: Hasher>(&self, state: &mut H) {
64        self.body_id.hash(state);
65        self.span.hash(state);
66    }
67}
68
69impl<'tcx> ObligationCause<'tcx> {
70    #[inline]
71    pub fn new(
72        span: Span,
73        body_id: LocalDefId,
74        code: ObligationCauseCode<'tcx>,
75    ) -> ObligationCause<'tcx> {
76        ObligationCause { span, body_id, code: code.into() }
77    }
78
79    pub fn misc(span: Span, body_id: LocalDefId) -> ObligationCause<'tcx> {
80        ObligationCause::new(span, body_id, ObligationCauseCode::Misc)
81    }
82
83    #[inline(always)]
84    pub fn dummy() -> ObligationCause<'tcx> {
85        ObligationCause::dummy_with_span(DUMMY_SP)
86    }
87
88    #[inline(always)]
89    pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> {
90        ObligationCause { span, body_id: CRATE_DEF_ID, code: Default::default() }
91    }
92
93    #[inline]
94    pub fn code(&self) -> &ObligationCauseCode<'tcx> {
95        &self.code
96    }
97
98    pub fn map_code(
99        &mut self,
100        f: impl FnOnce(ObligationCauseCodeHandle<'tcx>) -> ObligationCauseCode<'tcx>,
101    ) {
102        self.code = f(std::mem::take(&mut self.code)).into();
103    }
104
105    pub fn derived_cause(
106        mut self,
107        parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
108        variant: impl FnOnce(DerivedCause<'tcx>) -> ObligationCauseCode<'tcx>,
109    ) -> ObligationCause<'tcx> {
110        self.code = variant(DerivedCause { parent_trait_pred, parent_code: self.code }).into();
124        self
125    }
126
127    pub fn derived_host_cause(
128        mut self,
129        parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
130        variant: impl FnOnce(DerivedHostCause<'tcx>) -> ObligationCauseCode<'tcx>,
131    ) -> ObligationCause<'tcx> {
132        self.code = variant(DerivedHostCause { parent_host_pred, parent_code: self.code }).into();
133        self
134    }
135
136    pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
137        match self.code() {
138            ObligationCauseCode::MatchImpl(cause, _) => cause.to_constraint_category(),
139            ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span) => {
140                ConstraintCategory::Predicate(*predicate_span)
141            }
142            _ => ConstraintCategory::BoringNoLocation,
143        }
144    }
145}
146
147#[derive(Clone, PartialEq, Eq, Default, HashStable)]
149#[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
150pub struct ObligationCauseCodeHandle<'tcx> {
151    code: Option<Arc<ObligationCauseCode<'tcx>>>,
154}
155
156impl<'tcx> std::fmt::Debug for ObligationCauseCodeHandle<'tcx> {
157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158        let cause: &ObligationCauseCode<'_> = self;
159        cause.fmt(f)
160    }
161}
162
163impl<'tcx> ObligationCauseCode<'tcx> {
164    #[inline(always)]
165    fn into(self) -> ObligationCauseCodeHandle<'tcx> {
166        ObligationCauseCodeHandle {
167            code: if let ObligationCauseCode::Misc = self { None } else { Some(Arc::new(self)) },
168        }
169    }
170}
171
172impl<'tcx> std::ops::Deref for ObligationCauseCodeHandle<'tcx> {
173    type Target = ObligationCauseCode<'tcx>;
174
175    fn deref(&self) -> &Self::Target {
176        self.code.as_deref().unwrap_or(&ObligationCauseCode::Misc)
177    }
178}
179
180#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
181#[derive(TypeVisitable, TypeFoldable)]
182pub enum ObligationCauseCode<'tcx> {
183    Misc,
185
186    SliceOrArrayElem,
188
189    ArrayLen(Ty<'tcx>),
191
192    TupleElem,
194
195    WhereClause(DefId, Span),
198
199    OpaqueTypeBound(Span, Option<LocalDefId>),
203
204    WhereClauseInExpr(DefId, Span, HirId, usize),
209
210    HostEffectInExpr(DefId, Span, HirId, usize),
213
214    ReferenceOutlivesReferent(Ty<'tcx>),
216
217    ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
219
220    Coercion {
222        source: Ty<'tcx>,
223        target: Ty<'tcx>,
224    },
225
226    AssignmentLhsSized,
229    TupleInitializerSized,
231    StructInitializerSized,
233    VariableType(HirId),
235    SizedArgumentType(Option<HirId>),
237    SizedReturnType,
239    SizedCallReturnType,
241    SizedYieldType,
243    InlineAsmSized,
245    SizedClosureCapture(LocalDefId),
247    SizedCoroutineInterior(LocalDefId),
249    RepeatElementCopy {
251        is_constable: IsConstable,
254
255        elt_span: Span,
259    },
260
261    FieldSized {
263        adt_kind: AdtKind,
264        span: Span,
265        last: bool,
266    },
267
268    SizedConstOrStatic,
270
271    SharedStatic,
273
274    BuiltinDerived(DerivedCause<'tcx>),
277
278    ImplDerived(Box<ImplDerivedCause<'tcx>>),
281
282    WellFormedDerived(DerivedCause<'tcx>),
284
285    ImplDerivedHost(Box<ImplDerivedHostCause<'tcx>>),
288
289    BuiltinDerivedHost(DerivedHostCause<'tcx>),
292
293    FunctionArg {
296        arg_hir_id: HirId,
298        call_hir_id: HirId,
300        parent_code: ObligationCauseCodeHandle<'tcx>,
302    },
303
304    CompareImplItem {
307        impl_item_def_id: LocalDefId,
308        trait_item_def_id: DefId,
309        kind: ty::AssocKind,
310    },
311
312    CheckAssociatedTypeBounds {
314        impl_item_def_id: LocalDefId,
315        trait_item_def_id: DefId,
316    },
317
318    ExprAssignable,
320
321    MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
323
324    Pattern {
326        span: Option<Span>,
328        root_ty: Ty<'tcx>,
330        origin_expr: Option<PatternOriginExpr>,
332    },
333
334    IfExpression {
336        expr_id: HirId,
337        tail_defines_return_position_impl_trait: Option<LocalDefId>,
339    },
340
341    IfExpressionWithNoElse,
343
344    MainFunctionType,
346
347    LangFunctionType(Symbol),
349
350    IntrinsicType,
352
353    LetElse,
355
356    MethodReceiver,
358
359    ReturnNoExpression,
361
362    ReturnValue(HirId),
364
365    OpaqueReturnType(Option<(Ty<'tcx>, HirId)>),
367
368    BlockTailExpression(HirId, hir::MatchSource),
370
371    TrivialBound,
373
374    AwaitableExpr(HirId),
375
376    ForLoopIterator,
377
378    QuestionMark,
379
380    WellFormed(Option<WellFormedLoc>),
387
388    MatchImpl(ObligationCause<'tcx>, DefId),
391
392    UnOp {
393        hir_id: HirId,
394    },
395
396    BinOp {
397        lhs_hir_id: HirId,
398        rhs_hir_id: HirId,
399        rhs_span: Span,
400        rhs_is_lit: bool,
401        output_ty: Option<Ty<'tcx>>,
402    },
403
404    AscribeUserTypeProvePredicate(Span),
405
406    RustCall,
407
408    DynCompatible(Span),
409
410    AlwaysApplicableImpl,
413
414    ConstParam(Ty<'tcx>),
416
417    TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId),
419
420    UnsizedNonPlaceExpr(Span),
423}
424
425#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
428pub enum IsConstable {
429    No,
430    Fn,
432    Ctor,
434}
435
436#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)]
441#[derive(TypeVisitable, TypeFoldable)]
442pub enum WellFormedLoc {
443    Ty(LocalDefId),
445    Param {
449        function: LocalDefId,
451        param_idx: usize,
455    },
456}
457
458impl<'tcx> ObligationCauseCode<'tcx> {
459    pub fn peel_derives(&self) -> &Self {
461        let mut base_cause = self;
462        while let Some(parent_code) = base_cause.parent() {
463            base_cause = parent_code;
464        }
465        base_cause
466    }
467
468    pub fn parent(&self) -> Option<&Self> {
469        match self {
470            ObligationCauseCode::FunctionArg { parent_code, .. } => Some(parent_code),
471            ObligationCauseCode::BuiltinDerived(derived)
472            | ObligationCauseCode::WellFormedDerived(derived)
473            | ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
474                Some(&derived.parent_code)
475            }
476            ObligationCauseCode::BuiltinDerivedHost(derived)
477            | ObligationCauseCode::ImplDerivedHost(box ImplDerivedHostCause { derived, .. }) => {
478                Some(&derived.parent_code)
479            }
480            _ => None,
481        }
482    }
483
484    pub fn peel_derives_with_predicate(&self) -> (&Self, Option<ty::PolyTraitPredicate<'tcx>>) {
487        let mut base_cause = self;
488        let mut base_trait_pred = None;
489        while let Some((parent_code, parent_pred)) = base_cause.parent_with_predicate() {
490            base_cause = parent_code;
491            if let Some(parent_pred) = parent_pred {
492                base_trait_pred = Some(parent_pred);
493            }
494        }
495
496        (base_cause, base_trait_pred)
497    }
498
499    pub fn parent_with_predicate(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
500        match self {
501            ObligationCauseCode::FunctionArg { parent_code, .. } => Some((parent_code, None)),
502            ObligationCauseCode::BuiltinDerived(derived)
503            | ObligationCauseCode::WellFormedDerived(derived)
504            | ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
505                Some((&derived.parent_code, Some(derived.parent_trait_pred)))
506            }
507            _ => None,
508        }
509    }
510
511    pub fn peel_match_impls(&self) -> &Self {
512        match self {
513            ObligationCauseCode::MatchImpl(cause, _) => cause.code(),
514            _ => self,
515        }
516    }
517}
518
519#[cfg(target_pointer_width = "64")]
521rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
522
523#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
524#[derive(TypeVisitable, TypeFoldable)]
525pub struct MatchExpressionArmCause<'tcx> {
526    pub arm_block_id: Option<HirId>,
527    pub arm_ty: Ty<'tcx>,
528    pub arm_span: Span,
529    pub prior_arm_block_id: Option<HirId>,
530    pub prior_arm_ty: Ty<'tcx>,
531    pub prior_arm_span: Span,
532    pub scrut_span: Span,
534    pub source: hir::MatchSource,
536    pub expr_span: Span,
538    pub prior_non_diverging_arms: Vec<Span>,
542    pub tail_defines_return_position_impl_trait: Option<LocalDefId>,
544}
545
546#[derive(Copy, Clone, Debug, PartialEq, Eq)]
550#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
551pub struct PatternOriginExpr {
552    pub peeled_span: Span,
558    pub peeled_count: usize,
560    pub peeled_prefix_suggestion_parentheses: bool,
563}
564
565#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
566#[derive(TypeVisitable, TypeFoldable)]
567pub struct DerivedCause<'tcx> {
568    pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
573
574    pub parent_code: ObligationCauseCodeHandle<'tcx>,
576}
577
578#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
579#[derive(TypeVisitable, TypeFoldable)]
580pub struct ImplDerivedCause<'tcx> {
581    pub derived: DerivedCause<'tcx>,
582    pub impl_or_alias_def_id: DefId,
587    pub impl_def_predicate_index: Option<usize>,
589    pub span: Span,
590}
591
592#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
593#[derive(TypeVisitable, TypeFoldable)]
594pub struct DerivedHostCause<'tcx> {
595    pub parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
600
601    pub parent_code: ObligationCauseCodeHandle<'tcx>,
603}
604
605#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
606#[derive(TypeVisitable, TypeFoldable)]
607pub struct ImplDerivedHostCause<'tcx> {
608    pub derived: DerivedHostCause<'tcx>,
609    pub impl_def_id: DefId,
611    pub span: Span,
612}
613
614#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
615pub enum SelectionError<'tcx> {
616    Unimplemented,
618    SignatureMismatch(Box<SignatureMismatchData<'tcx>>),
622    TraitDynIncompatible(DefId),
624    NotConstEvaluatable(NotConstEvaluatable),
626    Overflow(OverflowError),
628    OpaqueTypeAutoTraitLeakageUnknown(DefId),
632    ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
634}
635
636#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
637pub struct SignatureMismatchData<'tcx> {
638    pub found_trait_ref: ty::TraitRef<'tcx>,
639    pub expected_trait_ref: ty::TraitRef<'tcx>,
640    pub terr: ty::error::TypeError<'tcx>,
641}
642
643pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
651
652#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
682#[derive(TypeFoldable, TypeVisitable)]
683pub enum ImplSource<'tcx, N> {
684    UserDefined(ImplSourceUserDefinedData<'tcx, N>),
686
687    Param(ThinVec<N>),
692
693    Builtin(BuiltinImplSource, ThinVec<N>),
695}
696
697impl<'tcx, N> ImplSource<'tcx, N> {
698    pub fn nested_obligations(self) -> ThinVec<N> {
699        match self {
700            ImplSource::UserDefined(i) => i.nested,
701            ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
702        }
703    }
704
705    pub fn borrow_nested_obligations(&self) -> &[N] {
706        match self {
707            ImplSource::UserDefined(i) => &i.nested,
708            ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
709        }
710    }
711
712    pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
713        match self {
714            ImplSource::UserDefined(i) => &mut i.nested,
715            ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
716        }
717    }
718
719    pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
720    where
721        F: FnMut(N) -> M,
722    {
723        match self {
724            ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData {
725                impl_def_id: i.impl_def_id,
726                args: i.args,
727                nested: i.nested.into_iter().map(f).collect(),
728            }),
729            ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()),
730            ImplSource::Builtin(source, n) => {
731                ImplSource::Builtin(source, n.into_iter().map(f).collect())
732            }
733        }
734    }
735}
736
737#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
748#[derive(TypeFoldable, TypeVisitable)]
749pub struct ImplSourceUserDefinedData<'tcx, N> {
750    pub impl_def_id: DefId,
751    pub args: GenericArgsRef<'tcx>,
752    pub nested: ThinVec<N>,
753}
754
755#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
756pub enum DynCompatibilityViolation {
757    SizedSelf(SmallVec<[Span; 1]>),
759
760    SupertraitSelf(SmallVec<[Span; 1]>),
763
764    SupertraitNonLifetimeBinder(SmallVec<[Span; 1]>),
766
767    SupertraitConst(SmallVec<[Span; 1]>),
769
770    Method(Symbol, MethodViolationCode, Span),
772
773    AssocConst(Symbol, Span),
775
776    GAT(Symbol, Span),
778}
779
780impl DynCompatibilityViolation {
781    pub fn error_msg(&self) -> Cow<'static, str> {
782        match self {
783            DynCompatibilityViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
784            DynCompatibilityViolation::SupertraitSelf(spans) => {
785                if spans.iter().any(|sp| *sp != DUMMY_SP) {
786                    "it uses `Self` as a type parameter".into()
787                } else {
788                    "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
789                        .into()
790                }
791            }
792            DynCompatibilityViolation::SupertraitNonLifetimeBinder(_) => {
793                "where clause cannot reference non-lifetime `for<...>` variables".into()
794            }
795            DynCompatibilityViolation::SupertraitConst(_) => {
796                "it cannot have a `const` supertrait".into()
797            }
798            DynCompatibilityViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
799                format!("associated function `{name}` has no `self` parameter").into()
800            }
801            DynCompatibilityViolation::Method(
802                name,
803                MethodViolationCode::ReferencesSelfInput(_),
804                DUMMY_SP,
805            ) => format!("method `{name}` references the `Self` type in its parameters").into(),
806            DynCompatibilityViolation::Method(
807                name,
808                MethodViolationCode::ReferencesSelfInput(_),
809                _,
810            ) => format!("method `{name}` references the `Self` type in this parameter").into(),
811            DynCompatibilityViolation::Method(
812                name,
813                MethodViolationCode::ReferencesSelfOutput,
814                _,
815            ) => format!("method `{name}` references the `Self` type in its return type").into(),
816            DynCompatibilityViolation::Method(
817                name,
818                MethodViolationCode::ReferencesImplTraitInTrait(_),
819                _,
820            ) => {
821                format!("method `{name}` references an `impl Trait` type in its return type").into()
822            }
823            DynCompatibilityViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
824                format!("method `{name}` is `async`").into()
825            }
826            DynCompatibilityViolation::Method(name, MethodViolationCode::CVariadic, _) => {
827                format!("method `{name}` is C-variadic").into()
828            }
829            DynCompatibilityViolation::Method(
830                name,
831                MethodViolationCode::WhereClauseReferencesSelf,
832                _,
833            ) => format!("method `{name}` references the `Self` type in its `where` clause").into(),
834            DynCompatibilityViolation::Method(name, MethodViolationCode::Generic, _) => {
835                format!("method `{name}` has generic type parameters").into()
836            }
837            DynCompatibilityViolation::Method(
838                name,
839                MethodViolationCode::UndispatchableReceiver(_),
840                _,
841            ) => format!("method `{name}`'s `self` parameter cannot be dispatched on").into(),
842            DynCompatibilityViolation::AssocConst(name, DUMMY_SP) => {
843                format!("it contains associated `const` `{name}`").into()
844            }
845            DynCompatibilityViolation::AssocConst(..) => {
846                "it contains this associated `const`".into()
847            }
848            DynCompatibilityViolation::GAT(name, _) => {
849                format!("it contains the generic associated type `{name}`").into()
850            }
851        }
852    }
853
854    pub fn solution(&self) -> DynCompatibilityViolationSolution {
855        match self {
856            DynCompatibilityViolation::SizedSelf(_)
857            | DynCompatibilityViolation::SupertraitSelf(_)
858            | DynCompatibilityViolation::SupertraitNonLifetimeBinder(..)
859            | DynCompatibilityViolation::SupertraitConst(_) => {
860                DynCompatibilityViolationSolution::None
861            }
862            DynCompatibilityViolation::Method(
863                name,
864                MethodViolationCode::StaticMethod(Some((add_self_sugg, make_sized_sugg))),
865                _,
866            ) => DynCompatibilityViolationSolution::AddSelfOrMakeSized {
867                name: *name,
868                add_self_sugg: add_self_sugg.clone(),
869                make_sized_sugg: make_sized_sugg.clone(),
870            },
871            DynCompatibilityViolation::Method(
872                name,
873                MethodViolationCode::UndispatchableReceiver(Some(span)),
874                _,
875            ) => DynCompatibilityViolationSolution::ChangeToRefSelf(*name, *span),
876            DynCompatibilityViolation::AssocConst(name, _)
877            | DynCompatibilityViolation::GAT(name, _)
878            | DynCompatibilityViolation::Method(name, ..) => {
879                DynCompatibilityViolationSolution::MoveToAnotherTrait(*name)
880            }
881        }
882    }
883
884    pub fn spans(&self) -> SmallVec<[Span; 1]> {
885        match self {
888            DynCompatibilityViolation::SupertraitSelf(spans)
889            | DynCompatibilityViolation::SizedSelf(spans)
890            | DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans)
891            | DynCompatibilityViolation::SupertraitConst(spans) => spans.clone(),
892            DynCompatibilityViolation::AssocConst(_, span)
893            | DynCompatibilityViolation::GAT(_, span)
894            | DynCompatibilityViolation::Method(_, _, span) => {
895                if *span != DUMMY_SP {
896                    smallvec![*span]
897                } else {
898                    smallvec![]
899                }
900            }
901        }
902    }
903}
904
905#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
906pub enum DynCompatibilityViolationSolution {
907    None,
908    AddSelfOrMakeSized {
909        name: Symbol,
910        add_self_sugg: (String, Span),
911        make_sized_sugg: (String, Span),
912    },
913    ChangeToRefSelf(Symbol, Span),
914    MoveToAnotherTrait(Symbol),
915}
916
917impl DynCompatibilityViolationSolution {
918    pub fn add_to<G: EmissionGuarantee>(self, err: &mut Diag<'_, G>) {
919        match self {
920            DynCompatibilityViolationSolution::None => {}
921            DynCompatibilityViolationSolution::AddSelfOrMakeSized {
922                name,
923                add_self_sugg,
924                make_sized_sugg,
925            } => {
926                err.span_suggestion(
927                    add_self_sugg.1,
928                    format!(
929                        "consider turning `{name}` into a method by giving it a `&self` argument"
930                    ),
931                    add_self_sugg.0,
932                    Applicability::MaybeIncorrect,
933                );
934                err.span_suggestion(
935                    make_sized_sugg.1,
936                    format!(
937                        "alternatively, consider constraining `{name}` so it does not apply to \
938                             trait objects"
939                    ),
940                    make_sized_sugg.0,
941                    Applicability::MaybeIncorrect,
942                );
943            }
944            DynCompatibilityViolationSolution::ChangeToRefSelf(name, span) => {
945                err.span_suggestion(
946                    span,
947                    format!("consider changing method `{name}`'s `self` parameter to be `&self`"),
948                    "&Self",
949                    Applicability::MachineApplicable,
950                );
951            }
952            DynCompatibilityViolationSolution::MoveToAnotherTrait(name) => {
953                err.help(format!("consider moving `{name}` to another trait"));
954            }
955        }
956    }
957}
958
959#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
961pub enum MethodViolationCode {
962    StaticMethod(Option<((String, Span), (String, Span))>),
964
965    ReferencesSelfInput(Option<Span>),
967
968    ReferencesSelfOutput,
970
971    ReferencesImplTraitInTrait(Span),
973
974    AsyncFn,
976
977    WhereClauseReferencesSelf,
979
980    Generic,
982
983    CVariadic,
985
986    UndispatchableReceiver(Option<Span>),
988}
989
990#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
992pub enum CodegenObligationError {
993    Ambiguity,
1000    Unimplemented,
1003    UnconstrainedParam(ErrorGuaranteed),
1006}