mirror of
https://github.com/rust-lang/rust.git
synced 2026-03-23 19:27:56 +00:00
Reviews
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>);
|
||||
|
||||
@@ -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]`
|
||||
|
||||
Reference in New Issue
Block a user