From 88bcc79f316b342c9413c5760bc2f6d5ac69e4fe Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross@umich.edu>
Date: Thu, 4 Apr 2024 21:18:24 -0500
Subject: [PATCH 1/4] Revert "Put basic impls for f16 and f128 behind
 cfg(not(bootstrap))"

This reverts commit 049a91753594422b6c672bf5a46e04076fc45d9e.

The resolution to <https://github.com/rust-lang/rust/issues/123282> is
that the `f16`/`f128` regression in the beta compiler was fixable
without a revert, so the commit adding `#[cfg(not(bootstrap))]` is no
longer useful (added in
<https://github.com/rust-lang/rust/pull/123390>).

Revert this commit because not having these basic impls bootstrap-gated
simplifies everything else that uses them.
---
 library/core/src/clone.rs  |  5 +----
 library/core/src/cmp.rs    | 10 ++--------
 library/core/src/lib.rs    |  4 ++--
 library/core/src/marker.rs |  8 +-------
 4 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 44ae72bcd26bf..d448c5338fc46 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -227,13 +227,10 @@ mod impls {
     impl_clone! {
         usize u8 u16 u32 u64 u128
         isize i8 i16 i32 i64 i128
-        f32 f64
+        f16 f32 f64 f128
         bool char
     }
 
-    #[cfg(not(bootstrap))]
-    impl_clone! { f16 f128 }
-
     #[unstable(feature = "never_type", issue = "35121")]
     impl Clone for ! {
         #[inline]
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 81bba927554a4..fa218600ed925 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1497,12 +1497,9 @@ mod impls {
     }
 
     partial_eq_impl! {
-        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
+        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
     }
 
-    #[cfg(not(bootstrap))]
-    partial_eq_impl! { f16 f128 }
-
     macro_rules! eq_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
@@ -1553,10 +1550,7 @@ mod impls {
         }
     }
 
-    partial_ord_impl! { f32 f64 }
-
-    #[cfg(not(bootstrap))]
-    partial_ord_impl! { f16 f128 }
+    partial_ord_impl! { f16 f32 f64 f128 }
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 0ba3a557a035a..ad141c2b2625e 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -200,8 +200,6 @@
 //
 // Language features:
 // tidy-alphabetical-start
-#![cfg_attr(not(bootstrap), feature(f128))]
-#![cfg_attr(not(bootstrap), feature(f16))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -226,6 +224,8 @@
 #![feature(doc_notable_trait)]
 #![feature(effects)]
 #![feature(extern_types)]
+#![feature(f128)]
+#![feature(f16)]
 #![feature(freeze_impls)]
 #![feature(fundamental)]
 #![feature(generic_arg_infer)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index fb97b3bfa0926..1d073a6d649b8 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -422,17 +422,11 @@ marker_impls! {
     Copy for
         usize, u8, u16, u32, u64, u128,
         isize, i8, i16, i32, i64, i128,
-        f32, f64,
+        f16, f32, f64, f128,
         bool, char,
         {T: ?Sized} *const T,
         {T: ?Sized} *mut T,
-}
 
-#[cfg(not(bootstrap))]
-marker_impls! {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    Copy for
-        f16, f128,
 }
 
 #[unstable(feature = "never_type", issue = "35121")]

From 454de78ea3073a284a7a8a41184789f9afa066a3 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross@umich.edu>
Date: Wed, 6 Mar 2024 05:40:29 -0600
Subject: [PATCH 2/4] Add basic library support for `f16` and `f128`

Implement basic operation traits that get lowered to intrinsics. This
includes codegen tests for implemented operations.
---
 library/core/src/convert/num.rs         |   7 ++
 library/core/src/fmt/nofloat.rs         |   2 +
 library/core/src/ops/arith.rs           |  22 ++--
 tests/codegen/float/f128.rs             | 129 ++++++++++++++++++++++++
 tests/codegen/float/f16.rs              | 129 ++++++++++++++++++++++++
 tests/ui/issues/issue-11771.stderr      |  12 +--
 tests/ui/issues/issue-50582.stderr      |   6 +-
 tests/ui/mismatched_types/binops.stderr |  18 ++--
 8 files changed, 296 insertions(+), 29 deletions(-)
 create mode 100644 tests/codegen/float/f128.rs
 create mode 100644 tests/codegen/float/f16.rs

diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs
index 0167d04c413fe..1737c631f0bd0 100644
--- a/library/core/src/convert/num.rs
+++ b/library/core/src/convert/num.rs
@@ -34,8 +34,10 @@ macro_rules! impl_float_to_int {
     }
 }
 
+impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
 impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
 impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
+impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
 
 // Conversion traits for primitive integer and float types
 // Conversions T -> T are covered by a blanket impl and therefore excluded
@@ -163,7 +165,12 @@ impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
 impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
 
 // float -> float
+impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
+impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
+impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
 impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
+impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
+impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
 
 macro_rules! impl_float_from_bool {
     ($float:ty) => {
diff --git a/library/core/src/fmt/nofloat.rs b/library/core/src/fmt/nofloat.rs
index cfb94cd9de530..a36e7efcd95c7 100644
--- a/library/core/src/fmt/nofloat.rs
+++ b/library/core/src/fmt/nofloat.rs
@@ -11,5 +11,7 @@ macro_rules! floating {
     };
 }
 
+floating! { f16 }
 floating! { f32 }
 floating! { f64 }
+floating! { f128 }
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index fd50f80474833..5e77788d8ea36 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -109,7 +109,7 @@ macro_rules! add_impl {
     )*)
 }
 
-add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The subtraction operator `-`.
 ///
@@ -218,7 +218,7 @@ macro_rules! sub_impl {
     )*)
 }
 
-sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The multiplication operator `*`.
 ///
@@ -348,7 +348,7 @@ macro_rules! mul_impl {
     )*)
 }
 
-mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The division operator `/`.
 ///
@@ -506,7 +506,7 @@ macro_rules! div_impl_float {
     )*)
 }
 
-div_impl_float! { f32 f64 }
+div_impl_float! { f16 f32 f64 f128 }
 
 /// The remainder operator `%`.
 ///
@@ -623,7 +623,7 @@ macro_rules! rem_impl_float {
     )*)
 }
 
-rem_impl_float! { f32 f64 }
+rem_impl_float! { f16 f32 f64 f128 }
 
 /// The unary negation operator `-`.
 ///
@@ -698,7 +698,7 @@ macro_rules! neg_impl {
     )*)
 }
 
-neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
+neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The addition assignment operator `+=`.
 ///
@@ -765,7 +765,7 @@ macro_rules! add_assign_impl {
     )+)
 }
 
-add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The subtraction assignment operator `-=`.
 ///
@@ -832,7 +832,7 @@ macro_rules! sub_assign_impl {
     )+)
 }
 
-sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The multiplication assignment operator `*=`.
 ///
@@ -890,7 +890,7 @@ macro_rules! mul_assign_impl {
     )+)
 }
 
-mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The division assignment operator `/=`.
 ///
@@ -947,7 +947,7 @@ macro_rules! div_assign_impl {
     )+)
 }
 
-div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
 
 /// The remainder assignment operator `%=`.
 ///
@@ -1008,4 +1008,4 @@ macro_rules! rem_assign_impl {
     )+)
 }
 
-rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
diff --git a/tests/codegen/float/f128.rs b/tests/codegen/float/f128.rs
new file mode 100644
index 0000000000000..97d545e028307
--- /dev/null
+++ b/tests/codegen/float/f128.rs
@@ -0,0 +1,129 @@
+// Verify that our intrinsics generate the correct LLVM calls for f128
+
+#![crate_type = "lib"]
+#![feature(f128)]
+#![feature(core_intrinsics)]
+
+// CHECK-LABEL: i1 @f128_eq(
+#[no_mangle]
+pub fn f128_eq(a: f128, b: f128) -> bool {
+    // CHECK: fcmp oeq fp128 %{{.+}}, %{{.+}}
+    a == b
+}
+
+// CHECK-LABEL: i1 @f128_ne(
+#[no_mangle]
+pub fn f128_ne(a: f128, b: f128) -> bool {
+    // CHECK: fcmp une fp128 %{{.+}}, %{{.+}}
+    a != b
+}
+
+// CHECK-LABEL: i1 @f128_gt(
+#[no_mangle]
+pub fn f128_gt(a: f128, b: f128) -> bool {
+    // CHECK: fcmp ogt fp128 %{{.+}}, %{{.+}}
+    a > b
+}
+
+// CHECK-LABEL: i1 @f128_ge(
+#[no_mangle]
+pub fn f128_ge(a: f128, b: f128) -> bool {
+    // CHECK: fcmp oge fp128 %{{.+}}, %{{.+}}
+    a >= b
+}
+
+// CHECK-LABEL: i1 @f128_lt(
+#[no_mangle]
+pub fn f128_lt(a: f128, b: f128) -> bool {
+    // CHECK: fcmp olt fp128 %{{.+}}, %{{.+}}
+    a < b
+}
+
+// CHECK-LABEL: i1 @f128_le(
+#[no_mangle]
+pub fn f128_le(a: f128, b: f128) -> bool {
+    // CHECK: fcmp ole fp128 %{{.+}}, %{{.+}}
+    a <= b
+}
+
+// CHECK-LABEL: fp128 @f128_neg(
+#[no_mangle]
+pub fn f128_neg(a: f128) -> f128 {
+    // CHECK: fneg fp128
+    -a
+}
+
+// CHECK-LABEL: fp128 @f128_add(
+#[no_mangle]
+pub fn f128_add(a: f128, b: f128) -> f128 {
+    // CHECK: fadd fp128 %{{.+}}, %{{.+}}
+    a + b
+}
+
+// CHECK-LABEL: fp128 @f128_sub(
+#[no_mangle]
+pub fn f128_sub(a: f128, b: f128) -> f128 {
+    // CHECK: fsub fp128 %{{.+}}, %{{.+}}
+    a - b
+}
+
+// CHECK-LABEL: fp128 @f128_mul(
+#[no_mangle]
+pub fn f128_mul(a: f128, b: f128) -> f128 {
+    // CHECK: fmul fp128 %{{.+}}, %{{.+}}
+    a * b
+}
+
+// CHECK-LABEL: fp128 @f128_div(
+#[no_mangle]
+pub fn f128_div(a: f128, b: f128) -> f128 {
+    // CHECK: fdiv fp128 %{{.+}}, %{{.+}}
+    a / b
+}
+
+// CHECK-LABEL: fp128 @f128_rem(
+#[no_mangle]
+pub fn f128_rem(a: f128, b: f128) -> f128 {
+    // CHECK: frem fp128 %{{.+}}, %{{.+}}
+    a % b
+}
+
+// CHECK-LABEL: void @f128_add_assign(
+#[no_mangle]
+pub fn f128_add_assign(a: &mut f128, b: f128) {
+    // CHECK: fadd fp128 %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
+    *a += b;
+}
+
+// CHECK-LABEL: void @f128_sub_assign(
+#[no_mangle]
+pub fn f128_sub_assign(a: &mut f128, b: f128) {
+    // CHECK: fsub fp128 %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
+    *a -= b;
+}
+
+// CHECK-LABEL: void @f128_mul_assign(
+#[no_mangle]
+pub fn f128_mul_assign(a: &mut f128, b: f128) {
+    // CHECK: fmul fp128 %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
+    *a *= b
+}
+
+// CHECK-LABEL: void @f128_div_assign(
+#[no_mangle]
+pub fn f128_div_assign(a: &mut f128, b: f128) {
+    // CHECK: fdiv fp128 %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
+    *a /= b
+}
+
+// CHECK-LABEL: void @f128_rem_assign(
+#[no_mangle]
+pub fn f128_rem_assign(a: &mut f128, b: f128) {
+    // CHECK: frem fp128 %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
+    *a %= b
+}
diff --git a/tests/codegen/float/f16.rs b/tests/codegen/float/f16.rs
new file mode 100644
index 0000000000000..d1f75cc3b6851
--- /dev/null
+++ b/tests/codegen/float/f16.rs
@@ -0,0 +1,129 @@
+// Verify that our intrinsics generate the correct LLVM calls for f16
+
+#![crate_type = "lib"]
+#![feature(f16)]
+#![feature(core_intrinsics)]
+
+// CHECK-LABEL: i1 @f16_eq(
+#[no_mangle]
+pub fn f16_eq(a: f16, b: f16) -> bool {
+    // CHECK: fcmp oeq half %{{.+}}, %{{.+}}
+    a == b
+}
+
+// CHECK-LABEL: i1 @f16_ne(
+#[no_mangle]
+pub fn f16_ne(a: f16, b: f16) -> bool {
+    // CHECK: fcmp une half %{{.+}}, %{{.+}}
+    a != b
+}
+
+// CHECK-LABEL: i1 @f16_gt(
+#[no_mangle]
+pub fn f16_gt(a: f16, b: f16) -> bool {
+    // CHECK: fcmp ogt half %{{.+}}, %{{.+}}
+    a > b
+}
+
+// CHECK-LABEL: i1 @f16_ge(
+#[no_mangle]
+pub fn f16_ge(a: f16, b: f16) -> bool {
+    // CHECK: fcmp oge half %{{.+}}, %{{.+}}
+    a >= b
+}
+
+// CHECK-LABEL: i1 @f16_lt(
+#[no_mangle]
+pub fn f16_lt(a: f16, b: f16) -> bool {
+    // CHECK: fcmp olt half %{{.+}}, %{{.+}}
+    a < b
+}
+
+// CHECK-LABEL: i1 @f16_le(
+#[no_mangle]
+pub fn f16_le(a: f16, b: f16) -> bool {
+    // CHECK: fcmp ole half %{{.+}}, %{{.+}}
+    a <= b
+}
+
+// CHECK-LABEL: half @f16_neg(
+#[no_mangle]
+pub fn f16_neg(a: f16) -> f16 {
+    // CHECK: fneg half %{{.+}}
+    -a
+}
+
+// CHECK-LABEL: half @f16_add(
+#[no_mangle]
+pub fn f16_add(a: f16, b: f16) -> f16 {
+    // CHECK: fadd half %{{.+}}, %{{.+}}
+    a + b
+}
+
+// CHECK-LABEL: half @f16_sub(
+#[no_mangle]
+pub fn f16_sub(a: f16, b: f16) -> f16 {
+    // CHECK: fsub half %{{.+}}, %{{.+}}
+    a - b
+}
+
+// CHECK-LABEL: half @f16_mul(
+#[no_mangle]
+pub fn f16_mul(a: f16, b: f16) -> f16 {
+    // CHECK: fmul half %{{.+}}, %{{.+}}
+    a * b
+}
+
+// CHECK-LABEL: half @f16_div(
+#[no_mangle]
+pub fn f16_div(a: f16, b: f16) -> f16 {
+    // CHECK: fdiv half %{{.+}}, %{{.+}}
+    a / b
+}
+
+// CHECK-LABEL: half @f16_rem(
+#[no_mangle]
+pub fn f16_rem(a: f16, b: f16) -> f16 {
+    // CHECK: frem half %{{.+}}, %{{.+}}
+    a % b
+}
+
+// CHECK-LABEL: void @f16_add_assign(
+#[no_mangle]
+pub fn f16_add_assign(a: &mut f16, b: f16) {
+    // CHECK: fadd half %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
+    *a += b;
+}
+
+// CHECK-LABEL: void @f16_sub_assign(
+#[no_mangle]
+pub fn f16_sub_assign(a: &mut f16, b: f16) {
+    // CHECK: fsub half %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
+    *a -= b;
+}
+
+// CHECK-LABEL: void @f16_mul_assign(
+#[no_mangle]
+pub fn f16_mul_assign(a: &mut f16, b: f16) {
+    // CHECK: fmul half %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
+    *a *= b
+}
+
+// CHECK-LABEL: void @f16_div_assign(
+#[no_mangle]
+pub fn f16_div_assign(a: &mut f16, b: f16) {
+    // CHECK: fdiv half %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
+    *a /= b
+}
+
+// CHECK-LABEL: void @f16_rem_assign(
+#[no_mangle]
+pub fn f16_rem_assign(a: &mut f16, b: f16) {
+    // CHECK: frem half %{{.+}}, %{{.+}}
+    // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
+    *a %= b
+}
diff --git a/tests/ui/issues/issue-11771.stderr b/tests/ui/issues/issue-11771.stderr
index 161fce4b0315c..d4a4647f6a10d 100644
--- a/tests/ui/issues/issue-11771.stderr
+++ b/tests/ui/issues/issue-11771.stderr
@@ -6,15 +6,15 @@ LL |     1 +
    |
    = help: the trait `Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
+             <&'a f128 as Add<f128>>
+             <&'a f16 as Add<f16>>
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
              <&'a i128 as Add<i128>>
              <&'a i16 as Add<i16>>
              <&'a i32 as Add<i32>>
              <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
-           and 48 others
+           and 56 others
 
 error[E0277]: cannot add `()` to `{integer}`
   --> $DIR/issue-11771.rs:8:7
@@ -24,15 +24,15 @@ LL |     1 +
    |
    = help: the trait `Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
+             <&'a f128 as Add<f128>>
+             <&'a f16 as Add<f16>>
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
              <&'a i128 as Add<i128>>
              <&'a i16 as Add<i16>>
              <&'a i32 as Add<i32>>
              <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
-           and 48 others
+           and 56 others
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr
index 1967b51128f61..b765d2f087d0a 100644
--- a/tests/ui/issues/issue-50582.stderr
+++ b/tests/ui/issues/issue-50582.stderr
@@ -16,15 +16,15 @@ LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
    |
    = help: the trait `Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
+             <&'a f128 as Add<f128>>
+             <&'a f16 as Add<f16>>
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
              <&'a i128 as Add<i128>>
              <&'a i16 as Add<i16>>
              <&'a i32 as Add<i32>>
              <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
-           and 48 others
+           and 56 others
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr
index f8047c8e2d449..099c580a0565e 100644
--- a/tests/ui/mismatched_types/binops.stderr
+++ b/tests/ui/mismatched_types/binops.stderr
@@ -6,15 +6,15 @@ LL |     1 + Some(1);
    |
    = help: the trait `Add<Option<{integer}>>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
+             <&'a f128 as Add<f128>>
+             <&'a f16 as Add<f16>>
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
              <&'a i128 as Add<i128>>
              <&'a i16 as Add<i16>>
              <&'a i32 as Add<i32>>
              <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
-           and 48 others
+           and 56 others
 
 error[E0277]: cannot subtract `Option<{integer}>` from `usize`
   --> $DIR/binops.rs:3:16
@@ -37,15 +37,15 @@ LL |     3 * ();
    |
    = help: the trait `Mul<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <&'a f128 as Mul<f128>>
+             <&'a f16 as Mul<f16>>
              <&'a f32 as Mul<f32>>
              <&'a f64 as Mul<f64>>
              <&'a i128 as Mul<i128>>
              <&'a i16 as Mul<i16>>
              <&'a i32 as Mul<i32>>
              <&'a i64 as Mul<i64>>
-             <&'a i8 as Mul<i8>>
-             <&'a isize as Mul<isize>>
-           and 49 others
+           and 57 others
 
 error[E0277]: cannot divide `{integer}` by `&str`
   --> $DIR/binops.rs:5:7
@@ -55,15 +55,15 @@ LL |     4 / "";
    |
    = help: the trait `Div<&str>` is not implemented for `{integer}`
    = help: the following other types implement trait `Div<Rhs>`:
+             <&'a f128 as Div<f128>>
+             <&'a f16 as Div<f16>>
              <&'a f32 as Div<f32>>
              <&'a f64 as Div<f64>>
              <&'a i128 as Div<i128>>
              <&'a i16 as Div<i16>>
              <&'a i32 as Div<i32>>
              <&'a i64 as Div<i64>>
-             <&'a i8 as Div<i8>>
-             <&'a isize as Div<isize>>
-           and 54 others
+           and 62 others
 
 error[E0277]: can't compare `{integer}` with `String`
   --> $DIR/binops.rs:6:7

From 143ecc3202e033cf843bc05c06d29cd3e4033497 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross@umich.edu>
Date: Tue, 26 Mar 2024 04:02:54 -0400
Subject: [PATCH 3/4] Add basic f16 and f128 modules

Create empty modules so `rustdoc` has someplace to link to for these
types.
---
 library/core/src/lib.rs       |  4 +++
 library/core/src/num/f128.rs  | 16 ++++++++++++
 library/core/src/num/f16.rs   | 16 ++++++++++++
 library/std/src/f128.rs       | 11 +++++++++
 library/std/src/f128/tests.rs | 40 ++++++++++++++++++++++++++++++
 library/std/src/f16.rs        | 11 +++++++++
 library/std/src/f16/tests.rs  | 46 +++++++++++++++++++++++++++++++++++
 library/std/src/lib.rs        |  6 +++++
 8 files changed, 150 insertions(+)
 create mode 100644 library/core/src/num/f128.rs
 create mode 100644 library/core/src/num/f16.rs
 create mode 100644 library/std/src/f128.rs
 create mode 100644 library/std/src/f128/tests.rs
 create mode 100644 library/std/src/f16.rs
 create mode 100644 library/std/src/f16/tests.rs

diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index ad141c2b2625e..10d2698c5dd1b 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -347,6 +347,10 @@ pub mod u8;
 #[path = "num/shells/usize.rs"]
 pub mod usize;
 
+#[path = "num/f128.rs"]
+pub mod f128;
+#[path = "num/f16.rs"]
+pub mod f16;
 #[path = "num/f32.rs"]
 pub mod f32;
 #[path = "num/f64.rs"]
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
new file mode 100644
index 0000000000000..3bc3e2dbf1242
--- /dev/null
+++ b/library/core/src/num/f128.rs
@@ -0,0 +1,16 @@
+//! Constants for the `f128` quadruple-precision floating point type.
+//!
+//! *[See also the `f128` primitive type][f128].*
+//!
+//! Mathematically significant numbers are provided in the `consts` sub-module.
+//!
+//! For the constants defined directly in this module
+//! (as distinct from those defined in the `consts` sub-module),
+//! new code should instead use the associated constants
+//! defined directly on the `f128` type.
+
+#![unstable(feature = "f128", issue = "116909")]
+
+/// Basic mathematical constants.
+#[unstable(feature = "f128", issue = "116909")]
+pub mod consts {}
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
new file mode 100644
index 0000000000000..969ebdc5690c1
--- /dev/null
+++ b/library/core/src/num/f16.rs
@@ -0,0 +1,16 @@
+//! Constants for the `f16` half-precision floating point type.
+//!
+//! *[See also the `f16` primitive type][f16].*
+//!
+//! Mathematically significant numbers are provided in the `consts` sub-module.
+//!
+//! For the constants defined directly in this module
+//! (as distinct from those defined in the `consts` sub-module),
+//! new code should instead use the associated constants
+//! defined directly on the `f16` type.
+
+#![unstable(feature = "f16", issue = "116909")]
+
+/// Basic mathematical constants.
+#[unstable(feature = "f16", issue = "116909")]
+pub mod consts {}
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
new file mode 100644
index 0000000000000..4710d7c50b444
--- /dev/null
+++ b/library/std/src/f128.rs
@@ -0,0 +1,11 @@
+//! Constants for the `f128` double-precision floating point type.
+//!
+//! *[See also the `f128` primitive type](primitive@f128).*
+//!
+//! Mathematically significant numbers are provided in the `consts` sub-module.
+
+#[cfg(test)]
+mod tests;
+
+#[unstable(feature = "f128", issue = "116909")]
+pub use core::f128::consts;
diff --git a/library/std/src/f128/tests.rs b/library/std/src/f128/tests.rs
new file mode 100644
index 0000000000000..b64c7f856a15f
--- /dev/null
+++ b/library/std/src/f128/tests.rs
@@ -0,0 +1,40 @@
+#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
+
+/// Smallest number
+const TINY_BITS: u128 = 0x1;
+/// Next smallest number
+const TINY_UP_BITS: u128 = 0x2;
+/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
+const MAX_DOWN_BITS: u128 = 0x7ffeffffffffffffffffffffffffffff;
+/// Zeroed exponent, full significant
+const LARGEST_SUBNORMAL_BITS: u128 = 0x0000ffffffffffffffffffffffffffff;
+/// Exponent = 0b1, zeroed significand
+const SMALLEST_NORMAL_BITS: u128 = 0x00010000000000000000000000000000;
+/// First pattern over the mantissa
+const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+/// Second pattern over the mantissa
+const NAN_MASK2: u128 = 0x00005555555555555555555555555555;
+
+/// Compare by value
+#[allow(unused_macros)]
+macro_rules! assert_f128_eq {
+    ($a:expr, $b:expr) => {
+        let (l, r): (&f128, &f128) = (&$a, &$b);
+        assert_eq!(*l, *r, "\na: {:#0130x}\nb: {:#0130x}", l.to_bits(), r.to_bits())
+    };
+}
+
+/// Compare by representation
+#[allow(unused_macros)]
+macro_rules! assert_f128_biteq {
+    ($a:expr, $b:expr) => {
+        let (l, r): (&f128, &f128) = (&$a, &$b);
+        let lb = l.to_bits();
+        let rb = r.to_bits();
+        assert_eq!(
+            lb, rb,
+            "float {:?} is not bitequal to {:?}.\na: {:#0130x}\nb: {:#0130x}",
+            *l, *r, lb, rb
+        );
+    };
+}
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
new file mode 100644
index 0000000000000..c36f9f5d4c6a8
--- /dev/null
+++ b/library/std/src/f16.rs
@@ -0,0 +1,11 @@
+//! Constants for the `f16` double-precision floating point type.
+//!
+//! *[See also the `f16` primitive type](primitive@f16).*
+//!
+//! Mathematically significant numbers are provided in the `consts` sub-module.
+
+#[cfg(test)]
+mod tests;
+
+#[unstable(feature = "f16", issue = "116909")]
+pub use core::f16::consts;
diff --git a/library/std/src/f16/tests.rs b/library/std/src/f16/tests.rs
new file mode 100644
index 0000000000000..d65c43eca4bb8
--- /dev/null
+++ b/library/std/src/f16/tests.rs
@@ -0,0 +1,46 @@
+#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
+
+// We run out of precision pretty quickly with f16
+const F16_APPROX_L1: f16 = 0.001;
+const F16_APPROX_L2: f16 = 0.01;
+const F16_APPROX_L3: f16 = 0.1;
+const F16_APPROX_L4: f16 = 0.5;
+
+/// Smallest number
+const TINY_BITS: u16 = 0x1;
+/// Next smallest number
+const TINY_UP_BITS: u16 = 0x2;
+/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
+const MAX_DOWN_BITS: u16 = 0x7bfe;
+/// Zeroed exponent, full significant
+const LARGEST_SUBNORMAL_BITS: u16 = 0x03ff;
+/// Exponent = 0b1, zeroed significand
+const SMALLEST_NORMAL_BITS: u16 = 0x0400;
+/// First pattern over the mantissa
+const NAN_MASK1: u16 = 0x02aa;
+/// Second pattern over the mantissa
+const NAN_MASK2: u16 = 0x0155;
+
+/// Compare by value
+#[allow(unused_macros)]
+macro_rules! assert_f16_eq {
+    ($a:expr, $b:expr) => {
+        let (l, r): (&f16, &f16) = (&$a, &$b);
+        assert_eq!(*l, *r, "\na: {:#018x}\nb: {:#018x}", l.to_bits(), r.to_bits())
+    };
+}
+
+/// Compare by representation
+#[allow(unused_macros)]
+macro_rules! assert_f16_biteq {
+    ($a:expr, $b:expr) => {
+        let (l, r): (&f16, &f16) = (&$a, &$b);
+        let lb = l.to_bits();
+        let rb = r.to_bits();
+        assert_eq!(
+            lb, rb,
+            "float {:?} is not bitequal to {:?}.\na: {:#018x}\nb: {:#018x}",
+            *l, *r, lb, rb
+        );
+    };
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index c713eefc72c93..2d7a9b7ce330a 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -283,6 +283,8 @@
 #![feature(doc_masked)]
 #![feature(doc_notable_trait)]
 #![feature(dropck_eyepatch)]
+#![feature(f128)]
+#![feature(f16)]
 #![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
 #![feature(lang_items)]
@@ -558,6 +560,10 @@ pub use core::u8;
 #[allow(deprecated, deprecated_in_future)]
 pub use core::usize;
 
+#[unstable(feature = "f128", issue = "116909")]
+pub mod f128;
+#[unstable(feature = "f16", issue = "116909")]
+pub mod f16;
 pub mod f32;
 pub mod f64;
 

From 311ad55c324959145fef4226bc615b8bc0e37e39 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross@umich.edu>
Date: Sat, 6 Apr 2024 19:08:54 -0400
Subject: [PATCH 4/4] Add primitive documentation for `f16` and `f128`

---
 library/core/src/primitive_docs.rs | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 15da4171bda21..e8e23f2a7ecc5 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1074,7 +1074,22 @@ mod prim_tuple {}
 #[doc(hidden)]
 impl<T> (T,) {}
 
+#[rustc_doc_primitive = "f16"]
+#[doc(alias = "half")]
+/// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008).
+///
+/// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many
+/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on
+/// half-precision values][wikipedia] for more information.
+///
+/// *[See also the `std::f16::consts` module](crate::f16::consts).*
+///
+/// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
+#[unstable(feature = "f16", issue = "116909")]
+mod prim_f16 {}
+
 #[rustc_doc_primitive = "f32"]
+#[doc(alias = "single")]
 /// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
 ///
 /// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
@@ -1143,6 +1158,7 @@ impl<T> (T,) {}
 mod prim_f32 {}
 
 #[rustc_doc_primitive = "f64"]
+#[doc(alias = "double")]
 /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
 ///
 /// This type is very similar to [`f32`], but has increased
@@ -1157,6 +1173,20 @@ mod prim_f32 {}
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_f64 {}
 
+#[rustc_doc_primitive = "f128"]
+#[doc(alias = "quad")]
+/// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008).
+///
+/// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice
+/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on
+/// quad-precision values][wikipedia] for more information.
+///
+/// *[See also the `std::f128::consts` module](crate::f128::consts).*
+///
+/// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
+#[unstable(feature = "f128", issue = "116909")]
+mod prim_f128 {}
+
 #[rustc_doc_primitive = "i8"]
 //
 /// The 8-bit signed integer type.