33use rustc_data_structures:: packed:: Pu128 ;
44use rustc_errors:: codes:: * ;
55use rustc_errors:: { Applicability , Diag , struct_span_code_err} ;
6+ use rustc_hir:: LangItem ;
67use rustc_infer:: traits:: ObligationCauseCode ;
78use rustc_middle:: ty:: adjustment:: {
89 Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability ,
@@ -194,6 +195,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
194195 self . demand_suptype ( rhs_span, lhs_ty, rhs_ty) ;
195196 tcx. types . bool
196197 }
198+
199+ BinOpCategory :: ThreeWayComparison => {
200+ // both LHS and RHS and result will have the same type
201+ self . demand_suptype ( rhs_span, lhs_ty, rhs_ty) ;
202+ tcx. ty_ordering_enum ( Some ( lhs_span) )
203+ }
204+
205+ BinOpCategory :: ThreeWayComparisonPartial => {
206+ // both LHS and RHS and result will have the same type
207+ self . demand_suptype ( rhs_span, lhs_ty, rhs_ty) ;
208+ let ordering_ty = tcx. ty_ordering_enum ( Some ( lhs_span) ) ;
209+ Ty :: new_lang_item ( tcx, ordering_ty, LangItem :: Option ) . unwrap ( )
210+ }
197211 }
198212 }
199213
@@ -1006,7 +1020,9 @@ fn lang_item_for_op(
10061020 | hir:: BinOpKind :: Eq
10071021 | hir:: BinOpKind :: Ne
10081022 | hir:: BinOpKind :: And
1009- | hir:: BinOpKind :: Or => {
1023+ | hir:: BinOpKind :: Or
1024+ | hir:: BinOpKind :: Cmp
1025+ | hir:: BinOpKind :: CmpPartial => {
10101026 span_bug ! ( span, "impossible assignment operation: {}=" , op. node. as_str( ) )
10111027 }
10121028 }
@@ -1027,6 +1043,8 @@ fn lang_item_for_op(
10271043 hir:: BinOpKind :: Ge => ( sym:: ge, lang. partial_ord_trait ( ) ) ,
10281044 hir:: BinOpKind :: Gt => ( sym:: gt, lang. partial_ord_trait ( ) ) ,
10291045 hir:: BinOpKind :: Eq => ( sym:: eq, lang. eq_trait ( ) ) ,
1046+ hir:: BinOpKind :: Cmp => ( sym:: cmp, lang. ord_trait ( ) ) ,
1047+ hir:: BinOpKind :: CmpPartial => ( sym:: partial_cmp, lang. partial_ord_trait ( ) ) ,
10301048 hir:: BinOpKind :: Ne => ( sym:: ne, lang. eq_trait ( ) ) ,
10311049 hir:: BinOpKind :: And | hir:: BinOpKind :: Or => {
10321050 span_bug ! ( span, "&& and || are not overloadable" )
@@ -1062,6 +1080,9 @@ enum BinOpCategory {
10621080 /// ==, !=, etc -- takes equal types, produces bools, except for simd,
10631081 /// which produce the input type
10641082 Comparison ,
1083+
1084+ ThreeWayComparison ,
1085+ ThreeWayComparisonPartial ,
10651086}
10661087
10671088impl BinOpCategory {
@@ -1086,6 +1107,9 @@ impl BinOpCategory {
10861107 | hir:: BinOpKind :: Ge
10871108 | hir:: BinOpKind :: Gt => BinOpCategory :: Comparison ,
10881109
1110+ hir:: BinOpKind :: Cmp => BinOpCategory :: ThreeWayComparison ,
1111+ hir:: BinOpKind :: CmpPartial => BinOpCategory :: ThreeWayComparisonPartial ,
1112+
10891113 hir:: BinOpKind :: And | hir:: BinOpKind :: Or => BinOpCategory :: Shortcircuit ,
10901114 }
10911115 }
@@ -1157,7 +1181,9 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool
11571181 || lhs. is_bool ( ) && rhs. is_bool ( )
11581182 }
11591183
1160- BinOpCategory :: Comparison => {
1184+ BinOpCategory :: Comparison
1185+ | BinOpCategory :: ThreeWayComparison
1186+ | BinOpCategory :: ThreeWayComparisonPartial => {
11611187 lhs. references_error ( ) || rhs. references_error ( ) || lhs. is_scalar ( ) && rhs. is_scalar ( )
11621188 }
11631189 }
0 commit comments