diff options
| author | Boxy <rust@boxyuwu.dev> | 2025-04-14 13:41:18 +0100 |
|---|---|---|
| committer | Boxy <rust@boxyuwu.dev> | 2025-05-22 11:39:49 +0100 |
| commit | cc10370fc8b2b412600aa846e3046b8a09dda7ca (patch) | |
| tree | 143426ba52b215b8b9693e20bafb7140d509203d | |
| parent | 43162597292f904ff5ff47e251ba40fb9ae41ded (diff) | |
| download | rust-cc10370fc8b2b412600aa846e3046b8a09dda7ca.tar.gz rust-cc10370fc8b2b412600aa846e3046b8a09dda7ca.zip | |
Reviews
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]` |
