about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBoxy <rust@boxyuwu.dev>2025-04-14 13:41:18 +0100
committerBoxy <rust@boxyuwu.dev>2025-05-22 11:39:49 +0100
commitcc10370fc8b2b412600aa846e3046b8a09dda7ca (patch)
tree143426ba52b215b8b9693e20bafb7140d509203d
parent43162597292f904ff5ff47e251ba40fb9ae41ded (diff)
downloadrust-cc10370fc8b2b412600aa846e3046b8a09dda7ca.tar.gz
rust-cc10370fc8b2b412600aa846e3046b8a09dda7ca.zip
Reviews
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs38
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs15
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs2
-rw-r--r--tests/ui/repeat-expr/copy-check-inference-side-effects.rs2
4 files changed, 32 insertions, 25 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 124b6e80fd4..4da014dd236 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -108,8 +108,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let deferred_repeat_expr_checks = deferred_repeat_expr_checks
             .drain(..)
             .flat_map(|(element, element_ty, count)| {
-                // Actual constants as the repeat element get inserted repeatedly instead of getting copied via Copy
-                // so we don't need to attempt to structurally resolve the repeat count which may unnecessarily error.
+                // Actual constants as the repeat element are inserted repeatedly instead
+                // of being copied via `Copy`, so we don't need to attempt to structurally
+                // resolve the repeat count which may unnecessarily error.
                 match &element.kind {
                     hir::ExprKind::ConstBlock(..) => return None,
                     hir::ExprKind::Path(qpath) => {
@@ -121,23 +122,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     _ => {}
                 }
 
-                // We want to emit an error if the const is not structurally resolveable as otherwise
-                // we can find up conservatively proving `Copy` which may infer the repeat expr count
-                // to something that never required `Copy` in the first place.
+                // We want to emit an error if the const is not structurally resolveable
+                // as otherwise we can wind up conservatively proving `Copy` which may
+                // infer the repeat expr count to something that never required `Copy` in
+                // the first place.
                 let count = self
                     .structurally_resolve_const(element.span, self.normalize(element.span, count));
 
-                // Avoid run on "`NotCopy: Copy` is not implemented" errors when the repeat expr count
-                // is erroneous/unknown. The user might wind up specifying a repeat count of 0/1.
+                // Avoid run on "`NotCopy: Copy` is not implemented" errors when the
+                // repeat expr count is erroneous/unknown. The user might wind up
+                // specifying a repeat count of 0/1.
                 if count.references_error() {
                     return None;
                 }
 
                 Some((element, element_ty, count))
             })
-            // We collect to force the side effects of structurally resolving the repeat count to happen in one
-            // go, to avoid side effects from proving `Copy` affecting whether repeat counts are known or not.
-            // If we did not do this we would get results that depend on the order that we evaluate each repeat
+            // We collect to force the side effects of structurally resolving the repeat
+            // count to happen in one go, to avoid side effects from proving `Copy`
+            // affecting whether repeat counts are known or not. If we did not do this we
+            // would get results that depend on the order that we evaluate each repeat
             // expr's `Copy` check.
             .collect::<Vec<_>>();
 
@@ -171,14 +175,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         for (element, element_ty, count) in deferred_repeat_expr_checks {
             match count.kind() {
-                ty::ConstKind::Value(val)
-                    if val.try_to_target_usize(self.tcx).is_none_or(|count| count > 1) =>
-                {
-                    enforce_copy_bound(element, element_ty)
+                ty::ConstKind::Value(val) => {
+                    if val.try_to_target_usize(self.tcx).is_none_or(|count| count > 1) {
+                        enforce_copy_bound(element, element_ty)
+                    } else {
+                        // If the length is 0 or 1 we don't actually copy the element, we either don't create it
+                        // or we just use the one value.
+                    }
                 }
-                // If the length is 0 or 1 we don't actually copy the element, we either don't create it
-                // or we just use the one value.
-                ty::ConstKind::Value(_) => (),
 
                 // If the length is a generic parameter or some rigid alias then conservatively
                 // require `element_ty: Copy` as it may wind up being `>1` after monomorphization.
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 161f5e981d4..ba83db7eebd 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -195,13 +195,16 @@ fn typeck_with_inspect<'tcx>(
         fcx.write_ty(id, expected_type);
     };
 
-    // Whether to check repeat exprs before/after inference fallback is somewhat arbitrary of a decision
-    // as neither option is strictly more permissive than the other. However, we opt to check repeat exprs
-    // first as errors from not having inferred array lengths yet seem less confusing than errors from inference
-    // fallback arbitrarily inferring something incompatible with `Copy` inference side effects.
+    // Whether to check repeat exprs before/after inference fallback is somewhat
+    // arbitrary of a decision as neither option is strictly more permissive than
+    // the other. However, we opt to check repeat exprs first as errors from not
+    // having inferred array lengths yet seem less confusing than errors from inference
+    // fallback arbitrarily inferring something incompatible with `Copy` inference
+    // side effects.
     //
-    // This should also be forwards compatible with moving repeat expr checks to a custom goal kind or using
-    // marker traits in the future.
+    // FIXME(#140855): This should also be forwards compatible with moving
+    // repeat expr checks to a custom goal kind or using marker traits in
+    // the future.
     fcx.check_repeat_exprs();
 
     fcx.type_inference_fallback();
diff --git a/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
index b81997a3c9f..4fbb8f0a00c 100644
--- a/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
+++ b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
@@ -5,7 +5,7 @@
 // checked before integer fallback occurs. We accomplish this by having the repeat
 // expr check allow inference progress on an ambiguous goal, where the ambiguous goal
 // would fail if the inference variable was fallen back to `i32`. This test will
-// pass if wecheck repeat exprs before integer fallback.
+// pass if we check repeat exprs before integer fallback.
 
 use std::marker::PhantomData;
 struct Foo<T>(PhantomData<T>);
diff --git a/tests/ui/repeat-expr/copy-check-inference-side-effects.rs b/tests/ui/repeat-expr/copy-check-inference-side-effects.rs
index 416a20169fb..4e3bfdead26 100644
--- a/tests/ui/repeat-expr/copy-check-inference-side-effects.rs
+++ b/tests/ui/repeat-expr/copy-check-inference-side-effects.rs
@@ -12,7 +12,7 @@ impl Copy for Foo<1> {}
 fn unify<const N: usize>(_: &[Foo<N>; 2], _: &[String; N]) {}
 
 fn works_if_inference_side_effects() {
-    // This will only pass if inference side effectrs from proving `Foo<?x>: Copy` are
+    // This will only pass if inference side effects from proving `Foo<?x>: Copy` are
     // able to be relied upon by other repeat expressions.
     let a /* : [Foo<?x>; 2] */ = [Foo::<_>; 2];
     //~^ ERROR: type annotations needed for `[Foo<_>; 2]`