Rollup merge of #61380 - varkor:expected-usize-got-param, r=eddyb

Fix some issues with `unwrap_usize` instead of `assert_usize`

Fixes https://github.com/rust-lang/rust/issues/61337.
Fixes https://github.com/rust-lang/rust/issues/61341.
Fixes https://github.com/rust-lang/rust/issues/61422.

r? @eddyb
This commit is contained in:
Mazdak Farrokhzad 2019-06-02 15:23:46 +02:00 committed by GitHub
commit c748c7b3fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 160 additions and 28 deletions

View File

@ -914,8 +914,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} }
// already reported in the query // already reported in the query
ConstEvalFailure(_) => { ConstEvalFailure(err) => {
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error"); self.tcx.sess.delay_span_bug(
span,
&format!("constant in type had an ignored error: {:?}", err),
);
return; return;
} }

View File

@ -549,8 +549,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
} }
} }
let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
let element = self.layout_of(element)?; let element = self.layout_of(element)?;
let count = count.unwrap_usize(tcx);
let size = element.size.checked_mul(count, dl) let size = element.size.checked_mul(count, dl)
.ok_or(LayoutError::SizeOverflow(ty))?; .ok_or(LayoutError::SizeOverflow(ty))?;

View File

@ -342,9 +342,7 @@ fn fixed_vec_metadata(
let (size, align) = cx.size_and_align_of(array_or_slice_type); let (size, align) = cx.size_and_align_of(array_or_slice_type);
let upper_bound = match array_or_slice_type.sty { let upper_bound = match array_or_slice_type.sty {
ty::Array(_, len) => { ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
len.unwrap_usize(cx.tcx) as c_longlong
}
_ => -1 _ => -1
}; };

View File

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

View File

@ -316,8 +316,9 @@ impl Qualif for HasMutInterior {
} else if let ty::Array(_, len) = ty.sty { } else if let ty::Array(_, len) = ty.sty {
// FIXME(eddyb) the `cx.mode == Mode::Fn` condition // FIXME(eddyb) the `cx.mode == Mode::Fn` condition
// seems unnecessary, given that this is merely a ZST. // seems unnecessary, given that this is merely a ZST.
if !(len.unwrap_usize(cx.tcx) == 0 && cx.mode == Mode::Fn) { match len.assert_usize(cx.tcx) {
return true; Some(0) if cx.mode == Mode::Fn => {},
_ => return true,
} }
} else { } else {
return true; return true;

View File

@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let expected_ty = self.structurally_resolved_type(pat.span, expected); let expected_ty = self.structurally_resolved_type(pat.span, expected);
let (inner_ty, slice_ty) = match expected_ty.sty { let (inner_ty, slice_ty) = match expected_ty.sty {
ty::Array(inner_ty, size) => { ty::Array(inner_ty, size) => {
let size = size.unwrap_usize(tcx); if let Some(size) = size.assert_usize(tcx) {
let min_len = before.len() as u64 + after.len() as u64; let min_len = before.len() as u64 + after.len() as u64;
if slice.is_none() { if slice.is_none() {
if min_len != size { if min_len != size {
@ -423,6 +423,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.emit(); .emit();
(inner_ty, tcx.types.err) (inner_ty, tcx.types.err)
} }
} else {
struct_span_err!(
tcx.sess,
pat.span,
E0730,
"cannot pattern-match on an array without a fixed length",
).emit();
(inner_ty, tcx.types.err)
}
} }
ty::Slice(inner_ty) => (inner_ty, expected_ty), ty::Slice(inner_ty) => (inner_ty, expected_ty),
_ => { _ => {

View File

@ -4648,6 +4648,38 @@ fn make_recursive_type() -> impl Sized {
``` ```
"##, "##,
E0730: r##"
An array without a fixed length was pattern-matched.
Example of erroneous code:
```compile_fail,E0730
#![feature(const_generics)]
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, 3] => true, // error: cannot pattern-match on an
// array without a fixed length
_ => false
}
}
```
Ensure that the pattern is consistent with the size of the matched
array. Additional elements can be matched with `..`:
```
#![feature(slice_patterns)]
let r = &[1, 2, 3, 4];
match r {
&[a, b, ..] => { // ok!
println!("a={}, b={}", a, b);
}
}
```
"##,
} }
register_diagnostics! { register_diagnostics! {

View File

@ -0,0 +1,15 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::mem;
fn foo<const SIZE: usize>() {
let arr: [u8; SIZE] = unsafe {
let mut array: [u8; SIZE] = mem::uninitialized();
array
};
}
fn main() {}

View File

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/issue-61422.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View File

@ -0,0 +1,19 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::ops::AddAssign;
fn inc<T: AddAssign + Clone, const N: usize>(v: &mut [T; N]) -> &mut [T; N] {
for x in v.iter_mut() {
*x += x.clone();
}
v
}
fn main() {
let mut v = [1, 2, 3];
inc(&mut v);
assert_eq!(v, [2, 4, 6]);
}

View File

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/mut-ref-const-param-array.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View File

@ -0,0 +1,11 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::mem::MaybeUninit;
#[repr(transparent)]
pub struct MaybeUninitWrapper<const N: usize>(MaybeUninit<[u64; N]>);
fn main() {}

View File

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/transparent-maybeunit-array-wrapper.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View File

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

View File

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