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 CompareEii {
427 external_impl: LocalDefId,
428 declaration: DefId,
429 },
430}
431
432#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
435pub enum IsConstable {
436 No,
437 Fn,
439 Ctor,
441}
442
443#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)]
448#[derive(TypeVisitable, TypeFoldable)]
449pub enum WellFormedLoc {
450 Ty(LocalDefId),
452 Param {
456 function: LocalDefId,
458 param_idx: usize,
462 },
463}
464
465impl<'tcx> ObligationCauseCode<'tcx> {
466 pub fn peel_derives(&self) -> &Self {
468 let mut base_cause = self;
469 while let Some(parent_code) = base_cause.parent() {
470 base_cause = parent_code;
471 }
472 base_cause
473 }
474
475 pub fn parent(&self) -> Option<&Self> {
476 match self {
477 ObligationCauseCode::FunctionArg { parent_code, .. } => Some(parent_code),
478 ObligationCauseCode::BuiltinDerived(derived)
479 | ObligationCauseCode::WellFormedDerived(derived)
480 | ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
481 Some(&derived.parent_code)
482 }
483 ObligationCauseCode::BuiltinDerivedHost(derived)
484 | ObligationCauseCode::ImplDerivedHost(box ImplDerivedHostCause { derived, .. }) => {
485 Some(&derived.parent_code)
486 }
487 _ => None,
488 }
489 }
490
491 pub fn peel_derives_with_predicate(&self) -> (&Self, Option<ty::PolyTraitPredicate<'tcx>>) {
494 let mut base_cause = self;
495 let mut base_trait_pred = None;
496 while let Some((parent_code, parent_pred)) = base_cause.parent_with_predicate() {
497 base_cause = parent_code;
498 if let Some(parent_pred) = parent_pred {
499 base_trait_pred = Some(parent_pred);
500 }
501 }
502
503 (base_cause, base_trait_pred)
504 }
505
506 pub fn parent_with_predicate(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
507 match self {
508 ObligationCauseCode::FunctionArg { parent_code, .. } => Some((parent_code, None)),
509 ObligationCauseCode::BuiltinDerived(derived)
510 | ObligationCauseCode::WellFormedDerived(derived)
511 | ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
512 Some((&derived.parent_code, Some(derived.parent_trait_pred)))
513 }
514 _ => None,
515 }
516 }
517
518 pub fn peel_match_impls(&self) -> &Self {
519 match self {
520 ObligationCauseCode::MatchImpl(cause, _) => cause.code(),
521 _ => self,
522 }
523 }
524}
525
526#[cfg(target_pointer_width = "64")]
528rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
529
530#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
531#[derive(TypeVisitable, TypeFoldable)]
532pub struct MatchExpressionArmCause<'tcx> {
533 pub arm_block_id: Option<HirId>,
534 pub arm_ty: Ty<'tcx>,
535 pub arm_span: Span,
536 pub prior_arm_block_id: Option<HirId>,
537 pub prior_arm_ty: Ty<'tcx>,
538 pub prior_arm_span: Span,
539 pub scrut_span: Span,
541 pub source: hir::MatchSource,
543 pub expr_span: Span,
545 pub prior_non_diverging_arms: Vec<Span>,
549 pub tail_defines_return_position_impl_trait: Option<LocalDefId>,
551}
552
553#[derive(Copy, Clone, Debug, PartialEq, Eq)]
557#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
558pub struct PatternOriginExpr {
559 pub peeled_span: Span,
565 pub peeled_count: usize,
567 pub peeled_prefix_suggestion_parentheses: bool,
570}
571
572#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
573#[derive(TypeVisitable, TypeFoldable)]
574pub struct DerivedCause<'tcx> {
575 pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
580
581 pub parent_code: ObligationCauseCodeHandle<'tcx>,
583}
584
585#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
586#[derive(TypeVisitable, TypeFoldable)]
587pub struct ImplDerivedCause<'tcx> {
588 pub derived: DerivedCause<'tcx>,
589 pub impl_or_alias_def_id: DefId,
594 pub impl_def_predicate_index: Option<usize>,
596 pub span: Span,
597}
598
599#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
600#[derive(TypeVisitable, TypeFoldable)]
601pub struct DerivedHostCause<'tcx> {
602 pub parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
607
608 pub parent_code: ObligationCauseCodeHandle<'tcx>,
610}
611
612#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
613#[derive(TypeVisitable, TypeFoldable)]
614pub struct ImplDerivedHostCause<'tcx> {
615 pub derived: DerivedHostCause<'tcx>,
616 pub impl_def_id: DefId,
618 pub span: Span,
619}
620
621#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
622pub enum SelectionError<'tcx> {
623 Unimplemented,
625 SignatureMismatch(Box<SignatureMismatchData<'tcx>>),
629 TraitDynIncompatible(DefId),
631 NotConstEvaluatable(NotConstEvaluatable),
633 Overflow(OverflowError),
635 OpaqueTypeAutoTraitLeakageUnknown(DefId),
639 ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
641}
642
643#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
644pub struct SignatureMismatchData<'tcx> {
645 pub found_trait_ref: ty::TraitRef<'tcx>,
646 pub expected_trait_ref: ty::TraitRef<'tcx>,
647 pub terr: ty::error::TypeError<'tcx>,
648}
649
650pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
658
659#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
689#[derive(TypeFoldable, TypeVisitable)]
690pub enum ImplSource<'tcx, N> {
691 UserDefined(ImplSourceUserDefinedData<'tcx, N>),
693
694 Param(ThinVec<N>),
699
700 Builtin(BuiltinImplSource, ThinVec<N>),
702}
703
704impl<'tcx, N> ImplSource<'tcx, N> {
705 pub fn nested_obligations(self) -> ThinVec<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(&self) -> &[N] {
713 match self {
714 ImplSource::UserDefined(i) => &i.nested,
715 ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
716 }
717 }
718
719 pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
720 match self {
721 ImplSource::UserDefined(i) => &mut i.nested,
722 ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
723 }
724 }
725
726 pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
727 where
728 F: FnMut(N) -> M,
729 {
730 match self {
731 ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData {
732 impl_def_id: i.impl_def_id,
733 args: i.args,
734 nested: i.nested.into_iter().map(f).collect(),
735 }),
736 ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()),
737 ImplSource::Builtin(source, n) => {
738 ImplSource::Builtin(source, n.into_iter().map(f).collect())
739 }
740 }
741 }
742}
743
744#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
755#[derive(TypeFoldable, TypeVisitable)]
756pub struct ImplSourceUserDefinedData<'tcx, N> {
757 pub impl_def_id: DefId,
758 pub args: GenericArgsRef<'tcx>,
759 pub nested: ThinVec<N>,
760}
761
762#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
763pub enum DynCompatibilityViolation {
764 SizedSelf(SmallVec<[Span; 1]>),
766
767 SupertraitSelf(SmallVec<[Span; 1]>),
770
771 SupertraitNonLifetimeBinder(SmallVec<[Span; 1]>),
773
774 SupertraitConst(SmallVec<[Span; 1]>),
776
777 Method(Symbol, MethodViolationCode, Span),
779
780 AssocConst(Symbol, Span),
782
783 GAT(Symbol, Span),
785}
786
787impl DynCompatibilityViolation {
788 pub fn error_msg(&self) -> Cow<'static, str> {
789 match self {
790 DynCompatibilityViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
791 DynCompatibilityViolation::SupertraitSelf(spans) => {
792 if spans.iter().any(|sp| *sp != DUMMY_SP) {
793 "it uses `Self` as a type parameter".into()
794 } else {
795 "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
796 .into()
797 }
798 }
799 DynCompatibilityViolation::SupertraitNonLifetimeBinder(_) => {
800 "where clause cannot reference non-lifetime `for<...>` variables".into()
801 }
802 DynCompatibilityViolation::SupertraitConst(_) => {
803 "it cannot have a `const` supertrait".into()
804 }
805 DynCompatibilityViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
806 format!("associated function `{name}` has no `self` parameter").into()
807 }
808 DynCompatibilityViolation::Method(
809 name,
810 MethodViolationCode::ReferencesSelfInput(_),
811 DUMMY_SP,
812 ) => format!("method `{name}` references the `Self` type in its parameters").into(),
813 DynCompatibilityViolation::Method(
814 name,
815 MethodViolationCode::ReferencesSelfInput(_),
816 _,
817 ) => format!("method `{name}` references the `Self` type in this parameter").into(),
818 DynCompatibilityViolation::Method(
819 name,
820 MethodViolationCode::ReferencesSelfOutput,
821 _,
822 ) => format!("method `{name}` references the `Self` type in its return type").into(),
823 DynCompatibilityViolation::Method(
824 name,
825 MethodViolationCode::ReferencesImplTraitInTrait(_),
826 _,
827 ) => {
828 format!("method `{name}` references an `impl Trait` type in its return type").into()
829 }
830 DynCompatibilityViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
831 format!("method `{name}` is `async`").into()
832 }
833 DynCompatibilityViolation::Method(name, MethodViolationCode::CVariadic, _) => {
834 format!("method `{name}` is C-variadic").into()
835 }
836 DynCompatibilityViolation::Method(
837 name,
838 MethodViolationCode::WhereClauseReferencesSelf,
839 _,
840 ) => format!("method `{name}` references the `Self` type in its `where` clause").into(),
841 DynCompatibilityViolation::Method(name, MethodViolationCode::Generic, _) => {
842 format!("method `{name}` has generic type parameters").into()
843 }
844 DynCompatibilityViolation::Method(
845 name,
846 MethodViolationCode::UndispatchableReceiver(_),
847 _,
848 ) => format!("method `{name}`'s `self` parameter cannot be dispatched on").into(),
849 DynCompatibilityViolation::AssocConst(name, DUMMY_SP) => {
850 format!("it contains associated `const` `{name}`").into()
851 }
852 DynCompatibilityViolation::AssocConst(..) => {
853 "it contains this associated `const`".into()
854 }
855 DynCompatibilityViolation::GAT(name, _) => {
856 format!("it contains the generic associated type `{name}`").into()
857 }
858 }
859 }
860
861 pub fn solution(&self) -> DynCompatibilityViolationSolution {
862 match self {
863 DynCompatibilityViolation::SizedSelf(_)
864 | DynCompatibilityViolation::SupertraitSelf(_)
865 | DynCompatibilityViolation::SupertraitNonLifetimeBinder(..)
866 | DynCompatibilityViolation::SupertraitConst(_) => {
867 DynCompatibilityViolationSolution::None
868 }
869 DynCompatibilityViolation::Method(
870 name,
871 MethodViolationCode::StaticMethod(Some((add_self_sugg, make_sized_sugg))),
872 _,
873 ) => DynCompatibilityViolationSolution::AddSelfOrMakeSized {
874 name: *name,
875 add_self_sugg: add_self_sugg.clone(),
876 make_sized_sugg: make_sized_sugg.clone(),
877 },
878 DynCompatibilityViolation::Method(
879 name,
880 MethodViolationCode::UndispatchableReceiver(Some(span)),
881 _,
882 ) => DynCompatibilityViolationSolution::ChangeToRefSelf(*name, *span),
883 DynCompatibilityViolation::AssocConst(name, _)
884 | DynCompatibilityViolation::GAT(name, _)
885 | DynCompatibilityViolation::Method(name, ..) => {
886 DynCompatibilityViolationSolution::MoveToAnotherTrait(*name)
887 }
888 }
889 }
890
891 pub fn spans(&self) -> SmallVec<[Span; 1]> {
892 match self {
895 DynCompatibilityViolation::SupertraitSelf(spans)
896 | DynCompatibilityViolation::SizedSelf(spans)
897 | DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans)
898 | DynCompatibilityViolation::SupertraitConst(spans) => spans.clone(),
899 DynCompatibilityViolation::AssocConst(_, span)
900 | DynCompatibilityViolation::GAT(_, span)
901 | DynCompatibilityViolation::Method(_, _, span) => {
902 if *span != DUMMY_SP {
903 smallvec![*span]
904 } else {
905 smallvec![]
906 }
907 }
908 }
909 }
910}
911
912#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
913pub enum DynCompatibilityViolationSolution {
914 None,
915 AddSelfOrMakeSized {
916 name: Symbol,
917 add_self_sugg: (String, Span),
918 make_sized_sugg: (String, Span),
919 },
920 ChangeToRefSelf(Symbol, Span),
921 MoveToAnotherTrait(Symbol),
922}
923
924impl DynCompatibilityViolationSolution {
925 pub fn add_to<G: EmissionGuarantee>(self, err: &mut Diag<'_, G>) {
926 match self {
927 DynCompatibilityViolationSolution::None => {}
928 DynCompatibilityViolationSolution::AddSelfOrMakeSized {
929 name,
930 add_self_sugg,
931 make_sized_sugg,
932 } => {
933 err.span_suggestion(
934 add_self_sugg.1,
935 format!(
936 "consider turning `{name}` into a method by giving it a `&self` argument"
937 ),
938 add_self_sugg.0,
939 Applicability::MaybeIncorrect,
940 );
941 err.span_suggestion(
942 make_sized_sugg.1,
943 format!(
944 "alternatively, consider constraining `{name}` so it does not apply to \
945 trait objects"
946 ),
947 make_sized_sugg.0,
948 Applicability::MaybeIncorrect,
949 );
950 }
951 DynCompatibilityViolationSolution::ChangeToRefSelf(name, span) => {
952 err.span_suggestion(
953 span,
954 format!("consider changing method `{name}`'s `self` parameter to be `&self`"),
955 "&Self",
956 Applicability::MachineApplicable,
957 );
958 }
959 DynCompatibilityViolationSolution::MoveToAnotherTrait(name) => {
960 err.help(format!("consider moving `{name}` to another trait"));
961 }
962 }
963 }
964}
965
966#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
968pub enum MethodViolationCode {
969 StaticMethod(Option<((String, Span), (String, Span))>),
971
972 ReferencesSelfInput(Option<Span>),
974
975 ReferencesSelfOutput,
977
978 ReferencesImplTraitInTrait(Span),
980
981 AsyncFn,
983
984 WhereClauseReferencesSelf,
986
987 Generic,
989
990 CVariadic,
992
993 UndispatchableReceiver(Option<Span>),
995}
996
997#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
999pub enum CodegenObligationError {
1000 Ambiguity,
1007 Unimplemented,
1010 UnconstrainedParam(ErrorGuaranteed),
1013}