about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/codegen-llvm/autodiff/typetree.rs33
-rw-r--r--tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs7
-rw-r--r--tests/codegen-llvm/vec_pop_push_noop.rs5
-rw-r--r--tests/codegen-llvm/vecdeque_pop_push.rs5
-rw-r--r--tests/crashes/120175.rs1
-rw-r--r--tests/run-make/autodiff/type-trees/array-typetree/array.check4
-rw-r--r--tests/run-make/autodiff/type-trees/array-typetree/rmake.rs9
-rw-r--r--tests/run-make/autodiff/type-trees/array-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check8
-rw-r--r--tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check13
-rw-r--r--tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs36
-rw-r--r--tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs39
-rw-r--r--tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check2
-rw-r--r--tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs16
-rw-r--r--tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs23
-rw-r--r--tests/run-make/autodiff/type-trees/nott-flag/nott.check5
-rw-r--r--tests/run-make/autodiff/type-trees/nott-flag/rmake.rs30
-rw-r--r--tests/run-make/autodiff/type-trees/nott-flag/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/nott-flag/with_tt.check4
-rw-r--r--tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check3
-rw-r--r--tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs9
-rw-r--r--tests/run-make/autodiff/type-trees/recursion-typetree/test.rs100
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check4
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs12
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check4
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs12
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check4
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs12
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check4
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs12
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check4
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs12
-rw-r--r--tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs9
-rw-r--r--tests/run-make/autodiff/type-trees/slice-typetree/slice.check4
-rw-r--r--tests/run-make/autodiff/type-trees/slice-typetree/test.rs16
-rw-r--r--tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs9
-rw-r--r--tests/run-make/autodiff/type-trees/struct-typetree/struct.check4
-rw-r--r--tests/run-make/autodiff/type-trees/struct-typetree/test.rs22
-rw-r--r--tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs9
-rw-r--r--tests/run-make/autodiff/type-trees/tuple-typetree/test.rs15
-rw-r--r--tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check4
-rw-r--r--tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check2
-rw-r--r--tests/run-make/doctests-compilation-time-info/rmake.rs119
-rw-r--r--tests/run-make/doctests-merge/doctest-2024.stdout1
-rw-r--r--tests/run-make/doctests-merge/rmake.rs2
-rw-r--r--tests/run-make/linker-warning/rmake.rs2
-rw-r--r--tests/rustdoc-gui/src/lib2/lib.rs1
-rw-r--r--tests/rustdoc-ui/cfg-hide-show-conflict.rs3
-rw-r--r--tests/rustdoc-ui/cfg-hide-show-conflict.stderr14
-rw-r--r--tests/rustdoc-ui/doc-cfg.rs11
-rw-r--r--tests/rustdoc-ui/doc-cfg.stderr78
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout6
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout7
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.rs2
-rw-r--r--tests/rustdoc-ui/doctest/merged-ignore-no_run.rs2
-rw-r--r--tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout5
-rw-r--r--tests/rustdoc-ui/feature-gate-doc_cfg.rs6
-rw-r--r--tests/rustdoc-ui/feature-gate-doc_cfg.stderr63
-rw-r--r--tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs7
-rw-r--r--tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr13
-rw-r--r--tests/rustdoc-ui/invalid-cfg.rs2
-rw-r--r--tests/rustdoc-ui/lints/doc_cfg_hide.rs11
-rw-r--r--tests/rustdoc-ui/lints/doc_cfg_hide.stderr27
-rw-r--r--tests/rustdoc/doc-auto-cfg.rs2
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-hide.rs8
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs3
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-implicit.rs2
-rw-r--r--tests/rustdoc/doc_auto_cfg.rs77
-rw-r--r--tests/rustdoc/doc_auto_cfg_reexports.rs35
-rw-r--r--tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs2
-rw-r--r--tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs2
-rw-r--r--tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs2
-rw-r--r--tests/rustdoc/reexport/reexport-cfg.rs2
-rw-r--r--tests/rustdoc/target-feature.rs2
-rw-r--r--tests/ui/autodiff/flag_nott.rs19
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_weird.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-doc_cfg.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-macro-attr.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs3
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow.stderr4
-rw-r--r--tests/ui/hygiene/panic-location.run.stderr2
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr2
-rw-r--r--tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr22
-rw-r--r--tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs4
-rw-r--r--tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr4
-rw-r--r--tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr16
-rw-r--r--tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed20
-rw-r--r--tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs20
-rw-r--r--tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr36
-rw-r--r--tests/ui/reborrow/custom_mut.rs13
-rw-r--r--tests/ui/reborrow/custom_mut.stderr29
-rw-r--r--tests/ui/reborrow/custom_mut_coerce_shared.rs28
-rw-r--r--tests/ui/reborrow/custom_mut_coerce_shared.stderr19
-rw-r--r--tests/ui/reborrow/option_mut.rs7
-rw-r--r--tests/ui/reborrow/option_mut.stderr21
-rw-r--r--tests/ui/reborrow/option_mut_coerce_shared.rs11
-rw-r--r--tests/ui/reborrow/option_mut_coerce_shared.stderr23
-rw-r--r--tests/ui/reborrow/pin_mut.rs10
-rw-r--r--tests/ui/reborrow/pin_mut.stderr21
-rw-r--r--tests/ui/reborrow/pin_mut_coerce_shared.rs13
-rw-r--r--tests/ui/reborrow/pin_mut_coerce_shared.stderr19
-rw-r--r--tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs55
-rw-r--r--tests/ui/traits/next-solver/well-formed-in-relate.stderr2
-rw-r--r--tests/ui/union/union-unsafe.rs73
-rw-r--r--tests/ui/union/union-unsafe.stderr54
114 files changed, 1597 insertions, 132 deletions
diff --git a/tests/codegen-llvm/autodiff/typetree.rs b/tests/codegen-llvm/autodiff/typetree.rs
new file mode 100644
index 00000000000..1cb0c2fb68b
--- /dev/null
+++ b/tests/codegen-llvm/autodiff/typetree.rs
@@ -0,0 +1,33 @@
+//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+
+// Test that basic autodiff still works with our TypeTree infrastructure
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_simple, Duplicated, Active)]
+#[no_mangle]
+#[inline(never)]
+fn simple(x: &f64) -> f64 {
+    2.0 * x
+}
+
+// CHECK-LABEL: @simple
+// CHECK: fmul double
+
+// The derivative function should be generated normally
+// CHECK-LABEL: diffesimple
+// CHECK: fadd fast double
+
+fn main() {
+    let x = std::hint::black_box(3.0);
+    let output = simple(&x);
+    assert_eq!(6.0, output);
+
+    let mut df_dx = 0.0;
+    let output_ = d_simple(&x, &mut df_dx, 1.0);
+    assert_eq!(output, output_);
+    assert_eq!(2.0, df_dx);
+}
diff --git a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs
index 853a1ff36b1..a0b453fac8e 100644
--- a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs
+++ b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -Copt-level=3
+//@ revisions: new old
+//@ [old] max-llvm-major-version: 21
+//@ [new] min-llvm-version: 22
 
 #![crate_type = "lib"]
 
@@ -22,8 +25,8 @@ pub unsafe fn update(s: *mut State) {
     // CHECK-NOT: memcpy
     // CHECK-NOT: 75{{3|4}}
 
-    // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1
-    // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1
+    // old: %[[TAG:.+]] = load i8, ptr %s, align 1
+    // old-NEXT: trunc nuw i8 %[[TAG]] to i1
 
     // CHECK-NOT: load
     // CHECK-NOT: store
diff --git a/tests/codegen-llvm/vec_pop_push_noop.rs b/tests/codegen-llvm/vec_pop_push_noop.rs
index 3e375219fe0..977c220b3ba 100644
--- a/tests/codegen-llvm/vec_pop_push_noop.rs
+++ b/tests/codegen-llvm/vec_pop_push_noop.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -Copt-level=3
+//@ revisions: new old
+//@ [old] max-llvm-major-version: 21
+//@ [new] min-llvm-version: 22
 
 #![crate_type = "lib"]
 
@@ -7,7 +10,7 @@
 pub fn noop(v: &mut Vec<u8>) {
     // CHECK-NOT: grow_one
     // CHECK-NOT: call
-    // CHECK: tail call void @llvm.assume
+    // old: tail call void @llvm.assume
     // CHECK-NOT: grow_one
     // CHECK-NOT: call
     // CHECK: {{ret|[}]}}
diff --git a/tests/codegen-llvm/vecdeque_pop_push.rs b/tests/codegen-llvm/vecdeque_pop_push.rs
index 5afa1b2248b..6f9ad6674d6 100644
--- a/tests/codegen-llvm/vecdeque_pop_push.rs
+++ b/tests/codegen-llvm/vecdeque_pop_push.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -Copt-level=3
+//@ revisions: new old
+//@ [old] max-llvm-major-version: 21
+//@ [new] min-llvm-version: 22
 
 #![crate_type = "lib"]
 
@@ -8,7 +11,7 @@ use std::collections::VecDeque;
 // CHECK-LABEL: @noop_back(
 pub fn noop_back(v: &mut VecDeque<u8>) {
     // CHECK-NOT: grow
-    // CHECK: tail call void @llvm.assume
+    // old: tail call void @llvm.assume
     // CHECK-NOT: grow
     // CHECK: ret
     if let Some(x) = v.pop_back() {
diff --git a/tests/crashes/120175.rs b/tests/crashes/120175.rs
index e441454bed2..e06da5a8e0a 100644
--- a/tests/crashes/120175.rs
+++ b/tests/crashes/120175.rs
@@ -1,5 +1,6 @@
 //@ known-bug: #120175
 //@ needs-rustc-debug-assertions
+//@ ignore-apple (raw-dylib doesn't work on Apple targets yet)
 
 #![feature(extern_types)]
 #![feature(raw_dylib_elf)]
diff --git a/tests/run-make/autodiff/type-trees/array-typetree/array.check b/tests/run-make/autodiff/type-trees/array-typetree/array.check
new file mode 100644
index 00000000000..0d38bdec17e
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/array-typetree/array.check
@@ -0,0 +1,4 @@
+; Check that array TypeTree metadata is correctly generated  
+; Should show Float@double at each array element offset (0, 8, 16, 24, 32 bytes)
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_array{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs
new file mode 100644
index 00000000000..20b6a066906
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs
@@ -0,0 +1,9 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+    llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/array-typetree/test.rs b/tests/run-make/autodiff/type-trees/array-typetree/test.rs
new file mode 100644
index 00000000000..f54ebf5a4c7
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/array-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_array(arr: &[f64; 5]) -> f64 {
+    arr[0] + arr[1] + arr[2] + arr[3] + arr[4]
+}
+
+fn main() {
+    let arr = [1.0, 2.0, 3.0, 4.0, 5.0];
+    let mut d_arr = [0.0; 5];
+    let _result = d_test(&arr, &mut d_arr, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check
new file mode 100644
index 00000000000..0e6351ac4d3
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check
@@ -0,0 +1,8 @@
+; Check that enzyme_type attributes are present in the LLVM IR function definition
+; This verifies our TypeTree system correctly attaches metadata for Enzyme
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_memcpy({{.*}}"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@double}"
+
+; Check that llvm.memcpy exists (either call or declare)
+CHECK: {{(call|declare).*}}@llvm.memcpy
+
diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check
new file mode 100644
index 00000000000..ae70830297a
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check
@@ -0,0 +1,13 @@
+CHECK: force_memcpy
+
+CHECK: @llvm.memcpy.p0.p0.i64
+
+CHECK: test_memcpy - {[-1]:Float@double} |{[-1]:Pointer}:{}
+
+CHECK-DAG: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double, [-1,24]:Float@double}
+
+CHECK-DAG: load double{{.*}}: {[-1]:Float@double}
+
+CHECK-DAG: fmul double{{.*}}: {[-1]:Float@double}
+
+CHECK-DAG: fadd double{{.*}}: {[-1]:Float@double}
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs
new file mode 100644
index 00000000000..3c1029190c8
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs
@@ -0,0 +1,36 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+use std::ptr;
+
+#[inline(never)]
+fn force_memcpy(src: *const f64, dst: *mut f64, count: usize) {
+    unsafe {
+        ptr::copy_nonoverlapping(src, dst, count);
+    }
+}
+
+#[autodiff_reverse(d_test_memcpy, Duplicated, Active)]
+#[no_mangle]
+fn test_memcpy(input: &[f64; 128]) -> f64 {
+    let mut local_data = [0.0f64; 128];
+
+    // Use a separate function to prevent inlining and optimization
+    force_memcpy(input.as_ptr(), local_data.as_mut_ptr(), 128);
+
+    // Sum only first few elements to keep the computation simple
+    local_data[0] * local_data[0]
+        + local_data[1] * local_data[1]
+        + local_data[2] * local_data[2]
+        + local_data[3] * local_data[3]
+}
+
+fn main() {
+    let input = [1.0; 128];
+    let mut d_input = [0.0; 128];
+    let result = test_memcpy(&input);
+    let result_d = d_test_memcpy(&input, &mut d_input, 1.0);
+
+    assert_eq!(result, result_d);
+    println!("Memcpy test passed: result = {}", result);
+}
diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs
new file mode 100644
index 00000000000..b4c650330fe
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs
@@ -0,0 +1,39 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // First, compile to LLVM IR to check for enzyme_type attributes
+    let _ir_output = rustc()
+        .input("memcpy.rs")
+        .arg("-Zautodiff=Enable")
+        .arg("-Zautodiff=NoPostopt")
+        .opt_level("0")
+        .arg("--emit=llvm-ir")
+        .arg("-o")
+        .arg("main.ll")
+        .run();
+
+    // Then compile with TypeTree analysis output for the existing checks
+    let output = rustc()
+        .input("memcpy.rs")
+        .arg("-Zautodiff=Enable,PrintTAFn=test_memcpy")
+        .arg("-Zautodiff=NoPostopt")
+        .opt_level("3")
+        .arg("-Clto=fat")
+        .arg("-g")
+        .run();
+
+    let stdout = output.stdout_utf8();
+    let stderr = output.stderr_utf8();
+    let ir_content = rfs::read_to_string("main.ll");
+
+    rfs::write("memcpy.stdout", &stdout);
+    rfs::write("memcpy.stderr", &stderr);
+    rfs::write("main.ir", &ir_content);
+
+    llvm_filecheck().patterns("memcpy.check").stdin_buf(stdout).run();
+
+    llvm_filecheck().patterns("memcpy-ir.check").stdin_buf(ir_content).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check
new file mode 100644
index 00000000000..584f5840843
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check
@@ -0,0 +1,2 @@
+; Check that mixed struct with large array generates correct detailed type tree
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@float}"{{.*}}@test_mixed_struct{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,8]:Float@float}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs
new file mode 100644
index 00000000000..1c19963bc36
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs
@@ -0,0 +1,16 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    rustc()
+        .input("test.rs")
+        .arg("-Zautodiff=Enable")
+        .arg("-Zautodiff=NoPostopt")
+        .opt_level("0")
+        .emit("llvm-ir")
+        .run();
+
+    llvm_filecheck().patterns("mixed.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs
new file mode 100644
index 00000000000..7a734980e61
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs
@@ -0,0 +1,23 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[repr(C)]
+struct Container {
+    header: i64,
+    data: [f32; 1000],
+}
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+#[inline(never)]
+fn test_mixed_struct(container: &Container) -> f32 {
+    container.data[0] + container.data[999]
+}
+
+fn main() {
+    let container = Container { header: 42, data: [1.0; 1000] };
+    let mut d_container = Container { header: 0, data: [0.0; 1000] };
+    let result = d_test(&container, &mut d_container, 1.0);
+    std::hint::black_box(result);
+}
diff --git a/tests/run-make/autodiff/type-trees/nott-flag/nott.check b/tests/run-make/autodiff/type-trees/nott-flag/nott.check
new file mode 100644
index 00000000000..8d23e2ee319
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/nott-flag/nott.check
@@ -0,0 +1,5 @@
+// Check that enzyme_type attributes are NOT present when NoTT flag is used
+// This verifies the NoTT flag correctly disables TypeTree metadata
+
+CHECK: define{{.*}}@square
+CHECK-NOT: "enzyme_type"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs b/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs
new file mode 100644
index 00000000000..de540b990ca
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs
@@ -0,0 +1,30 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // Test with NoTT flag - should not generate TypeTree metadata
+    rustc()
+        .input("test.rs")
+        .arg("-Zautodiff=Enable,NoTT")
+        .emit("llvm-ir")
+        .arg("-o")
+        .arg("nott.ll")
+        .run();
+
+    // Test without NoTT flag - should generate TypeTree metadata
+    rustc()
+        .input("test.rs")
+        .arg("-Zautodiff=Enable")
+        .emit("llvm-ir")
+        .arg("-o")
+        .arg("with_tt.ll")
+        .run();
+
+    // Verify NoTT version does NOT have enzyme_type attributes
+    llvm_filecheck().patterns("nott.check").stdin_buf(rfs::read("nott.ll")).run();
+
+    // Verify TypeTree version DOES have enzyme_type attributes
+    llvm_filecheck().patterns("with_tt.check").stdin_buf(rfs::read("with_tt.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/nott-flag/test.rs b/tests/run-make/autodiff/type-trees/nott-flag/test.rs
new file mode 100644
index 00000000000..de3549c37c6
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/nott-flag/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_square, Duplicated, Active)]
+#[no_mangle]
+fn square(x: &f64) -> f64 {
+    x * x
+}
+
+fn main() {
+    let x = 2.0;
+    let mut dx = 0.0;
+    let _result = d_square(&x, &mut dx, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/nott-flag/with_tt.check b/tests/run-make/autodiff/type-trees/nott-flag/with_tt.check
new file mode 100644
index 00000000000..0b4c9119179
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/nott-flag/with_tt.check
@@ -0,0 +1,4 @@
+// Check that enzyme_type attributes are present when TypeTree is enabled
+// This verifies our TypeTree metadata attachment is working
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@square{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check b/tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check
new file mode 100644
index 00000000000..1960e7b816c
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check
@@ -0,0 +1,3 @@
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_deep{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}"
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_graph{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,8]:Integer, [-1,16]:Integer, [-1,24]:Float@double}"
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_node{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs
new file mode 100644
index 00000000000..78718f3a215
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs
@@ -0,0 +1,9 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+    llvm_filecheck().patterns("recursion.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/test.rs b/tests/run-make/autodiff/type-trees/recursion-typetree/test.rs
new file mode 100644
index 00000000000..9d40bec1bf1
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/recursion-typetree/test.rs
@@ -0,0 +1,100 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+// Self-referential struct to test recursion detection
+#[derive(Clone)]
+struct Node {
+    value: f64,
+    next: Option<Box<Node>>,
+}
+
+// Mutually recursive structs to test cycle detection
+#[derive(Clone)]
+struct GraphNodeA {
+    value: f64,
+    connections: Vec<GraphNodeB>,
+}
+
+#[derive(Clone)]
+struct GraphNodeB {
+    weight: f64,
+    target: Option<Box<GraphNodeA>>,
+}
+
+#[autodiff_reverse(d_test_node, Duplicated, Active)]
+#[no_mangle]
+fn test_node(node: &Node) -> f64 {
+    node.value * 2.0
+}
+
+#[autodiff_reverse(d_test_graph, Duplicated, Active)]
+#[no_mangle]
+fn test_graph(a: &GraphNodeA) -> f64 {
+    a.value * 3.0
+}
+
+// Simple depth test - deeply nested but not circular
+#[derive(Clone)]
+struct Level1 {
+    val: f64,
+    next: Option<Box<Level2>>,
+}
+#[derive(Clone)]
+struct Level2 {
+    val: f64,
+    next: Option<Box<Level3>>,
+}
+#[derive(Clone)]
+struct Level3 {
+    val: f64,
+    next: Option<Box<Level4>>,
+}
+#[derive(Clone)]
+struct Level4 {
+    val: f64,
+    next: Option<Box<Level5>>,
+}
+#[derive(Clone)]
+struct Level5 {
+    val: f64,
+    next: Option<Box<Level6>>,
+}
+#[derive(Clone)]
+struct Level6 {
+    val: f64,
+    next: Option<Box<Level7>>,
+}
+#[derive(Clone)]
+struct Level7 {
+    val: f64,
+    next: Option<Box<Level8>>,
+}
+#[derive(Clone)]
+struct Level8 {
+    val: f64,
+}
+
+#[autodiff_reverse(d_test_deep, Duplicated, Active)]
+#[no_mangle]
+fn test_deep(deep: &Level1) -> f64 {
+    deep.val * 4.0
+}
+
+fn main() {
+    let node = Node { value: 1.0, next: None };
+
+    let graph = GraphNodeA { value: 2.0, connections: vec![] };
+
+    let deep = Level1 { val: 5.0, next: None };
+
+    let mut d_node = Node { value: 0.0, next: None };
+
+    let mut d_graph = GraphNodeA { value: 0.0, connections: vec![] };
+
+    let mut d_deep = Level1 { val: 0.0, next: None };
+
+    let _result1 = d_test_node(&node, &mut d_node, 1.0);
+    let _result2 = d_test_graph(&graph, &mut d_graph, 1.0);
+    let _result3 = d_test_deep(&deep, &mut d_deep, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check
new file mode 100644
index 00000000000..23db64eea52
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check
@@ -0,0 +1,4 @@
+; Check that f128 TypeTree metadata is correctly generated
+; Should show Float@fp128 for f128 values and Pointer for references
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@fp128}"{{.*}}@test_f128{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@fp128}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs
new file mode 100644
index 00000000000..44320ecdd57
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs
@@ -0,0 +1,12 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // Compile with TypeTree enabled and emit LLVM IR
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+
+    // Check that f128 TypeTree metadata is correctly generated
+    llvm_filecheck().patterns("f128.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs
new file mode 100644
index 00000000000..5c71baa3e69
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff, f128)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_f128(x: &f128) -> f128 {
+    *x * *x
+}
+
+fn main() {
+    let x = 2.0_f128;
+    let mut dx = 0.0_f128;
+    let _result = d_test(&x, &mut dx, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check
new file mode 100644
index 00000000000..9adff68d36f
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check
@@ -0,0 +1,4 @@
+; Check that f16 TypeTree metadata is correctly generated
+; Should show Float@half for f16 values and Pointer for references
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@half}"{{.*}}@test_f16{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@half}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs
new file mode 100644
index 00000000000..0aebdbf5520
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs
@@ -0,0 +1,12 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // Compile with TypeTree enabled and emit LLVM IR
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+
+    // Check that f16 TypeTree metadata is correctly generated
+    llvm_filecheck().patterns("f16.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs
new file mode 100644
index 00000000000..6b68e8252f4
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff, f16)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_f16(x: &f16) -> f16 {
+    *x * *x
+}
+
+fn main() {
+    let x = 2.0_f16;
+    let mut dx = 0.0_f16;
+    let _result = d_test(&x, &mut dx, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check
new file mode 100644
index 00000000000..176630f57e8
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check
@@ -0,0 +1,4 @@
+; Check that f32 TypeTree metadata is correctly generated
+; Should show Float@float for f32 values and Pointer for references
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@float}"{{.*}}@test_f32{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@float}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs
new file mode 100644
index 00000000000..ee3ab753bf5
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs
@@ -0,0 +1,12 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // Compile with TypeTree enabled and emit LLVM IR
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+
+    // Check that f32 TypeTree metadata is correctly generated
+    llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs
new file mode 100644
index 00000000000..56c118399ee
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_f32(x: &f32) -> f32 {
+    x * x
+}
+
+fn main() {
+    let x = 2.0_f32;
+    let mut dx = 0.0_f32;
+    let _result = d_test(&x, &mut dx, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check
new file mode 100644
index 00000000000..929cd379694
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check
@@ -0,0 +1,4 @@
+; Check that f64 TypeTree metadata is correctly generated  
+; Should show Float@double for f64 values and Pointer for references
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_f64{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs
new file mode 100644
index 00000000000..5fac9b23bc8
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs
@@ -0,0 +1,12 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // Compile with TypeTree enabled and emit LLVM IR
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+
+    // Check that f64 TypeTree metadata is correctly generated
+    llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs
new file mode 100644
index 00000000000..235360b76b2
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_f64(x: &f64) -> f64 {
+    x * x
+}
+
+fn main() {
+    let x = 2.0_f64;
+    let mut dx = 0.0_f64;
+    let _result = d_test(&x, &mut dx, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check
new file mode 100644
index 00000000000..dee4aa5bbb6
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check
@@ -0,0 +1,4 @@
+; Check that i32 TypeTree metadata is correctly generated
+; Should show Integer for i32 values and Pointer for references
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Integer}"{{.*}}@test_i32{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Integer}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs
new file mode 100644
index 00000000000..a40fd55d88a
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs
@@ -0,0 +1,12 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    // Compile with TypeTree enabled and emit LLVM IR
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+
+    // Check that i32 TypeTree metadata is correctly generated
+    llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs
new file mode 100644
index 00000000000..249803c5d9f
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_i32(x: &i32) -> i32 {
+    x * x
+}
+
+fn main() {
+    let x = 5_i32;
+    let mut dx = 0_i32;
+    let _result = d_test(&x, &mut dx, 1);
+}
diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs
new file mode 100644
index 00000000000..b81fb50bf1a
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs
@@ -0,0 +1,9 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+    llvm_filecheck().patterns("slice.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/slice.check b/tests/run-make/autodiff/type-trees/slice-typetree/slice.check
new file mode 100644
index 00000000000..6543b616115
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/slice-typetree/slice.check
@@ -0,0 +1,4 @@
+; Check that slice TypeTree metadata is correctly generated
+; Should show Float@double for slice elements
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_slice{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/test.rs b/tests/run-make/autodiff/type-trees/slice-typetree/test.rs
new file mode 100644
index 00000000000..7117fa3844f
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/slice-typetree/test.rs
@@ -0,0 +1,16 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_slice(slice: &[f64]) -> f64 {
+    slice.iter().sum()
+}
+
+fn main() {
+    let arr = [1.0, 2.0, 3.0, 4.0, 5.0];
+    let slice = &arr[..];
+    let mut d_slice = [0.0; 5];
+    let _result = d_test(slice, &mut d_slice[..], 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs
new file mode 100644
index 00000000000..0af1b65ee18
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs
@@ -0,0 +1,9 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+    llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/struct.check b/tests/run-make/autodiff/type-trees/struct-typetree/struct.check
new file mode 100644
index 00000000000..54956317e1e
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/struct-typetree/struct.check
@@ -0,0 +1,4 @@
+; Check that struct TypeTree metadata is correctly generated
+; Should show Float@double at offsets 0, 8, 16 for Point struct fields
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_struct{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/test.rs b/tests/run-make/autodiff/type-trees/struct-typetree/test.rs
new file mode 100644
index 00000000000..cbe7b10e409
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/struct-typetree/test.rs
@@ -0,0 +1,22 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[repr(C)]
+struct Point {
+    x: f64,
+    y: f64,
+    z: f64,
+}
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_struct(point: &Point) -> f64 {
+    point.x + point.y * 2.0 + point.z * 3.0
+}
+
+fn main() {
+    let point = Point { x: 1.0, y: 2.0, z: 3.0 };
+    let mut d_point = Point { x: 0.0, y: 0.0, z: 0.0 };
+    let _result = d_test(&point, &mut d_point, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs
new file mode 100644
index 00000000000..76913828901
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs
@@ -0,0 +1,9 @@
+//@ needs-enzyme
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_filecheck, rfs, rustc};
+
+fn main() {
+    rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
+    llvm_filecheck().patterns("tuple.check").stdin_buf(rfs::read("test.ll")).run();
+}
diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/test.rs b/tests/run-make/autodiff/type-trees/tuple-typetree/test.rs
new file mode 100644
index 00000000000..32187b587a3
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/tuple-typetree/test.rs
@@ -0,0 +1,15 @@
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+#[autodiff_reverse(d_test, Duplicated, Active)]
+#[no_mangle]
+fn test_tuple(tuple: &(f64, f64, f64)) -> f64 {
+    tuple.0 + tuple.1 * 2.0 + tuple.2 * 3.0
+}
+
+fn main() {
+    let tuple = (1.0, 2.0, 3.0);
+    let mut d_tuple = (0.0, 0.0, 0.0);
+    let _result = d_test(&tuple, &mut d_tuple, 1.0);
+}
diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check b/tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check
new file mode 100644
index 00000000000..47647e78cc3
--- /dev/null
+++ b/tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check
@@ -0,0 +1,4 @@
+; Check that tuple TypeTree metadata is correctly generated
+; Should show Float@double at offsets 0, 8, 16 for (f64, f64, f64)
+
+CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_tuple{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double}"
\ No newline at end of file
diff --git a/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check
index dcf9508b69d..cdb70eb83fc 100644
--- a/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check
+++ b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check
@@ -1,7 +1,7 @@
 // CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
 // CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer}
 // CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer}
-// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !102, !noundef !{{[0-9]+}}: {}
+// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !noundef !{{[0-9]+}}: {}
 // CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 16, !dbg !{{[0-9]+}}: {[-1]:Pointer}
 // CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {}
 // CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, 0, !dbg !{{[0-9]+}}: {[-1]:Integer}
diff --git a/tests/run-make/doctests-compilation-time-info/rmake.rs b/tests/run-make/doctests-compilation-time-info/rmake.rs
new file mode 100644
index 00000000000..2bcf664923f
--- /dev/null
+++ b/tests/run-make/doctests-compilation-time-info/rmake.rs
@@ -0,0 +1,119 @@
+//@ ignore-cross-compile (needs to run doctests)
+
+use run_make_support::rfs::write;
+use run_make_support::{cwd, rustdoc};
+
+fn assert_presence_of_compilation_time_report(
+    content: &str,
+    success: bool,
+    should_contain_compile_time: bool,
+) {
+    let mut cmd = rustdoc();
+    let file = cwd().join("foo.rs");
+
+    write(&file, content);
+    cmd.input(&file).arg("--test").edition("2024").env("RUST_BACKTRACE", "0");
+    let output = if success { cmd.run() } else { cmd.run_fail() };
+
+    assert_eq!(
+        output
+            .stdout_utf8()
+            .split("all doctests ran in ")
+            .last()
+            .is_some_and(|s| s.contains("; merged doctests compilation took")),
+        should_contain_compile_time,
+    );
+}
+
+fn main() {
+    // Checking with only successful merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! let x = 12;
+//! ```",
+        true,
+        true,
+    );
+    // Checking with only failing merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! panic!();
+//! ```",
+        false,
+        true,
+    );
+    // Checking with mix of successful doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! let x = 12;
+//! ```
+//!
+//! ```compile_fail
+//! let x
+//! ```",
+        true,
+        true,
+    );
+    // Checking with mix of failing doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! panic!();
+//! ```
+//!
+//! ```compile_fail
+//! let x
+//! ```",
+        false,
+        true,
+    );
+    // Checking with mix of failing doctests (v2).
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! let x = 12;
+//! ```
+//!
+//! ```compile_fail
+//! let x = 12;
+//! ```",
+        false,
+        true,
+    );
+    // Checking with mix of failing doctests (v3).
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! panic!();
+//! ```
+//!
+//! ```compile_fail
+//! let x = 12;
+//! ```",
+        false,
+        true,
+    );
+    // Checking with successful non-merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```compile_fail
+//! let x
+//! ```",
+        true,
+        // If there is no merged doctests, then we should not display compilation time.
+        false,
+    );
+    // Checking with failing non-merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```compile_fail
+//! let x = 12;
+//! ```",
+        false,
+        // If there is no merged doctests, then we should not display compilation time.
+        false,
+    );
+}
diff --git a/tests/run-make/doctests-merge/doctest-2024.stdout b/tests/run-make/doctests-merge/doctest-2024.stdout
index 7da08d68faa..a7e139bbd23 100644
--- a/tests/run-make/doctests-merge/doctest-2024.stdout
+++ b/tests/run-make/doctests-merge/doctest-2024.stdout
@@ -5,3 +5,4 @@ test doctest.rs - init (line 8) ... ok
 
 test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
+all doctests ran in $TIME; merged doctests compilation took $TIME
diff --git a/tests/run-make/doctests-merge/rmake.rs b/tests/run-make/doctests-merge/rmake.rs
index 7893d4988eb..f2a1e8e13dd 100644
--- a/tests/run-make/doctests-merge/rmake.rs
+++ b/tests/run-make/doctests-merge/rmake.rs
@@ -20,6 +20,8 @@ fn test_and_compare(input_file: &str, stdout_file: &str, edition: &str, dep: &Pa
         .expected_file(stdout_file)
         .actual_text("output", output.stdout_utf8())
         .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME")
+        .normalize(r#"ran in \d+\.\d+s"#, "ran in $$TIME")
+        .normalize(r#"compilation took \d+\.\d+s"#, "compilation took $$TIME")
         .run();
 }
 
diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
index b0c40dd171d..a31b08d6c69 100644
--- a/tests/run-make/linker-warning/rmake.rs
+++ b/tests/run-make/linker-warning/rmake.rs
@@ -61,13 +61,13 @@ fn main() {
         diff()
             .expected_file("short-error.txt")
             .actual_text("(linker error)", out.stderr())
-            .normalize("libpanic_abort", "libpanic_unwind")
             .normalize(
                 regex::escape(
                     run_make_support::build_root().canonicalize().unwrap().to_str().unwrap(),
                 ),
                 "/build-root",
             )
+            .normalize("libpanic_abort", "libpanic_unwind")
             .normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"")
             .normalize(r#""[^"]*\/raw-dylibs""#, "\"/raw-dylibs\"")
             .run();
diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs
index 8db754f91ce..400488cbe85 100644
--- a/tests/rustdoc-gui/src/lib2/lib.rs
+++ b/tests/rustdoc-gui/src/lib2/lib.rs
@@ -1,7 +1,6 @@
 // ignore-tidy-linelength
 
 #![feature(doc_cfg)]
-#![feature(doc_auto_cfg)]
 
 pub mod another_folder;
 pub mod another_mod;
diff --git a/tests/rustdoc-ui/cfg-hide-show-conflict.rs b/tests/rustdoc-ui/cfg-hide-show-conflict.rs
new file mode 100644
index 00000000000..8e98b95c85b
--- /dev/null
+++ b/tests/rustdoc-ui/cfg-hide-show-conflict.rs
@@ -0,0 +1,3 @@
+#![feature(doc_cfg)]
+#![doc(auto_cfg(hide(target_os = "linux")))]
+#![doc(auto_cfg(show(windows, target_os = "linux")))] //~ ERROR
diff --git a/tests/rustdoc-ui/cfg-hide-show-conflict.stderr b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr
new file mode 100644
index 00000000000..22231e82cd7
--- /dev/null
+++ b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr
@@ -0,0 +1,14 @@
+error: same `cfg` was in `auto_cfg(hide(...))` and `auto_cfg(show(...))` on the same item
+  --> $DIR/cfg-hide-show-conflict.rs:3:31
+   |
+LL | #![doc(auto_cfg(show(windows, target_os = "linux")))]
+   |                               ^^^^^^^^^^^^^^^^^^^
+   |
+note: first change was here
+  --> $DIR/cfg-hide-show-conflict.rs:2:22
+   |
+LL | #![doc(auto_cfg(hide(target_os = "linux")))]
+   |                      ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/rustdoc-ui/doc-cfg.rs b/tests/rustdoc-ui/doc-cfg.rs
index 14943bbc341..d72643e2355 100644
--- a/tests/rustdoc-ui/doc-cfg.rs
+++ b/tests/rustdoc-ui/doc-cfg.rs
@@ -8,4 +8,15 @@
 //~^^ WARN unexpected `cfg` condition name: `bar`
 #[doc(cfg())] //~ ERROR
 #[doc(cfg(foo, bar))] //~ ERROR
+#[doc(auto_cfg(42))] //~ ERROR
+#[doc(auto_cfg(hide(true)))] //~ ERROR
+#[doc(auto_cfg(hide(42)))] //~ ERROR
+#[doc(auto_cfg(hide("a")))] //~ ERROR
+#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR
+#[doc(auto_cfg = 42)] //~ ERROR
+#[doc(auto_cfg = "a")] //~ ERROR
+// Shouldn't lint
+#[doc(auto_cfg(hide(windows)))]
+#[doc(auto_cfg(hide(feature = "windows")))]
+#[doc(auto_cfg(hide(foo)))]
 pub fn foo() {}
diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr
index 1233ee010de..49e8c324fac 100644
--- a/tests/rustdoc-ui/doc-cfg.stderr
+++ b/tests/rustdoc-ui/doc-cfg.stderr
@@ -1,26 +1,46 @@
-error: `cfg` predicate is not specified
-  --> $DIR/doc-cfg.rs:3:7
+error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`
+  --> $DIR/doc-cfg.rs:11:7
    |
-LL | #[doc(cfg(), cfg(foo, bar))]
-   |       ^^^^^ help: expected syntax is: `cfg(/* predicate */)`
+LL | #[doc(auto_cfg(42))]
+   |       ^^^^^^^^^^^^
+   |
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
-error: multiple `cfg` predicates are specified
-  --> $DIR/doc-cfg.rs:3:23
+error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
+  --> $DIR/doc-cfg.rs:12:21
    |
-LL | #[doc(cfg(), cfg(foo, bar))]
-   |                       ^^^
+LL | #[doc(auto_cfg(hide(true)))]
+   |                     ^^^^
 
-error: `cfg` predicate is not specified
-  --> $DIR/doc-cfg.rs:9:7
+error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
+  --> $DIR/doc-cfg.rs:13:21
    |
-LL | #[doc(cfg())]
-   |       ^^^^^ help: expected syntax is: `cfg(/* predicate */)`
+LL | #[doc(auto_cfg(hide(42)))]
+   |                     ^^
 
-error: multiple `cfg` predicates are specified
-  --> $DIR/doc-cfg.rs:10:16
+error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
+  --> $DIR/doc-cfg.rs:14:21
    |
-LL | #[doc(cfg(foo, bar))]
-   |                ^^^
+LL | #[doc(auto_cfg(hide("a")))]
+   |                     ^^^
+
+error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
+  --> $DIR/doc-cfg.rs:15:21
+   |
+LL | #[doc(auto_cfg(hide(foo::bar)))]
+   |                     ^^^^^^^^
+
+error: expected boolean for `#[doc(auto_cfg = ...)]`
+  --> $DIR/doc-cfg.rs:16:7
+   |
+LL | #[doc(auto_cfg = 42)]
+   |       ^^^^^^^^^^^^^
+
+error: expected boolean for `#[doc(auto_cfg = ...)]`
+  --> $DIR/doc-cfg.rs:17:7
+   |
+LL | #[doc(auto_cfg = "a")]
+   |       ^^^^^^^^^^^^^^
 
 warning: unexpected `cfg` condition name: `foo`
   --> $DIR/doc-cfg.rs:6:11
@@ -42,5 +62,29 @@ LL | #[doc(cfg(foo), cfg(bar))]
    = help: to expect this configuration use `--check-cfg=cfg(bar)`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
-error: aborting due to 4 previous errors; 2 warnings emitted
+error: `cfg` predicate is not specified
+  --> $DIR/doc-cfg.rs:3:7
+   |
+LL | #[doc(cfg(), cfg(foo, bar))]
+   |       ^^^^^ help: expected syntax is: `cfg(/* predicate */)`
+
+error: multiple `cfg` predicates are specified
+  --> $DIR/doc-cfg.rs:3:23
+   |
+LL | #[doc(cfg(), cfg(foo, bar))]
+   |                       ^^^
+
+error: `cfg` predicate is not specified
+  --> $DIR/doc-cfg.rs:9:7
+   |
+LL | #[doc(cfg())]
+   |       ^^^^^ help: expected syntax is: `cfg(/* predicate */)`
+
+error: multiple `cfg` predicates are specified
+  --> $DIR/doc-cfg.rs:10:16
+   |
+LL | #[doc(cfg(foo, bar))]
+   |                ^^^
+
+error: aborting due to 11 previous errors; 2 warnings emitted
 
diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout
index 0e2e30390ad..2ff7174577e 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout
+++ b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout
@@ -1,8 +1,8 @@
 
 running 3 tests
-test $DIR/doctest-output.rs - (line 12) ... ok
-test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok
-test $DIR/doctest-output.rs - foo::bar (line 22) ... ok
+test $DIR/doctest-output.rs - (line 14) ... ok
+test $DIR/doctest-output.rs - ExpandedStruct (line 30) ... ok
+test $DIR/doctest-output.rs - foo::bar (line 24) ... ok
 
 test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout
index 0e2e30390ad..20bfd7e7086 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout
+++ b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout
@@ -1,8 +1,9 @@
 
 running 3 tests
-test $DIR/doctest-output.rs - (line 12) ... ok
-test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok
-test $DIR/doctest-output.rs - foo::bar (line 22) ... ok
+test $DIR/doctest-output.rs - (line 14) ... ok
+test $DIR/doctest-output.rs - ExpandedStruct (line 30) ... ok
+test $DIR/doctest-output.rs - foo::bar (line 24) ... ok
 
 test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
+all doctests ran in $TIME; merged doctests compilation took $TIME
diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs
index 04bd1813b4c..943f59e8b15 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.rs
+++ b/tests/rustdoc-ui/doctest/doctest-output.rs
@@ -7,6 +7,8 @@
 //@[edition2024]compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
+//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
 //@ check-pass
 
 //! ```
diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
index 7dac64e6de4..f92bea74bfe 100644
--- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
+++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
@@ -2,6 +2,8 @@
 //@ compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
+//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
 //@ check-pass
 
 /// ```ignore (test)
diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
index a32da0aeb96..6714cdb0b80 100644
--- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
+++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
@@ -1,7 +1,8 @@
 
 running 2 tests
-test $DIR/merged-ignore-no_run.rs - ignored (line 7) ... ignored
-test $DIR/merged-ignore-no_run.rs - no_run (line 12) - compile ... ok
+test $DIR/merged-ignore-no_run.rs - ignored (line 9) ... ignored
+test $DIR/merged-ignore-no_run.rs - no_run (line 14) - compile ... ok
 
 test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME
 
+all doctests ran in $TIME; merged doctests compilation took $TIME
diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg.rs b/tests/rustdoc-ui/feature-gate-doc_cfg.rs
new file mode 100644
index 00000000000..b474a1524bc
--- /dev/null
+++ b/tests/rustdoc-ui/feature-gate-doc_cfg.rs
@@ -0,0 +1,6 @@
+#![doc(auto_cfg)] //~ ERROR
+#![doc(auto_cfg(false))] //~ ERROR
+#![doc(auto_cfg(true))] //~ ERROR
+#![doc(auto_cfg(hide(feature = "solecism")))] //~ ERROR
+#![doc(auto_cfg(show(feature = "bla")))] //~ ERROR
+#![doc(cfg(feature = "solecism"))] //~ ERROR
diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg.stderr b/tests/rustdoc-ui/feature-gate-doc_cfg.stderr
new file mode 100644
index 00000000000..68a86c1abb7
--- /dev/null
+++ b/tests/rustdoc-ui/feature-gate-doc_cfg.stderr
@@ -0,0 +1,63 @@
+error[E0658]: `#[doc(auto_cfg)]` is experimental
+  --> $DIR/feature-gate-doc_cfg.rs:1:1
+   |
+LL | #![doc(auto_cfg)]
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
+   = help: add `#![feature(doc_cfg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[doc(auto_cfg)]` is experimental
+  --> $DIR/feature-gate-doc_cfg.rs:2:1
+   |
+LL | #![doc(auto_cfg(false))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
+   = help: add `#![feature(doc_cfg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[doc(auto_cfg)]` is experimental
+  --> $DIR/feature-gate-doc_cfg.rs:3:1
+   |
+LL | #![doc(auto_cfg(true))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
+   = help: add `#![feature(doc_cfg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[doc(auto_cfg)]` is experimental
+  --> $DIR/feature-gate-doc_cfg.rs:4:1
+   |
+LL | #![doc(auto_cfg(hide(feature = "solecism")))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
+   = help: add `#![feature(doc_cfg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[doc(auto_cfg)]` is experimental
+  --> $DIR/feature-gate-doc_cfg.rs:5:1
+   |
+LL | #![doc(auto_cfg(show(feature = "bla")))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
+   = help: add `#![feature(doc_cfg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[doc(cfg)]` is experimental
+  --> $DIR/feature-gate-doc_cfg.rs:6:1
+   |
+LL | #![doc(cfg(feature = "solecism"))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
+   = help: add `#![feature(doc_cfg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs
deleted file mode 100644
index 17812018b9b..00000000000
--- a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#![doc(cfg_hide(test))]
-//~^ ERROR `#[doc(cfg_hide)]` is experimental
-
-#[cfg(not(test))]
-pub fn public_fn() {}
-#[cfg(test)]
-pub fn internal_use_only() {}
diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr
deleted file mode 100644
index 55135986ffe..00000000000
--- a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: `#[doc(cfg_hide)]` is experimental
-  --> $DIR/feature-gate-doc_cfg_hide.rs:1:1
-   |
-LL | #![doc(cfg_hide(test))]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
-   = help: add `#![feature(doc_cfg_hide)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/rustdoc-ui/invalid-cfg.rs b/tests/rustdoc-ui/invalid-cfg.rs
index d237b8605c0..aff36286c53 100644
--- a/tests/rustdoc-ui/invalid-cfg.rs
+++ b/tests/rustdoc-ui/invalid-cfg.rs
@@ -1,4 +1,4 @@
 #![feature(doc_cfg)]
 #[doc(cfg = "x")] //~ ERROR not followed by parentheses
 #[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates
-struct S {}
+pub struct S {}
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
index 9a8bce2a92a..397b21393e5 100644
--- a/tests/rustdoc-ui/lints/doc_cfg_hide.rs
+++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
@@ -1,7 +1,4 @@
-#![feature(doc_cfg_hide)]
-
-#![doc(cfg_hide = "test")] //~ ERROR
-#![doc(cfg_hide)] //~ ERROR
-
-#[doc(cfg_hide(doc))] //~ ERROR
-pub fn foo() {}
+#![feature(doc_cfg)]
+#![doc(auto_cfg(hide = "test"))] //~ ERROR
+#![doc(auto_cfg(hide))] //~ ERROR
+#![doc(auto_cfg(hide(not(windows))))] //~ ERROR
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
index 0c9d0879b0a..c63c8d607fa 100644
--- a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
+++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
@@ -1,27 +1,22 @@
-error: this attribute can only be applied at the crate level
-  --> $DIR/doc_cfg_hide.rs:6:7
+error: `#![doc(auto_cfg(hide(...)))]` expects a list of items
+  --> $DIR/doc_cfg_hide.rs:2:8
    |
-LL | #[doc(cfg_hide(doc))]
-   |       ^^^^^^^^^^^^^
+LL | #![doc(auto_cfg(hide = "test"))]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
    = note: `#[deny(invalid_doc_attributes)]` on by default
-help: to apply to the crate, use an inner attribute
-   |
-LL | #![doc(cfg_hide(doc))]
-   |  +
 
-error: `#[doc(cfg_hide(...))]` takes a list of attributes
+error: `#![doc(auto_cfg(hide(...)))]` expects a list of items
   --> $DIR/doc_cfg_hide.rs:3:8
    |
-LL | #![doc(cfg_hide = "test")]
-   |        ^^^^^^^^^^^^^^^^^
+LL | #![doc(auto_cfg(hide))]
+   |        ^^^^^^^^^^^^^^
 
-error: `#[doc(cfg_hide(...))]` takes a list of attributes
-  --> $DIR/doc_cfg_hide.rs:4:8
+error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
+  --> $DIR/doc_cfg_hide.rs:4:22
    |
-LL | #![doc(cfg_hide)]
-   |        ^^^^^^^^
+LL | #![doc(auto_cfg(hide(not(windows))))]
+   |                      ^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/rustdoc/doc-auto-cfg.rs b/tests/rustdoc/doc-auto-cfg.rs
index b3fe8922fd7..e56cf18d08a 100644
--- a/tests/rustdoc/doc-auto-cfg.rs
+++ b/tests/rustdoc/doc-auto-cfg.rs
@@ -1,4 +1,4 @@
-#![feature(doc_auto_cfg)]
+#![feature(doc_cfg)]
 #![crate_name = "foo"]
 
 //@ has foo/fn.foo.html
diff --git a/tests/rustdoc/doc-cfg/doc-cfg-hide.rs b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs
index ceb1f99fae0..e919206d3a4 100644
--- a/tests/rustdoc/doc-cfg/doc-cfg-hide.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs
@@ -1,7 +1,7 @@
 #![crate_name = "oud"]
-#![feature(doc_auto_cfg, doc_cfg, doc_cfg_hide)]
+#![feature(doc_cfg)]
 
-#![doc(cfg_hide(feature = "solecism"))]
+#![doc(auto_cfg(hide(feature = "solecism")))]
 
 //@ has 'oud/struct.Solecism.html'
 //@ count   - '//*[@class="stab portability"]' 0
@@ -18,7 +18,7 @@ pub struct Scribacious;
 
 //@ has 'oud/struct.Hyperdulia.html'
 //@ count   - '//*[@class="stab portability"]' 1
-//@ matches - '//*[@class="stab portability"]' 'crate feature hyperdulia'
+//@ matches - '//*[@class="stab portability"]' 'crate features hyperdulia only'
 //@ compile-flags:--cfg feature="hyperdulia"
 #[cfg(feature = "solecism")]
 #[cfg(feature = "hyperdulia")]
@@ -26,7 +26,7 @@ pub struct Hyperdulia;
 
 //@ has 'oud/struct.Oystercatcher.html'
 //@ count   - '//*[@class="stab portability"]' 1
-//@ matches - '//*[@class="stab portability"]' 'crate feature oystercatcher only'
+//@ matches - '//*[@class="stab portability"]' 'crate features oystercatcher only'
 //@ compile-flags:--cfg feature="oystercatcher"
 #[cfg(all(feature = "solecism", feature = "oystercatcher"))]
 pub struct Oystercatcher;
diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs
index b5b8d0f427b..9ae8b8fca4f 100644
--- a/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs
@@ -1,7 +1,8 @@
 //@ compile-flags:--cfg feature="worricow"
+#![feature(doc_cfg)]
 #![crate_name = "xenogenous"]
 
 //@ has 'xenogenous/struct.Worricow.html'
-//@ count   - '//*[@class="stab portability"]' 0
+//@ count   - '//*[@class="stab portability"]' 1
 #[cfg(feature = "worricow")]
 pub struct Worricow;
diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs
index 69b10867ee3..c092675ee5c 100644
--- a/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs
@@ -1,5 +1,5 @@
 #![crate_name = "funambulism"]
-#![feature(doc_auto_cfg, doc_cfg)]
+#![feature(doc_cfg)]
 
 //@ has 'funambulism/struct.Disorbed.html'
 //@ count   - '//*[@class="stab portability"]' 1
diff --git a/tests/rustdoc/doc_auto_cfg.rs b/tests/rustdoc/doc_auto_cfg.rs
new file mode 100644
index 00000000000..19ef174c177
--- /dev/null
+++ b/tests/rustdoc/doc_auto_cfg.rs
@@ -0,0 +1,77 @@
+// Test covering RFC 3631 features.
+
+#![crate_name = "foo"]
+#![feature(doc_cfg)]
+#![doc(auto_cfg(hide(feature = "hidden")))]
+
+//@ has 'foo/index.html'
+//@ !has - '//*[@class="stab portability"]' 'Non-moustache'
+//@ has - '//*[@class="stab portability"]' 'Non-pistache'
+//@ count - '//*[@class="stab portability"]' 1
+
+//@ has 'foo/m/index.html'
+//@ count - '//*[@title="Available on non-crate feature `hidden` only"]' 2
+#[cfg(not(feature = "hidden"))]
+pub mod m {
+    //@ count 'foo/m/struct.A.html' '//*[@class="stab portability"]' 0
+    pub struct A;
+
+    //@ has 'foo/m/inner/index.html' '//*[@class="stab portability"]' 'Available on non-crate feature hidden only.'
+    #[doc(auto_cfg(show(feature = "hidden")))]
+    pub mod inner {
+        //@ has 'foo/m/inner/struct.B.html' '//*[@class="stab portability"]' 'Available on non-crate feature hidden only.'
+        pub struct B;
+
+        //@ count 'foo/m/inner/struct.A.html' '//*[@class="stab portability"]' 0
+        #[doc(auto_cfg(hide(feature = "hidden")))]
+        pub struct A;
+    }
+
+    //@ has 'foo/m/struct.B.html' '//*[@class="stab portability"]' 'Available on non-crate feature hidden only.'
+    #[doc(auto_cfg(show(feature = "hidden")))]
+    pub struct B;
+}
+
+//@ count 'foo/n/index.html' '//*[@title="Available on non-crate feature `moustache` only"]' 3
+//@ count - '//dl/dt' 4
+#[cfg(not(feature = "moustache"))]
+#[doc(auto_cfg = false)]
+pub mod n {
+    // Should not have `moustache` listed.
+    //@ count 'foo/n/struct.X.html' '//*[@class="stab portability"]' 0
+    pub struct X;
+
+    // Should re-enable `auto_cfg` and make `moustache` listed.
+    //@ has 'foo/n/struct.Y.html' '//*[@class="stab portability"]' \
+    //  'Available on non-crate feature moustache only.'
+    #[doc(auto_cfg)]
+    pub struct Y;
+
+    // Should re-enable `auto_cfg` and make `moustache` listed for itself
+    // and for `Y`.
+    //@ has 'foo/n/inner/index.html' '//*[@class="stab portability"]' \
+    //  'Available on non-crate feature moustache only.'
+    #[doc(auto_cfg = true)]
+    pub mod inner {
+        //@ has 'foo/n/inner/struct.Y.html' '//*[@class="stab portability"]' \
+        //  'Available on non-crate feature moustache only.'
+        pub struct Y;
+    }
+
+    // Should re-enable `auto_cfg` and make `moustache` listed.
+    //@ has 'foo/n/struct.Z.html' '//*[@class="stab portability"]' \
+    //  'Available on non-crate feature moustache only.'
+    #[doc(auto_cfg(hide(feature = "hidden")))]
+    pub struct Z;
+}
+
+// Checking inheritance.
+//@ has 'foo/o/index.html' '//*[@class="stab portability"]' \
+//  'Available on non-crate feature pistache only.'
+#[doc(cfg(not(feature = "pistache")))]
+pub mod o {
+    //@ has 'foo/o/struct.A.html' '//*[@class="stab portability"]' \
+    //  'Available on non-crate feature pistache and non-crate feature tarte only.'
+    #[doc(cfg(not(feature = "tarte")))]
+    pub struct A;
+}
diff --git a/tests/rustdoc/doc_auto_cfg_reexports.rs b/tests/rustdoc/doc_auto_cfg_reexports.rs
new file mode 100644
index 00000000000..ecfe9aabcfe
--- /dev/null
+++ b/tests/rustdoc/doc_auto_cfg_reexports.rs
@@ -0,0 +1,35 @@
+// Checks that `cfg` are correctly applied on inlined reexports.
+
+#![crate_name = "foo"]
+#![feature(doc_cfg)]
+
+// Check with `std` item.
+//@ has 'foo/index.html' '//*[@class="stab portability"]' 'Non-moustache'
+//@ has 'foo/struct.C.html' '//*[@class="stab portability"]' \
+//      'Available on non-crate feature moustache only.'
+#[cfg(not(feature = "moustache"))]
+pub use std::cell::RefCell as C;
+
+// Check with local item.
+mod x {
+    pub struct B;
+}
+
+//@ has 'foo/index.html' '//*[@class="stab portability"]' 'Non-pistache'
+//@ has 'foo/struct.B.html' '//*[@class="stab portability"]' \
+//      'Available on non-crate feature pistache only.'
+#[cfg(not(feature = "pistache"))]
+pub use crate::x::B;
+
+// Now checking that `cfg`s are not applied on non-inlined reexports.
+pub mod pub_sub_mod {
+    //@ has 'foo/pub_sub_mod/index.html'
+    // There should be only only item with `cfg` note.
+    //@ count - '//*[@class="stab portability"]' 1
+    // And obviously the item should be "blabla".
+    //@ has - '//dt' 'blablaNon-pistache'
+    #[cfg(not(feature = "pistache"))]
+    pub fn blabla() {}
+
+    pub use self::blabla as another;
+}
diff --git a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
index f85d7b23637..f24ebcd52ac 100644
--- a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
+++ b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
@@ -1,6 +1,6 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/101129>.
 
-#![feature(doc_auto_cfg)]
+#![feature(doc_cfg)]
 #![crate_type = "lib"]
 #![crate_name = "foo"]
 
diff --git a/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs
index 76b25127a9c..f8ec4afc031 100644
--- a/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs
+++ b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs
@@ -1,7 +1,7 @@
 //@ aux-build: issue-113982-doc_auto_cfg-reexport-foreign.rs
 
 // https://github.com/rust-lang/rust/issues/113982
-#![feature(no_core, doc_auto_cfg)]
+#![feature(no_core, doc_cfg)]
 #![no_core]
 #![crate_name = "foo"]
 
diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs
index d0a2165ec8a..0aed2b0c462 100644
--- a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs
+++ b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs
@@ -2,7 +2,7 @@
 // the reexported item whereas glob reexports do with the `doc_auto_cfg` feature.
 
 #![crate_name = "foo"]
-#![feature(doc_auto_cfg)]
+#![feature(doc_cfg)]
 
 //@ has 'foo/index.html'
 // There are two items.
diff --git a/tests/rustdoc/reexport/reexport-cfg.rs b/tests/rustdoc/reexport/reexport-cfg.rs
index 73b66824316..b624e5acf50 100644
--- a/tests/rustdoc/reexport/reexport-cfg.rs
+++ b/tests/rustdoc/reexport/reexport-cfg.rs
@@ -2,7 +2,7 @@
 // include `cfg`s from the previous chained items.
 
 #![crate_name = "foo"]
-#![feature(doc_auto_cfg, doc_cfg)]
+#![feature(doc_cfg)]
 
 mod foo {
     #[cfg(not(feature = "foo"))]
diff --git a/tests/rustdoc/target-feature.rs b/tests/rustdoc/target-feature.rs
index 59a08a0ca94..f2686f81fbf 100644
--- a/tests/rustdoc/target-feature.rs
+++ b/tests/rustdoc/target-feature.rs
@@ -1,3 +1,5 @@
+#![feature(doc_cfg)]
+
 #![crate_name = "foo"]
 
 //@ has 'foo/index.html'
diff --git a/tests/ui/autodiff/flag_nott.rs b/tests/ui/autodiff/flag_nott.rs
new file mode 100644
index 00000000000..faa9949fe81
--- /dev/null
+++ b/tests/ui/autodiff/flag_nott.rs
@@ -0,0 +1,19 @@
+//@ compile-flags: -Zautodiff=Enable,NoTT
+//@ needs-enzyme
+//@ check-pass
+
+#![feature(autodiff)]
+
+use std::autodiff::autodiff_reverse;
+
+// Test that NoTT flag is accepted and doesn't cause compilation errors
+#[autodiff_reverse(d_square, Duplicated, Active)]
+fn square(x: &f64) -> f64 {
+    x * x
+}
+
+fn main() {
+    let x = 2.0;
+    let mut dx = 0.0;
+    let result = d_square(&x, &mut dx, 1.0);
+}
diff --git a/tests/ui/explicit-tail-calls/callee_is_weird.stderr b/tests/ui/explicit-tail-calls/callee_is_weird.stderr
index a4e5a38ce33..9a5da28b559 100644
--- a/tests/ui/explicit-tail-calls/callee_is_weird.stderr
+++ b/tests/ui/explicit-tail-calls/callee_is_weird.stderr
@@ -12,7 +12,7 @@ error: tail calls can only be performed with function definitions or pointers
 LL |     become (&mut &std::sync::Exclusive::new(f))()
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: callee has type `Exclusive<fn() {f}>`
+   = note: callee has type `&Exclusive<fn() {f}>`
 
 error: tail calls can only be performed with function definitions or pointers
   --> $DIR/callee_is_weird.rs:22:12
diff --git a/tests/ui/feature-gates/feature-gate-doc_cfg.rs b/tests/ui/feature-gates/feature-gate-doc_cfg.rs
index b12b8a10571..213a5a8c5a9 100644
--- a/tests/ui/feature-gates/feature-gate-doc_cfg.rs
+++ b/tests/ui/feature-gates/feature-gate-doc_cfg.rs
@@ -1,2 +1,2 @@
-#[doc(cfg(unix))] //~ ERROR: `#[doc(cfg)]` is experimental
+#[doc(cfg(unix))] //~ ERROR
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-macro-attr.stderr b/tests/ui/feature-gates/feature-gate-macro-attr.stderr
index b58418527c5..75bc93e8027 100644
--- a/tests/ui/feature-gates/feature-gate-macro-attr.stderr
+++ b/tests/ui/feature-gates/feature-gate-macro-attr.stderr
@@ -4,7 +4,7 @@ error[E0658]: `macro_rules!` attributes are unstable
 LL | macro_rules! myattr { attr() {} => {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
+   = note: see issue #143547 <https://github.com/rust-lang/rust/issues/143547> for more information
    = help: add `#![feature(macro_attr)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
diff --git a/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs b/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
index b4dc1fd4556..e37e405d1af 100644
--- a/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
+++ b/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
@@ -3,7 +3,7 @@ fn main() {
         //~^ ERROR non-exhaustive patterns: `usize::MAX..` not covered
         //~| NOTE pattern `usize::MAX..` not covered
         //~| NOTE the matched value is of type `usize`
-        //~| NOTE `usize` does not have a fixed maximum value
+        //~| NOTE `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
         0..=usize::MAX => {}
     }
 
@@ -11,7 +11,7 @@ fn main() {
         //~^ ERROR non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
         //~| NOTE patterns `..isize::MIN` and `isize::MAX..` not covered
         //~| NOTE the matched value is of type `isize`
-        //~| NOTE `isize` does not have fixed minimum and maximum values
+        //~| NOTE `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
         isize::MIN..=isize::MAX => {}
     }
 }
diff --git a/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr b/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
index c89dcaf727a..cfb00d6e741 100644
--- a/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
+++ b/tests/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
@@ -5,7 +5,7 @@ LL |     match 0usize {
    |           ^^^^^^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         0..=usize::MAX => {},
@@ -19,7 +19,7 @@ LL |     match 0isize {
    |           ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         isize::MIN..=isize::MAX => {},
diff --git a/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs
new file mode 100644
index 00000000000..c8ca4537089
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs
@@ -0,0 +1,3 @@
+use std::ops::CoerceShared; //~ ERROR  use of unstable library feature `reborrow`
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr
new file mode 100644
index 00000000000..dbbbcdf2fd5
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr
@@ -0,0 +1,13 @@
+error[E0658]: use of unstable library feature `reborrow`
+  --> $DIR/feature-gate-reborrow-coerce-shared.rs:1:5
+   |
+LL | use std::ops::CoerceShared;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #145612 <https://github.com/rust-lang/rust/issues/145612> for more information
+   = help: add `#![feature(reborrow)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-reborrow.rs b/tests/ui/feature-gates/feature-gate-reborrow.rs
index f016f6c6bfa..96eecfb28a1 100644
--- a/tests/ui/feature-gates/feature-gate-reborrow.rs
+++ b/tests/ui/feature-gates/feature-gate-reborrow.rs
@@ -1,3 +1,3 @@
-use std::marker::Reborrow; //~ ERROR  use of unstable library feature `reborrow`
+use std::ops::Reborrow; //~ ERROR  use of unstable library feature `reborrow`
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-reborrow.stderr b/tests/ui/feature-gates/feature-gate-reborrow.stderr
index 5e3033f3bf1..1224909f564 100644
--- a/tests/ui/feature-gates/feature-gate-reborrow.stderr
+++ b/tests/ui/feature-gates/feature-gate-reborrow.stderr
@@ -1,8 +1,8 @@
 error[E0658]: use of unstable library feature `reborrow`
   --> $DIR/feature-gate-reborrow.rs:1:5
    |
-LL | use std::marker::Reborrow;
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL | use std::ops::Reborrow;
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #145612 <https://github.com/rust-lang/rust/issues/145612> for more information
    = help: add `#![feature(reborrow)]` to the crate attributes to enable
diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr
index d28ab864183..bd74e96fd8c 100644
--- a/tests/ui/hygiene/panic-location.run.stderr
+++ b/tests/ui/hygiene/panic-location.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' ($TID) panicked at $DIR/panic-location.rs:LL:CC:
+thread 'main' ($TID) panicked at library/alloc/src/raw_vec/mod.rs:LL:CC:
 capacity overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index 08caff326c4..4d8f23bf7ca 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -387,6 +387,8 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
              where A: Tuple, F: Fn<A>, F: ?Sized;
            - impl<Args, F, A> Fn<Args> for Box<F, A>
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
+           - impl<F, Args> Fn<Args> for Exclusive<F>
+             where F: Sync, F: Fn<Args>, Args: Tuple;
 
 error[E0118]: no nominal type found for inherent implementation
   --> $DIR/where-allowed.rs:240:1
diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
index 7caee64a33f..099d6e86243 100644
--- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
+++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
@@ -5,7 +5,7 @@ LL |     match 0usize {
    |           ^^^^^^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         0..=usize::MAX => {},
@@ -19,7 +19,7 @@ LL |     match 0isize {
    |           ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         isize::MIN..=isize::MAX => {},
@@ -33,7 +33,7 @@ LL |     m!(0usize, 0..=usize::MAX);
    |        ^^^^^^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |         match $s { $($t)+ => {}, usize::MAX.. => todo!() }
@@ -46,7 +46,7 @@ LL |     m!(0usize, 0..5 | 5..=usize::MAX);
    |        ^^^^^^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |         match $s { $($t)+ => {}, usize::MAX.. => todo!() }
@@ -59,7 +59,7 @@ LL |     m!(0usize, 0..usize::MAX | usize::MAX);
    |        ^^^^^^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |         match $s { $($t)+ => {}, usize::MAX.. => todo!() }
@@ -72,7 +72,7 @@ LL |     m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::
    |        ^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered
    |
    = note: the matched value is of type `(usize, bool)`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |         match $s { $($t)+ => {}, (usize::MAX.., _) => todo!() }
@@ -85,7 +85,7 @@ LL |     m!(0isize, isize::MIN..=isize::MAX);
    |        ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL |         match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
@@ -98,7 +98,7 @@ LL |     m!(0isize, isize::MIN..5 | 5..=isize::MAX);
    |        ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL |         match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
@@ -111,7 +111,7 @@ LL |     m!(0isize, isize::MIN..=-1 | 0 | 1..=isize::MAX);
    |        ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL |         match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
@@ -124,7 +124,7 @@ LL |     m!(0isize, isize::MIN..isize::MAX | isize::MAX);
    |        ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL |         match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
@@ -137,7 +137,7 @@ LL |         (0isize, true),
    |         ^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered
    |
    = note: the matched value is of type `(isize, bool)`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL |         match $s { $($t)+ => {}, (..isize::MIN, _) | (isize::MAX.., _) => todo!() }
diff --git a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
index d60f479c0d1..6a0106134b5 100644
--- a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
+++ b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
@@ -4,7 +4,7 @@ fn main() {
         //~^ ERROR non-exhaustive patterns: `usize::MAX..` not covered
         //~| NOTE pattern `usize::MAX..` not covered
         //~| NOTE the matched value is of type `usize`
-        //~| NOTE `usize` does not have a fixed maximum value
+        //~| NOTE `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
         0..=usize::MAX => {}
     }
 
@@ -12,7 +12,7 @@ fn main() {
         //~^ ERROR non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
         //~| NOTE patterns `..isize::MIN` and `isize::MAX..` not covered
         //~| NOTE the matched value is of type `isize`
-        //~| NOTE `isize` does not have fixed minimum and maximum values
+        //~| NOTE `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
         isize::MIN..=isize::MAX => {}
     }
 }
diff --git a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
index 36743aa8102..fefe7f46ead 100644
--- a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
+++ b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
@@ -5,7 +5,7 @@ LL |     match 0usize {
    |           ^^^^^^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         0..=usize::MAX => {},
@@ -19,7 +19,7 @@ LL |     match 0isize {
    |           ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
    |
    = note: the matched value is of type `isize`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         isize::MIN..=isize::MAX => {},
diff --git a/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr
index c31411018bc..9d7b53093df 100644
--- a/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr
+++ b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr
@@ -5,7 +5,7 @@ LL |     match 0 {
    |           ^ pattern `usize::MAX..` not covered
    |
    = note: the matched value is of type `usize`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         1..=usize::MAX => (),
@@ -19,7 +19,7 @@ LL |     match (0usize, 0usize) {
    |           ^^^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered
    |
    = note: the matched value is of type `(usize, usize)`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         (1..=usize::MAX, 1..=usize::MAX) => (),
@@ -33,7 +33,7 @@ LL |     match (0isize, 0usize) {
    |           ^^^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered
    |
    = note: the matched value is of type `(isize, usize)`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         (isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
@@ -70,7 +70,7 @@ note: `Option<usize>` defined here
    |
    = note: not covered
    = note: the matched value is of type `Option<usize>`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         None => (),
@@ -93,7 +93,7 @@ note: `Option<Option<Option<usize>>>` defined here
    |
    = note: not covered
    = note: the matched value is of type `Option<Option<Option<usize>>>`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         None => (),
@@ -112,7 +112,7 @@ note: `A<usize>` defined here
 LL | struct A<T> {
    |        ^
    = note: the matched value is of type `A<usize>`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         A { a: 1..=usize::MAX } => (),
@@ -131,7 +131,7 @@ note: `B<isize, usize>` defined here
 LL | struct B<T, U>(T, U);
    |        ^
    = note: the matched value is of type `B<isize, usize>`
-   = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
+   = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
@@ -150,7 +150,7 @@ note: `B<isize, usize>` defined here
 LL | struct B<T, U>(T, U);
    |        ^
    = note: the matched value is of type `B<isize, usize>`
-   = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
+   = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         B(_, 1..=usize::MAX) => (),
diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed
new file mode 100644
index 00000000000..63cc3333b6b
--- /dev/null
+++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed
@@ -0,0 +1,20 @@
+#![allow(dead_code, unused_variables)]
+//@ run-rustfix
+pub use my_mod::Foo;
+//~^ NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+//~| NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+
+mod my_mod {
+    pub struct Foo(u32);
+
+    mod my_sub_mod {
+        fn my_func() {
+            let crate::my_mod::Foo(x) = crate::my_mod::Foo(42);
+            //~^ ERROR cannot initialize a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+            //~| ERROR cannot match against a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+        }
+    }
+}
+fn main() {}
diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs
new file mode 100644
index 00000000000..0b695f90654
--- /dev/null
+++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs
@@ -0,0 +1,20 @@
+#![allow(dead_code, unused_variables)]
+//@ run-rustfix
+pub use my_mod::Foo;
+//~^ NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+//~| NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+
+mod my_mod {
+    pub struct Foo(u32);
+
+    mod my_sub_mod {
+        fn my_func() {
+            let crate::Foo(x) = crate::Foo(42);
+            //~^ ERROR cannot initialize a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+            //~| ERROR cannot match against a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+        }
+    }
+}
+fn main() {}
diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr
new file mode 100644
index 00000000000..6ab324cb32f
--- /dev/null
+++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr
@@ -0,0 +1,36 @@
+error[E0423]: cannot initialize a tuple struct which contains private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:12:33
+   |
+LL |             let crate::Foo(x) = crate::Foo(42);
+   |                                 ^^^^^^^^^^
+   |
+note: the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:3:9
+   |
+LL | pub use my_mod::Foo;
+   |         ^^^^^^^^^^^
+help: the type can be constructed directly, because its fields are available from the current scope
+   |
+LL |             let crate::Foo(x) = crate::my_mod::Foo(42);
+   |                                        ++++++++
+
+error[E0532]: cannot match against a tuple struct which contains private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:12:17
+   |
+LL |             let crate::Foo(x) = crate::Foo(42);
+   |                 ^^^^^^^^^^
+   |
+note: the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:3:9
+   |
+LL | pub use my_mod::Foo;
+   |         ^^^^^^^^^^^
+help: the type can be constructed directly, because its fields are available from the current scope
+   |
+LL |             let crate::my_mod::Foo(x) = crate::Foo(42);
+   |                        ++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0423, E0532.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/tests/ui/reborrow/custom_mut.rs b/tests/ui/reborrow/custom_mut.rs
new file mode 100644
index 00000000000..1e7c4693238
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut.rs
@@ -0,0 +1,13 @@
+#![feature(reborrow)]
+use std::ops::Reborrow;
+
+struct CustomMut<'a, T>(&'a mut T);
+impl<'a, T> Reborrow for CustomMut<'a, T> {}
+
+fn method(a: CustomMut<'_, ()>) {}
+
+fn main() {
+    let a = CustomMut(&mut ());
+    let _ = method(a);
+    let _ = method(a); //~ERROR use of moved value: `a`
+}
diff --git a/tests/ui/reborrow/custom_mut.stderr b/tests/ui/reborrow/custom_mut.stderr
new file mode 100644
index 00000000000..3b3f47b62d6
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut.stderr
@@ -0,0 +1,29 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/custom_mut.rs:12:20
+   |
+LL |     let a = CustomMut(&mut ());
+   |         - move occurs because `a` has type `CustomMut<'_, ()>`, which does not implement the `Copy` trait
+LL |     let _ = method(a);
+   |                    - value moved here
+LL |     let _ = method(a);
+   |                    ^ value used here after move
+   |
+note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary
+  --> $DIR/custom_mut.rs:7:14
+   |
+LL | fn method(a: CustomMut<'_, ()>) {}
+   |    ------    ^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+note: if `CustomMut<'_, ()>` implemented `Clone`, you could clone the value
+  --> $DIR/custom_mut.rs:4:1
+   |
+LL | struct CustomMut<'a, T>(&'a mut T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |     let _ = method(a);
+   |                    - you could clone this value
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/reborrow/custom_mut_coerce_shared.rs b/tests/ui/reborrow/custom_mut_coerce_shared.rs
new file mode 100644
index 00000000000..e2d25835c09
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut_coerce_shared.rs
@@ -0,0 +1,28 @@
+#![feature(reborrow)]
+use std::ops::{CoerceShared, Reborrow};
+
+struct CustomMut<'a, T>(&'a mut T);
+impl<'a, T> Reborrow for CustomMut<'a, T> {}
+impl<'a, T> CoerceShared for CustomMut<'a, T> {
+    type Target = CustomRef<'a, T>;
+}
+
+struct CustomRef<'a, T>(&'a T);
+
+impl<'a, T> Clone for CustomRef<'a, T> {
+    fn clone(&self) -> Self {
+        Self(self.0)
+    }
+}
+impl<'a, T> Copy for CustomRef<'a, T> {}
+
+fn method(a: CustomRef<'_, ()>) {}  //~NOTE function defined here
+
+fn main() {
+    let a = CustomMut(&mut ());
+    method(a);
+    //~^ ERROR mismatched types
+    //~| NOTE expected `CustomRef<'_, ()>`, found `CustomMut<'_, ()>`
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE expected struct `CustomRef<'_, ()>`
+}
diff --git a/tests/ui/reborrow/custom_mut_coerce_shared.stderr b/tests/ui/reborrow/custom_mut_coerce_shared.stderr
new file mode 100644
index 00000000000..508651badc0
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut_coerce_shared.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/custom_mut_coerce_shared.rs:23:12
+   |
+LL |     method(a);
+   |     ------ ^ expected `CustomRef<'_, ()>`, found `CustomMut<'_, ()>`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected struct `CustomRef<'_, ()>`
+              found struct `CustomMut<'_, ()>`
+note: function defined here
+  --> $DIR/custom_mut_coerce_shared.rs:19:4
+   |
+LL | fn method(a: CustomRef<'_, ()>) {}
+   |    ^^^^^^ --------------------
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/reborrow/option_mut.rs b/tests/ui/reborrow/option_mut.rs
new file mode 100644
index 00000000000..04d8301772d
--- /dev/null
+++ b/tests/ui/reborrow/option_mut.rs
@@ -0,0 +1,7 @@
+fn method(a: Option<&mut ()>) {}
+
+fn main() {
+    let a = Some(&mut ());
+    let _ = method(a);
+    let _ = method(a); //~ERROR use of moved value: `a`
+}
diff --git a/tests/ui/reborrow/option_mut.stderr b/tests/ui/reborrow/option_mut.stderr
new file mode 100644
index 00000000000..d665e266079
--- /dev/null
+++ b/tests/ui/reborrow/option_mut.stderr
@@ -0,0 +1,21 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/option_mut.rs:6:20
+   |
+LL |     let a = Some(&mut ());
+   |         - move occurs because `a` has type `Option<&mut ()>`, which does not implement the `Copy` trait
+LL |     let _ = method(a);
+   |                    - value moved here
+LL |     let _ = method(a);
+   |                    ^ value used here after move
+   |
+note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary
+  --> $DIR/option_mut.rs:1:14
+   |
+LL | fn method(a: Option<&mut ()>) {}
+   |    ------    ^^^^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/reborrow/option_mut_coerce_shared.rs b/tests/ui/reborrow/option_mut_coerce_shared.rs
new file mode 100644
index 00000000000..95d33ed94dd
--- /dev/null
+++ b/tests/ui/reborrow/option_mut_coerce_shared.rs
@@ -0,0 +1,11 @@
+fn method(a: Option<&()>) {}  //~NOTE function defined here
+
+fn main() {
+    let a = Some(&mut ());
+    method(a);
+    //~^ ERROR mismatched types
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE types differ in mutability
+    //~| NOTE expected enum `Option<&()>`
+    //~| NOTE    found enum `Option<&mut ()>`
+}
diff --git a/tests/ui/reborrow/option_mut_coerce_shared.stderr b/tests/ui/reborrow/option_mut_coerce_shared.stderr
new file mode 100644
index 00000000000..6ca1a237461
--- /dev/null
+++ b/tests/ui/reborrow/option_mut_coerce_shared.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/option_mut_coerce_shared.rs:5:12
+   |
+LL |     method(a);
+   |     ------ ^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected enum `Option<&()>`
+              found enum `Option<&mut ()>`
+note: function defined here
+  --> $DIR/option_mut_coerce_shared.rs:1:4
+   |
+LL | fn method(a: Option<&()>) {}
+   |    ^^^^^^ --------------
+help: try using `.as_deref()` to convert `Option<&mut ()>` to `Option<&()>`
+   |
+LL |     method(a.as_deref());
+   |             +++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/reborrow/pin_mut.rs b/tests/ui/reborrow/pin_mut.rs
new file mode 100644
index 00000000000..959cb14f8c9
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut.rs
@@ -0,0 +1,10 @@
+use std::pin::Pin;
+
+fn method(a: Pin<&mut ()>) {}
+
+fn main() {
+    let a = &mut ();
+    let a = Pin::new(a);
+    let _ = method(a);
+    let _ = method(a); //~ERROR use of moved value: `a`
+}
diff --git a/tests/ui/reborrow/pin_mut.stderr b/tests/ui/reborrow/pin_mut.stderr
new file mode 100644
index 00000000000..64e3f603e11
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut.stderr
@@ -0,0 +1,21 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/pin_mut.rs:9:20
+   |
+LL |     let a = Pin::new(a);
+   |         - move occurs because `a` has type `Pin<&mut ()>`, which does not implement the `Copy` trait
+LL |     let _ = method(a);
+   |                    - value moved here
+LL |     let _ = method(a);
+   |                    ^ value used here after move
+   |
+note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary
+  --> $DIR/pin_mut.rs:3:14
+   |
+LL | fn method(a: Pin<&mut ()>) {}
+   |    ------    ^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/reborrow/pin_mut_coerce_shared.rs b/tests/ui/reborrow/pin_mut_coerce_shared.rs
new file mode 100644
index 00000000000..06af0b765d0
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut_coerce_shared.rs
@@ -0,0 +1,13 @@
+use std::pin::Pin;
+
+fn method(a: Pin<&()>) {}  //~NOTE function defined here
+
+fn main() {
+    let a = &mut ();
+    let a = Pin::new(a);
+    method(a);
+    //~^ ERROR mismatched types
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE types differ in mutability
+    //~| NOTE expected struct `Pin<&()>`
+}
diff --git a/tests/ui/reborrow/pin_mut_coerce_shared.stderr b/tests/ui/reborrow/pin_mut_coerce_shared.stderr
new file mode 100644
index 00000000000..74ecf4de4c7
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut_coerce_shared.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/pin_mut_coerce_shared.rs:8:12
+   |
+LL |     method(a);
+   |     ------ ^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected struct `Pin<&()>`
+              found struct `Pin<&mut ()>`
+note: function defined here
+  --> $DIR/pin_mut_coerce_shared.rs:3:4
+   |
+LL | fn method(a: Pin<&()>) {}
+   |    ^^^^^^ -----------
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs b/tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs
new file mode 100644
index 00000000000..9a33ae53644
--- /dev/null
+++ b/tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs
@@ -0,0 +1,55 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// A regression test for trait-system-refactor-initiative#232. We've
+// previously incorrectly rebased provisional cache entries even if
+// the cycle head didn't reach a fixpoint as it did not depend on any
+// cycles itself.
+//
+// Just because the result of a goal does not depend on its own provisional
+// result, it does not mean its nested goals don't depend on its result.
+struct B;
+struct C;
+struct D;
+
+pub trait Trait {
+    type Output;
+}
+macro_rules! k {
+    ($t:ty) => {
+        <$t as Trait>::Output
+    };
+}
+
+trait CallB<T1, T2> {
+    type Output;
+    type Return;
+}
+
+trait CallC<T1> {
+    type Output;
+    type Return;
+}
+
+trait CallD<T1, T2> {
+    type Output;
+}
+
+fn foo<X, Y>()
+where
+    X: Trait,
+    Y: Trait,
+    D: CallD<k![X], k![Y]>,
+    C: CallC<<D as CallD<k![X], k![Y]>>::Output>,
+    <C as CallC<<D as CallD<k![X], k![Y]>>::Output>>::Output: Trait,
+    B: CallB<
+            <C as CallC<<D as CallD<k![X], k![Y]>>::Output>>::Return,
+            <C as CallC<<D as CallD<k![X], k![Y]>>::Output>>::Output,
+        >,
+    <B as CallB<
+        <C as CallC<<D as CallD<k![X], k![Y]>>::Output>>::Return,
+        <C as CallC<<D as CallD<k![X], k![Y]>>::Output>>::Output,
+    >>::Output: Trait<Output = ()>,
+{
+}
+fn main() {}
diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr
index 5294a072d31..d79e465b3e3 100644
--- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr
+++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr
@@ -12,6 +12,8 @@ LL |     x = unconstrained_map();
              where A: Tuple, F: Fn<A>, F: ?Sized;
            - impl<Args, F, A> Fn<Args> for Box<F, A>
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
+           - impl<F, Args> Fn<Args> for Exclusive<F>
+             where F: Sync, F: Fn<Args>, Args: Tuple;
 note: required by a bound in `unconstrained_map`
   --> $DIR/well-formed-in-relate.rs:21:25
    |
diff --git a/tests/ui/union/union-unsafe.rs b/tests/ui/union/union-unsafe.rs
index bd3946686be..beb074f4e8e 100644
--- a/tests/ui/union/union-unsafe.rs
+++ b/tests/ui/union/union-unsafe.rs
@@ -1,5 +1,6 @@
 use std::cell::RefCell;
 use std::mem::ManuallyDrop;
+use std::ops::Deref;
 
 union U1 {
     a: u8,
@@ -17,6 +18,10 @@ union U4<T: Copy> {
     a: T,
 }
 
+union U5 {
+    a: usize,
+}
+
 union URef {
     p: &'static mut i32,
 }
@@ -31,6 +36,20 @@ fn deref_union_field(mut u: URef) {
     *(u.p) = 13; //~ ERROR access to union field is unsafe
 }
 
+union A {
+    a: usize,
+    b: &'static &'static B,
+}
+
+union B {
+    c: usize,
+}
+
+fn raw_deref_union_field(mut u: URef) {
+    // This is unsafe because we first dereference u.p (reading uninitialized memory)
+    let _p = &raw const *(u.p); //~ ERROR access to union field is unsafe
+}
+
 fn assign_noncopy_union_field(mut u: URefCell) {
     u.a = (ManuallyDrop::new(RefCell::new(0)), 1); // OK (assignment does not drop)
     u.a.0 = ManuallyDrop::new(RefCell::new(0)); // OK (assignment does not drop)
@@ -57,6 +76,20 @@ fn main() {
     let a = u1.a; //~ ERROR access to union field is unsafe
     u1.a = 11; // OK
 
+    let mut u2 = U1 { a: 10 };
+    let a = &raw mut u2.a; // OK
+    unsafe { *a = 3 };
+
+    let mut u3 = U1 { a: 10 };
+    let a = std::ptr::addr_of_mut!(u3.a); // OK
+    unsafe { *a = 14 };
+
+    let u4 = U5 { a: 2 };
+    let vec = vec![1, 2, 3];
+    // This is unsafe because we read u4.a (potentially uninitialized memory)
+    // to use as an array index
+    let _a = &raw const vec[u4.a]; //~ ERROR access to union field is unsafe
+
     let U1 { a } = u1; //~ ERROR access to union field is unsafe
     if let U1 { a: 12 } = u1 {} //~ ERROR access to union field is unsafe
     if let Some(U1 { a: 13 }) = Some(u1) {} //~ ERROR access to union field is unsafe
@@ -73,4 +106,44 @@ fn main() {
     let mut u3 = U3 { a: ManuallyDrop::new(String::from("old")) }; // OK
     u3.a = ManuallyDrop::new(String::from("new")); // OK (assignment does not drop)
     *u3.a = String::from("new"); //~ ERROR access to union field is unsafe
+
+    let mut unions = [U1 { a: 1 }, U1 { a: 2 }];
+
+    // Array indexing + union field raw borrow - should be OK
+    let ptr = &raw mut unions[0].a; // OK
+    let ptr2 = &raw const unions[1].a; // OK
+
+    let a = A { a: 0 };
+    let _p = &raw const (**a.b).c; //~ ERROR access to union field is unsafe
+
+    arbitrary_deref();
+}
+
+// regression test for https://github.com/rust-lang/rust/pull/141469#discussion_r2312546218
+fn arbitrary_deref() {
+    use std::ops::Deref;
+
+    union A {
+        a: usize,
+        b: B,
+    }
+
+    #[derive(Copy, Clone)]
+    struct B(&'static str);
+
+    impl Deref for B {
+        type Target = C;
+
+        fn deref(&self) -> &C {
+            println!("{:?}", self.0);
+            &C { c: 0 }
+        }
+    }
+
+    union C {
+        c: usize,
+    }
+
+    let a = A { a: 0 };
+    let _p = &raw const (*a.b).c; //~ ERROR access to union field is unsafe
 }
diff --git a/tests/ui/union/union-unsafe.stderr b/tests/ui/union/union-unsafe.stderr
index 82b3f897167..01f4d95eb64 100644
--- a/tests/ui/union/union-unsafe.stderr
+++ b/tests/ui/union/union-unsafe.stderr
@@ -1,5 +1,5 @@
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:31:6
+  --> $DIR/union-unsafe.rs:36:6
    |
 LL |     *(u.p) = 13;
    |      ^^^^^ access to union field
@@ -7,7 +7,15 @@ LL |     *(u.p) = 13;
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:43:6
+  --> $DIR/union-unsafe.rs:50:26
+   |
+LL |     let _p = &raw const *(u.p);
+   |                          ^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:62:6
    |
 LL |     *u3.a = T::default();
    |      ^^^^ access to union field
@@ -15,7 +23,7 @@ LL |     *u3.a = T::default();
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:49:6
+  --> $DIR/union-unsafe.rs:68:6
    |
 LL |     *u3.a = T::default();
    |      ^^^^ access to union field
@@ -23,7 +31,7 @@ LL |     *u3.a = T::default();
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:57:13
+  --> $DIR/union-unsafe.rs:76:13
    |
 LL |     let a = u1.a;
    |             ^^^^ access to union field
@@ -31,7 +39,15 @@ LL |     let a = u1.a;
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:60:14
+  --> $DIR/union-unsafe.rs:91:29
+   |
+LL |     let _a = &raw const vec[u4.a];
+   |                             ^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:93:14
    |
 LL |     let U1 { a } = u1;
    |              ^ access to union field
@@ -39,7 +55,7 @@ LL |     let U1 { a } = u1;
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:61:20
+  --> $DIR/union-unsafe.rs:94:20
    |
 LL |     if let U1 { a: 12 } = u1 {}
    |                    ^^ access to union field
@@ -47,7 +63,7 @@ LL |     if let U1 { a: 12 } = u1 {}
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:62:25
+  --> $DIR/union-unsafe.rs:95:25
    |
 LL |     if let Some(U1 { a: 13 }) = Some(u1) {}
    |                         ^^ access to union field
@@ -55,7 +71,7 @@ LL |     if let Some(U1 { a: 13 }) = Some(u1) {}
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:67:6
+  --> $DIR/union-unsafe.rs:100:6
    |
 LL |     *u2.a = String::from("new");
    |      ^^^^ access to union field
@@ -63,7 +79,7 @@ LL |     *u2.a = String::from("new");
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:71:6
+  --> $DIR/union-unsafe.rs:104:6
    |
 LL |     *u3.a = 1;
    |      ^^^^ access to union field
@@ -71,13 +87,29 @@ LL |     *u3.a = 1;
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:75:6
+  --> $DIR/union-unsafe.rs:108:6
    |
 LL |     *u3.a = String::from("new");
    |      ^^^^ access to union field
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-error: aborting due to 10 previous errors
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:117:28
+   |
+LL |     let _p = &raw const (**a.b).c;
+   |                            ^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:148:27
+   |
+LL |     let _p = &raw const (*a.b).c;
+   |                           ^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 14 previous errors
 
 For more information about this error, try `rustc --explain E0133`.