Skip to content

Commit c748c7b

Browse files
authored
Rollup merge of rust-lang#61380 - varkor:expected-usize-got-param, r=eddyb
Fix some issues with `unwrap_usize` instead of `assert_usize` Fixes rust-lang#61337. Fixes rust-lang#61341. Fixes rust-lang#61422. r? @eddyb
2 parents 538e17a + e82cd95 commit c748c7b

File tree

15 files changed

+160
-28
lines changed

15 files changed

+160
-28
lines changed

src/librustc/traits/error_reporting.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -914,8 +914,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
914914
}
915915

916916
// already reported in the query
917-
ConstEvalFailure(_) => {
918-
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
917+
ConstEvalFailure(err) => {
918+
self.tcx.sess.delay_span_bug(
919+
span,
920+
&format!("constant in type had an ignored error: {:?}", err),
921+
);
919922
return;
920923
}
921924

src/librustc/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
549549
}
550550
}
551551

552+
let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
552553
let element = self.layout_of(element)?;
553-
let count = count.unwrap_usize(tcx);
554554
let size = element.size.checked_mul(count, dl)
555555
.ok_or(LayoutError::SizeOverflow(ty))?;
556556

src/librustc_codegen_llvm/debuginfo/metadata.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,7 @@ fn fixed_vec_metadata(
342342
let (size, align) = cx.size_and_align_of(array_or_slice_type);
343343

344344
let upper_bound = match array_or_slice_type.sty {
345-
ty::Array(_, len) => {
346-
len.unwrap_usize(cx.tcx) as c_longlong
347-
}
345+
ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
348346
_ => -1
349347
};
350348

src/librustc_mir/borrow_check/places_conflict.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
332332
},
333333
(StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
334334
if promoted_1 == promoted_2 {
335-
if let ty::Array(_, size) = s1.ty.sty {
336-
if size.unwrap_usize(tcx) == 0 {
335+
if let ty::Array(_, len) = s1.ty.sty {
336+
if let Some(0) = len.assert_usize(tcx) {
337337
// Ignore conflicts with promoted [T; 0].
338338
debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
339339
return Overlap::Disjoint;

src/librustc_mir/transform/qualify_consts.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,9 @@ impl Qualif for HasMutInterior {
316316
} else if let ty::Array(_, len) = ty.sty {
317317
// FIXME(eddyb) the `cx.mode == Mode::Fn` condition
318318
// seems unnecessary, given that this is merely a ZST.
319-
if !(len.unwrap_usize(cx.tcx) == 0 && cx.mode == Mode::Fn) {
320-
return true;
319+
match len.assert_usize(cx.tcx) {
320+
Some(0) if cx.mode == Mode::Fn => {},
321+
_ => return true,
321322
}
322323
} else {
323324
return true;

src/librustc_typeck/check/_match.rs

+27-18
Original file line numberDiff line numberDiff line change
@@ -400,27 +400,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
400400
let expected_ty = self.structurally_resolved_type(pat.span, expected);
401401
let (inner_ty, slice_ty) = match expected_ty.sty {
402402
ty::Array(inner_ty, size) => {
403-
let size = size.unwrap_usize(tcx);
404-
let min_len = before.len() as u64 + after.len() as u64;
405-
if slice.is_none() {
406-
if min_len != size {
407-
struct_span_err!(
408-
tcx.sess, pat.span, E0527,
409-
"pattern requires {} elements but array has {}",
410-
min_len, size)
411-
.span_label(pat.span, format!("expected {} elements", size))
403+
if let Some(size) = size.assert_usize(tcx) {
404+
let min_len = before.len() as u64 + after.len() as u64;
405+
if slice.is_none() {
406+
if min_len != size {
407+
struct_span_err!(
408+
tcx.sess, pat.span, E0527,
409+
"pattern requires {} elements but array has {}",
410+
min_len, size)
411+
.span_label(pat.span, format!("expected {} elements", size))
412+
.emit();
413+
}
414+
(inner_ty, tcx.types.err)
415+
} else if let Some(rest) = size.checked_sub(min_len) {
416+
(inner_ty, tcx.mk_array(inner_ty, rest))
417+
} else {
418+
struct_span_err!(tcx.sess, pat.span, E0528,
419+
"pattern requires at least {} elements but array has {}",
420+
min_len, size)
421+
.span_label(pat.span,
422+
format!("pattern cannot match array of {} elements", size))
412423
.emit();
424+
(inner_ty, tcx.types.err)
413425
}
414-
(inner_ty, tcx.types.err)
415-
} else if let Some(rest) = size.checked_sub(min_len) {
416-
(inner_ty, tcx.mk_array(inner_ty, rest))
417426
} else {
418-
struct_span_err!(tcx.sess, pat.span, E0528,
419-
"pattern requires at least {} elements but array has {}",
420-
min_len, size)
421-
.span_label(pat.span,
422-
format!("pattern cannot match array of {} elements", size))
423-
.emit();
427+
struct_span_err!(
428+
tcx.sess,
429+
pat.span,
430+
E0730,
431+
"cannot pattern-match on an array without a fixed length",
432+
).emit();
424433
(inner_ty, tcx.types.err)
425434
}
426435
}

src/librustc_typeck/error_codes.rs

+32
Original file line numberDiff line numberDiff line change
@@ -4648,6 +4648,38 @@ fn make_recursive_type() -> impl Sized {
46484648
```
46494649
"##,
46504650

4651+
E0730: r##"
4652+
An array without a fixed length was pattern-matched.
4653+
4654+
Example of erroneous code:
4655+
4656+
```compile_fail,E0730
4657+
#![feature(const_generics)]
4658+
4659+
fn is_123<const N: usize>(x: [u32; N]) -> bool {
4660+
match x {
4661+
[1, 2, 3] => true, // error: cannot pattern-match on an
4662+
// array without a fixed length
4663+
_ => false
4664+
}
4665+
}
4666+
```
4667+
4668+
Ensure that the pattern is consistent with the size of the matched
4669+
array. Additional elements can be matched with `..`:
4670+
4671+
```
4672+
#![feature(slice_patterns)]
4673+
4674+
let r = &[1, 2, 3, 4];
4675+
match r {
4676+
&[a, b, ..] => { // ok!
4677+
println!("a={}, b={}", a, b);
4678+
}
4679+
}
4680+
```
4681+
"##,
4682+
46514683
}
46524684

46534685
register_diagnostics! {
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// run-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
5+
6+
use std::mem;
7+
8+
fn foo<const SIZE: usize>() {
9+
let arr: [u8; SIZE] = unsafe {
10+
let mut array: [u8; SIZE] = mem::uninitialized();
11+
array
12+
};
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/issue-61422.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// run-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
5+
6+
use std::ops::AddAssign;
7+
8+
fn inc<T: AddAssign + Clone, const N: usize>(v: &mut [T; N]) -> &mut [T; N] {
9+
for x in v.iter_mut() {
10+
*x += x.clone();
11+
}
12+
v
13+
}
14+
15+
fn main() {
16+
let mut v = [1, 2, 3];
17+
inc(&mut v);
18+
assert_eq!(v, [2, 4, 6]);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/mut-ref-const-param-array.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// run-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
5+
6+
use std::mem::MaybeUninit;
7+
8+
#[repr(transparent)]
9+
pub struct MaybeUninitWrapper<const N: usize>(MaybeUninit<[u64; N]>);
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/transparent-maybeunit-array-wrapper.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+

src/test/ui/error-codes/E0730.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
fn is_123<const N: usize>(x: [u32; N]) -> bool {
5+
match x {
6+
[1, 2, 3] => true, //~ ERROR cannot pattern-match on an array without a fixed length
7+
_ => false
8+
}
9+
}
10+
11+
fn main() {}

src/test/ui/error-codes/E0730.stderr

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/E0730.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
7+
error[E0730]: cannot pattern-match on an array without a fixed length
8+
--> $DIR/E0730.rs:6:9
9+
|
10+
LL | [1, 2, 3] => true,
11+
| ^^^^^^^^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0730`.

0 commit comments

Comments
 (0)