Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #70617

Merged
merged 22 commits into from
Mar 31, 2020
Merged
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8f7eb62
Add long error code for error E0226
Aelerinya Mar 30, 2020
9f86d28
try_resolve_as_non_binding: span_bug -> delay_span_bug
Centril Mar 30, 2020
d6f71f0
remove obsolete comment
tshepang Mar 30, 2020
ac478f2
Optimize strip_prefix and strip_suffix with str patterns
benesch Mar 6, 2020
50ab773
infer arr len from pattern
lcnr Mar 30, 2020
32103b1
Correct long error message according to reviews
Aelerinya Mar 30, 2020
7f12561
dedup docs
lcnr Mar 30, 2020
40c5eef
add test for array len inference
lcnr Mar 30, 2020
a3df1db
update tests, improve variable names
lcnr Mar 30, 2020
ab2998b
std: Fix over-aligned allocations on wasm32-wasi
alexcrichton Mar 30, 2020
641409b
Add `Rust` to the code snippet
DutchGhost Mar 30, 2020
fcab1f9
Fix incorrect documentation for `str::{split_at, split_at_mut}`
Coder-256 Mar 30, 2020
08f2904
more clippy fixes
matthiaskrgr Mar 29, 2020
9ee373f
Rollup merge of #69784 - benesch:fast-strip-prefix-suffix, r=kennytm
Centril Mar 31, 2020
cbe3266
Rollup merge of #70548 - Ersikan:master, r=GuillaumeGomez
Centril Mar 31, 2020
65b85a5
Rollup merge of #70555 - Centril:fix-70549, r=petrochenkov
Centril Mar 31, 2020
38cd294
Rollup merge of #70561 - tshepang:obsolete-comment, r=petrochenkov
Centril Mar 31, 2020
3ef70fe
Rollup merge of #70562 - lcnr:const-arr_len, r=Centril
Centril Mar 31, 2020
cd4d1c7
Rollup merge of #70585 - alexcrichton:fix-wasi-align-alloc, r=Mark-Si…
Centril Mar 31, 2020
c55f500
Rollup merge of #70587 - DutchGhost:patch-1, r=Dylan-DPC
Centril Mar 31, 2020
4aeeb81
Rollup merge of #70588 - Coder-256:str-split-at-docs, r=Dylan-DPC
Centril Mar 31, 2020
976f8d5
Rollup merge of #70613 - matthiaskrgr:cl5ppy_squashed, r=Centril
Centril Mar 31, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions src/librustc_typeck/check/pat.rs
Original file line number Diff line number Diff line change
@@ -1355,16 +1355,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let err = self.tcx.types.err;
let expected = self.structurally_resolved_type(span, expected);
let (inner_ty, slice_ty, expected) = match expected.kind {
let (element_ty, slice_ty, expected) = match expected.kind {
// An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
ty::Array(inner_ty, len) => {
ty::Array(element_ty, len) => {
let min = before.len() as u64 + after.len() as u64;
let slice_ty = self
.check_array_pat_len(span, slice, len, min)
.map_or(err, |len| self.tcx.mk_array(inner_ty, len));
(inner_ty, slice_ty, expected)
let (slice_ty, expected) =
self.check_array_pat_len(span, element_ty, expected, slice, len, min);
(element_ty, slice_ty, expected)
}
ty::Slice(inner_ty) => (inner_ty, expected, expected),
ty::Slice(element_ty) => (element_ty, expected, expected),
// The expected type must be an array or slice, but was neither, so error.
_ => {
if !expected.references_error() {
@@ -1376,30 +1375,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Type check all the patterns before `slice`.
for elt in before {
self.check_pat(&elt, inner_ty, def_bm, ti);
self.check_pat(&elt, element_ty, def_bm, ti);
}
// Type check the `slice`, if present, against its expected type.
if let Some(slice) = slice {
self.check_pat(&slice, slice_ty, def_bm, ti);
}
// Type check the elements after `slice`, if present.
for elt in after {
self.check_pat(&elt, inner_ty, def_bm, ti);
self.check_pat(&elt, element_ty, def_bm, ti);
}
expected
}

/// Type check the length of an array pattern.
///
/// Return the length of the variable length pattern,
/// if it exists and there are no errors.
/// Returns both the type of the variable length pattern
/// (or `tcx.err` in case there is none),
/// and the potentially inferred array type.
fn check_array_pat_len(
&self,
span: Span,
element_ty: Ty<'tcx>,
arr_ty: Ty<'tcx>,
slice: Option<&'tcx Pat<'tcx>>,
len: &ty::Const<'tcx>,
min_len: u64,
) -> Option<u64> {
) -> (Ty<'tcx>, Ty<'tcx>) {
if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) {
// Now we know the length...
if slice.is_none() {
@@ -1409,21 +1411,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if min_len != len {
self.error_scrutinee_inconsistent_length(span, min_len, len);
}
} else if let r @ Some(_) = len.checked_sub(min_len) {
} else if let Some(pat_len) = len.checked_sub(min_len) {
// The variable-length pattern was there,
// so it has an array type with the remaining elements left as its size...
return r;
return (self.tcx.mk_array(element_ty, pat_len), arr_ty);
} else {
// ...however, in this case, there were no remaining elements.
// That is, the slice pattern requires more than the array type offers.
self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len);
}
} else if slice.is_none() {
// We have a pattern with a fixed length,
// which we can use to infer the length of the array.
// of the array.
let updated_arr_ty = self.tcx.mk_array(element_ty, min_len);
self.demand_eqtype(span, updated_arr_ty, arr_ty);
return (self.tcx.types.err, updated_arr_ty);
} else {
// No idea what the length is, which happens if we have e.g.,
// `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`.
// We have a variable-length pattern and don't know the array length.
// This happens if we have e.g.,
// `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
self.error_scrutinee_unfixed_length(span);
}
None
(self.tcx.types.err, arr_ty)
}

fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
27 changes: 27 additions & 0 deletions src/test/ui/const-generics/infer_arg_from_pat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// run-pass
//
// see issue #70529
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

struct A<const N: usize> {
arr: [u8; N],
}

impl<const N: usize> A<N> {
fn new() -> Self {
A {
arr: [0; N],
}
}

fn value(&self) -> usize {
N
}
}

fn main() {
let a = A::new();
let [_, _] = a.arr;
assert_eq!(a.value(), 2);
}
8 changes: 8 additions & 0 deletions src/test/ui/const-generics/infer_arg_from_pat.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/infer_arg_from_pat.rs:4:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

13 changes: 13 additions & 0 deletions src/test/ui/const-generics/infer_arr_len_from_pat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// check-pass
//
// see issue #70529
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

fn as_chunks<const N: usize>() -> [u8; N] {
loop {}
}

fn main() {
let [_, _] = as_chunks();
}
8 changes: 8 additions & 0 deletions src/test/ui/const-generics/infer_arr_len_from_pat.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/infer_arr_len_from_pat.rs:4:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0730.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

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
[1, 2, 3] => true, //~ ERROR mismatched types
_ => false
}
}
9 changes: 6 additions & 3 deletions src/test/ui/error-codes/E0730.stderr
Original file line number Diff line number Diff line change
@@ -6,12 +6,15 @@ LL | #![feature(const_generics)]
|
= note: `#[warn(incomplete_features)]` on by default

error[E0730]: cannot pattern-match on an array without a fixed length
error[E0308]: mismatched types
--> $DIR/E0730.rs:6:9
|
LL | [1, 2, 3] => true,
| ^^^^^^^^^
| ^^^^^^^^^ expected `3usize`, found `N`
|
= note: expected array `[u32; 3]`
found array `[u32; _]`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0730`.
For more information about this error, try `rustc --explain E0308`.