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};
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: InternedObligationCauseCode<'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(InternedObligationCauseCode<'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, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
148#[derive(TypeVisitable, TypeFoldable)]
149pub struct UnifyReceiverContext<'tcx> {
150 pub assoc_item: ty::AssocItem,
151 pub param_env: ty::ParamEnv<'tcx>,
152 pub args: GenericArgsRef<'tcx>,
153}
154
155#[derive(Clone, PartialEq, Eq, Default, HashStable)]
156#[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
157pub struct InternedObligationCauseCode<'tcx> {
158 code: Option<Arc<ObligationCauseCode<'tcx>>>,
161}
162
163impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 let cause: &ObligationCauseCode<'_> = self;
166 cause.fmt(f)
167 }
168}
169
170impl<'tcx> ObligationCauseCode<'tcx> {
171 #[inline(always)]
172 fn into(self) -> InternedObligationCauseCode<'tcx> {
173 InternedObligationCauseCode {
174 code: if let ObligationCauseCode::Misc = self { None } else { Some(Arc::new(self)) },
175 }
176 }
177}
178
179impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> {
180 type Target = ObligationCauseCode<'tcx>;
181
182 fn deref(&self) -> &Self::Target {
183 self.code.as_deref().unwrap_or(&ObligationCauseCode::Misc)
184 }
185}
186
187#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
188#[derive(TypeVisitable, TypeFoldable)]
189pub enum ObligationCauseCode<'tcx> {
190 Misc,
192
193 SliceOrArrayElem,
195
196 ArrayLen(Ty<'tcx>),
198
199 TupleElem,
201
202 WhereClause(DefId, Span),
205
206 OpaqueTypeBound(Span, Option<LocalDefId>),
210
211 WhereClauseInExpr(DefId, Span, HirId, usize),
216
217 HostEffectInExpr(DefId, Span, HirId, usize),
220
221 ReferenceOutlivesReferent(Ty<'tcx>),
223
224 ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
226
227 Coercion {
229 source: Ty<'tcx>,
230 target: Ty<'tcx>,
231 },
232
233 AssignmentLhsSized,
236 TupleInitializerSized,
238 StructInitializerSized,
240 VariableType(HirId),
242 SizedArgumentType(Option<HirId>),
244 SizedReturnType,
246 SizedCallReturnType,
248 SizedYieldType,
250 InlineAsmSized,
252 SizedClosureCapture(LocalDefId),
254 SizedCoroutineInterior(LocalDefId),
256 RepeatElementCopy {
258 is_constable: IsConstable,
261
262 elt_span: Span,
266 },
267
268 FieldSized {
270 adt_kind: AdtKind,
271 span: Span,
272 last: bool,
273 },
274
275 ConstSized,
277
278 SharedStatic,
280
281 BuiltinDerived(DerivedCause<'tcx>),
284
285 ImplDerived(Box<ImplDerivedCause<'tcx>>),
288
289 WellFormedDerived(DerivedCause<'tcx>),
291
292 ImplDerivedHost(Box<ImplDerivedHostCause<'tcx>>),
295
296 BuiltinDerivedHost(DerivedHostCause<'tcx>),
299
300 FunctionArg {
303 arg_hir_id: HirId,
305 call_hir_id: HirId,
307 parent_code: InternedObligationCauseCode<'tcx>,
309 },
310
311 CompareImplItem {
314 impl_item_def_id: LocalDefId,
315 trait_item_def_id: DefId,
316 kind: ty::AssocKind,
317 },
318
319 CheckAssociatedTypeBounds {
321 impl_item_def_id: LocalDefId,
322 trait_item_def_id: DefId,
323 },
324
325 ExprAssignable,
327
328 MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
330
331 Pattern {
333 span: Option<Span>,
335 root_ty: Ty<'tcx>,
337 origin_expr: Option<PatternOriginExpr>,
339 },
340
341 IfExpression(Box<IfExpressionCause<'tcx>>),
343
344 IfExpressionWithNoElse,
346
347 MainFunctionType,
349
350 LangFunctionType(Symbol),
352
353 IntrinsicType,
355
356 LetElse,
358
359 MethodReceiver,
361
362 UnifyReceiver(Box<UnifyReceiverContext<'tcx>>),
363
364 ReturnNoExpression,
366
367 ReturnValue(HirId),
369
370 OpaqueReturnType(Option<(Ty<'tcx>, HirId)>),
372
373 BlockTailExpression(HirId, hir::MatchSource),
375
376 TrivialBound,
378
379 AwaitableExpr(HirId),
380
381 ForLoopIterator,
382
383 QuestionMark,
384
385 WellFormed(Option<WellFormedLoc>),
392
393 MatchImpl(ObligationCause<'tcx>, DefId),
395
396 BinOp {
397 lhs_hir_id: HirId,
398 rhs_hir_id: Option<HirId>,
399 rhs_span: Option<Span>,
400 rhs_is_lit: bool,
401 output_ty: Option<Ty<'tcx>>,
402 },
403
404 AscribeUserTypeProvePredicate(Span),
405
406 RustCall,
407
408 DropImpl,
411
412 ConstParam(Ty<'tcx>),
414
415 TypeAlias(InternedObligationCauseCode<'tcx>, Span, DefId),
417}
418
419#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
422pub enum IsConstable {
423 No,
424 Fn,
426 Ctor,
428}
429
430#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)]
435#[derive(TypeVisitable, TypeFoldable)]
436pub enum WellFormedLoc {
437 Ty(LocalDefId),
439 Param {
443 function: LocalDefId,
445 param_idx: usize,
449 },
450}
451
452impl<'tcx> ObligationCauseCode<'tcx> {
453 pub fn peel_derives(&self) -> &Self {
455 let mut base_cause = self;
456 while let Some(parent_code) = base_cause.parent() {
457 base_cause = parent_code;
458 }
459 base_cause
460 }
461
462 pub fn parent(&self) -> Option<&Self> {
463 match self {
464 ObligationCauseCode::FunctionArg { parent_code, .. } => Some(parent_code),
465 ObligationCauseCode::BuiltinDerived(derived)
466 | ObligationCauseCode::WellFormedDerived(derived)
467 | ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
468 Some(&derived.parent_code)
469 }
470 ObligationCauseCode::BuiltinDerivedHost(derived)
471 | ObligationCauseCode::ImplDerivedHost(box ImplDerivedHostCause { derived, .. }) => {
472 Some(&derived.parent_code)
473 }
474 _ => None,
475 }
476 }
477
478 pub fn peel_derives_with_predicate(&self) -> (&Self, Option<ty::PolyTraitPredicate<'tcx>>) {
481 let mut base_cause = self;
482 let mut base_trait_pred = None;
483 while let Some((parent_code, parent_pred)) = base_cause.parent_with_predicate() {
484 base_cause = parent_code;
485 if let Some(parent_pred) = parent_pred {
486 base_trait_pred = Some(parent_pred);
487 }
488 }
489
490 (base_cause, base_trait_pred)
491 }
492
493 pub fn parent_with_predicate(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
494 match self {
495 ObligationCauseCode::FunctionArg { parent_code, .. } => Some((parent_code, None)),
496 ObligationCauseCode::BuiltinDerived(derived)
497 | ObligationCauseCode::WellFormedDerived(derived)
498 | ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
499 Some((&derived.parent_code, Some(derived.parent_trait_pred)))
500 }
501 _ => None,
502 }
503 }
504
505 pub fn peel_match_impls(&self) -> &Self {
506 match self {
507 ObligationCauseCode::MatchImpl(cause, _) => cause.code(),
508 _ => self,
509 }
510 }
511}
512
513#[cfg(target_pointer_width = "64")]
515rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
516
517#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
518pub enum StatementAsExpression {
519 CorrectType,
520 NeedsBoxing,
521}
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(Copy, Clone, Debug, PartialEq, Eq)]
566#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
567pub struct IfExpressionCause<'tcx> {
568 pub then_id: HirId,
569 pub else_id: HirId,
570 pub then_ty: Ty<'tcx>,
571 pub else_ty: Ty<'tcx>,
572 pub outer_span: Option<Span>,
573 pub tail_defines_return_position_impl_trait: Option<LocalDefId>,
575}
576
577#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
578#[derive(TypeVisitable, TypeFoldable)]
579pub struct DerivedCause<'tcx> {
580 pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
585
586 pub parent_code: InternedObligationCauseCode<'tcx>,
588}
589
590#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
591#[derive(TypeVisitable, TypeFoldable)]
592pub struct ImplDerivedCause<'tcx> {
593 pub derived: DerivedCause<'tcx>,
594 pub impl_or_alias_def_id: DefId,
599 pub impl_def_predicate_index: Option<usize>,
601 pub span: Span,
602}
603
604#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
605#[derive(TypeVisitable, TypeFoldable)]
606pub struct DerivedHostCause<'tcx> {
607 pub parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
612
613 pub parent_code: InternedObligationCauseCode<'tcx>,
615}
616
617#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
618#[derive(TypeVisitable, TypeFoldable)]
619pub struct ImplDerivedHostCause<'tcx> {
620 pub derived: DerivedHostCause<'tcx>,
621 pub impl_def_id: DefId,
623 pub span: Span,
624}
625
626#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
627pub enum SelectionError<'tcx> {
628 Unimplemented,
630 SignatureMismatch(Box<SignatureMismatchData<'tcx>>),
634 TraitDynIncompatible(DefId),
636 NotConstEvaluatable(NotConstEvaluatable),
638 Overflow(OverflowError),
640 OpaqueTypeAutoTraitLeakageUnknown(DefId),
644 ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
646}
647
648#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
649pub struct SignatureMismatchData<'tcx> {
650 pub found_trait_ref: ty::TraitRef<'tcx>,
651 pub expected_trait_ref: ty::TraitRef<'tcx>,
652 pub terr: ty::error::TypeError<'tcx>,
653}
654
655pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
663
664#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
694#[derive(TypeFoldable, TypeVisitable)]
695pub enum ImplSource<'tcx, N> {
696 UserDefined(ImplSourceUserDefinedData<'tcx, N>),
698
699 Param(ThinVec<N>),
704
705 Builtin(BuiltinImplSource, ThinVec<N>),
707}
708
709impl<'tcx, N> ImplSource<'tcx, N> {
710 pub fn nested_obligations(self) -> ThinVec<N> {
711 match self {
712 ImplSource::UserDefined(i) => i.nested,
713 ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
714 }
715 }
716
717 pub fn borrow_nested_obligations(&self) -> &[N] {
718 match self {
719 ImplSource::UserDefined(i) => &i.nested,
720 ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
721 }
722 }
723
724 pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
725 match self {
726 ImplSource::UserDefined(i) => &mut i.nested,
727 ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
728 }
729 }
730
731 pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
732 where
733 F: FnMut(N) -> M,
734 {
735 match self {
736 ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData {
737 impl_def_id: i.impl_def_id,
738 args: i.args,
739 nested: i.nested.into_iter().map(f).collect(),
740 }),
741 ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()),
742 ImplSource::Builtin(source, n) => {
743 ImplSource::Builtin(source, n.into_iter().map(f).collect())
744 }
745 }
746 }
747}
748
749#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
760#[derive(TypeFoldable, TypeVisitable)]
761pub struct ImplSourceUserDefinedData<'tcx, N> {
762 pub impl_def_id: DefId,
763 pub args: GenericArgsRef<'tcx>,
764 pub nested: ThinVec<N>,
765}
766
767#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
768pub enum DynCompatibilityViolation {
769 SizedSelf(SmallVec<[Span; 1]>),
771
772 SupertraitSelf(SmallVec<[Span; 1]>),
775
776 SupertraitNonLifetimeBinder(SmallVec<[Span; 1]>),
778
779 Method(Symbol, MethodViolationCode, Span),
781
782 AssocConst(Symbol, Span),
784
785 GAT(Symbol, Span),
787}
788
789impl DynCompatibilityViolation {
790 pub fn error_msg(&self) -> Cow<'static, str> {
791 match self {
792 DynCompatibilityViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
793 DynCompatibilityViolation::SupertraitSelf(ref spans) => {
794 if spans.iter().any(|sp| *sp != DUMMY_SP) {
795 "it uses `Self` as a type parameter".into()
796 } else {
797 "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
798 .into()
799 }
800 }
801 DynCompatibilityViolation::SupertraitNonLifetimeBinder(_) => {
802 "where clause cannot reference non-lifetime `for<...>` variables".into()
803 }
804 DynCompatibilityViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
805 format!("associated function `{name}` has no `self` parameter").into()
806 }
807 DynCompatibilityViolation::Method(
808 name,
809 MethodViolationCode::ReferencesSelfInput(_),
810 DUMMY_SP,
811 ) => format!("method `{name}` references the `Self` type in its parameters").into(),
812 DynCompatibilityViolation::Method(
813 name,
814 MethodViolationCode::ReferencesSelfInput(_),
815 _,
816 ) => format!("method `{name}` references the `Self` type in this parameter").into(),
817 DynCompatibilityViolation::Method(
818 name,
819 MethodViolationCode::ReferencesSelfOutput,
820 _,
821 ) => format!("method `{name}` references the `Self` type in its return type").into(),
822 DynCompatibilityViolation::Method(
823 name,
824 MethodViolationCode::ReferencesImplTraitInTrait(_),
825 _,
826 ) => {
827 format!("method `{name}` references an `impl Trait` type in its return type").into()
828 }
829 DynCompatibilityViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
830 format!("method `{name}` is `async`").into()
831 }
832 DynCompatibilityViolation::Method(
833 name,
834 MethodViolationCode::WhereClauseReferencesSelf,
835 _,
836 ) => format!("method `{name}` references the `Self` type in its `where` clause").into(),
837 DynCompatibilityViolation::Method(name, MethodViolationCode::Generic, _) => {
838 format!("method `{name}` has generic type parameters").into()
839 }
840 DynCompatibilityViolation::Method(
841 name,
842 MethodViolationCode::UndispatchableReceiver(_),
843 _,
844 ) => format!("method `{name}`'s `self` parameter cannot be dispatched on").into(),
845 DynCompatibilityViolation::AssocConst(name, DUMMY_SP) => {
846 format!("it contains associated `const` `{name}`").into()
847 }
848 DynCompatibilityViolation::AssocConst(..) => {
849 "it contains this associated `const`".into()
850 }
851 DynCompatibilityViolation::GAT(name, _) => {
852 format!("it contains the generic associated type `{name}`").into()
853 }
854 }
855 }
856
857 pub fn solution(&self) -> DynCompatibilityViolationSolution {
858 match self {
859 DynCompatibilityViolation::SizedSelf(_)
860 | DynCompatibilityViolation::SupertraitSelf(_)
861 | DynCompatibilityViolation::SupertraitNonLifetimeBinder(..) => {
862 DynCompatibilityViolationSolution::None
863 }
864 DynCompatibilityViolation::Method(
865 name,
866 MethodViolationCode::StaticMethod(Some((add_self_sugg, make_sized_sugg))),
867 _,
868 ) => DynCompatibilityViolationSolution::AddSelfOrMakeSized {
869 name: *name,
870 add_self_sugg: add_self_sugg.clone(),
871 make_sized_sugg: make_sized_sugg.clone(),
872 },
873 DynCompatibilityViolation::Method(
874 name,
875 MethodViolationCode::UndispatchableReceiver(Some(span)),
876 _,
877 ) => DynCompatibilityViolationSolution::ChangeToRefSelf(*name, *span),
878 DynCompatibilityViolation::AssocConst(name, _)
879 | DynCompatibilityViolation::GAT(name, _)
880 | DynCompatibilityViolation::Method(name, ..) => {
881 DynCompatibilityViolationSolution::MoveToAnotherTrait(*name)
882 }
883 }
884 }
885
886 pub fn spans(&self) -> SmallVec<[Span; 1]> {
887 match self {
890 DynCompatibilityViolation::SupertraitSelf(spans)
891 | DynCompatibilityViolation::SizedSelf(spans)
892 | DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans) => spans.clone(),
893 DynCompatibilityViolation::AssocConst(_, span)
894 | DynCompatibilityViolation::GAT(_, span)
895 | DynCompatibilityViolation::Method(_, _, span)
896 if *span != DUMMY_SP =>
897 {
898 smallvec![*span]
899 }
900 _ => smallvec![],
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 UndispatchableReceiver(Option<Span>),
985}
986
987#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
989pub enum CodegenObligationError {
990 Ambiguity,
997 Unimplemented,
1002 FulfillmentError,
1003}