diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 7d10ef3d28219..58606531a1ace 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1890,17 +1890,15 @@ where #[inline] fn nth(&mut self, n: usize) -> Option { // Can't just add n + self.n due to overflow. - if self.n == 0 { - self.iter.nth(n) - } else { + if self.n > 0 { let to_skip = self.n; self.n = 0; // nth(n) skips n+1 if self.iter.nth(to_skip - 1).is_none() { return None; } - self.iter.nth(n) } + self.iter.nth(n) } #[inline] @@ -1916,17 +1914,13 @@ where #[inline] fn last(mut self) -> Option { - if self.n == 0 { - self.iter.last() - } else { - let next = self.next(); - if next.is_some() { - // recurse. n should be 0. - self.last().or(next) - } else { - None + if self.n > 0 { + // nth(n) skips n+1 + if self.iter.nth(self.n - 1).is_none() { + return None; } } + self.iter.last() } #[inline] diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index c721faafbecaf..a4f9193c0eb64 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -7,7 +7,7 @@ use rustc_hir::intravisit; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{HirId, ItemLocalId}; -pub fn check_crate(hir_map: &Map<'_>) { +pub fn check_crate(hir_map: &Map<'_>, sess: &rustc_session::Session) { hir_map.dep_graph.assert_ignored(); let errors = Lock::new(Vec::new()); @@ -24,7 +24,7 @@ pub fn check_crate(hir_map: &Map<'_>) { if !errors.is_empty() { let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); - bug!("{}", message); + sess.delay_span_bug(rustc_span::DUMMY_SP, &message); } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 1645420892a75..adda0cde24fc0 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1235,7 +1235,7 @@ pub fn map_crate<'hir>( let map = Map { krate, dep_graph, crate_hash, map, hir_to_node_id, definitions }; sess.time("validate_HIR_map", || { - hir_id_validator::check_crate(&map); + hir_id_validator::check_crate(&map, sess); }); map diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index e1e774b853c20..055d70effc6e6 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -46,6 +46,7 @@ #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(hash_raw_entry)] +#![feature(int_error_matching)] #![recursion_limit = "512"] #[macro_use] diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs index b33cde8e2af20..be530da5910df 100644 --- a/src/librustc/middle/recursion_limit.rs +++ b/src/librustc/middle/recursion_limit.rs @@ -6,26 +6,60 @@ // just peeks and looks for that attribute. use crate::session::Session; +use core::num::IntErrorKind; +use rustc::bug; use rustc_span::symbol::{sym, Symbol}; use syntax::ast; use rustc_data_structures::sync::Once; pub fn update_limits(sess: &Session, krate: &ast::Crate) { - update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 128); - update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576); + update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128); + update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576); } -fn update_limit(krate: &ast::Crate, limit: &Once, name: Symbol, default: usize) { +fn update_limit( + sess: &Session, + krate: &ast::Crate, + limit: &Once, + name: Symbol, + default: usize, +) { for attr in &krate.attrs { if !attr.check_name(name) { continue; } if let Some(s) = attr.value_str() { - if let Some(n) = s.as_str().parse().ok() { - limit.set(n); - return; + match s.as_str().parse() { + Ok(n) => { + limit.set(n); + return; + } + Err(e) => { + let mut err = sess.struct_span_err( + attr.span, + "`recursion_limit` must be a non-negative integer", + ); + + let value_span = attr + .meta() + .and_then(|meta| meta.name_value_literal().cloned()) + .map(|lit| lit.span) + .unwrap_or(attr.span); + + let error_str = match e.kind() { + IntErrorKind::Overflow => "`recursion_limit` is too large", + IntErrorKind::Empty => "`recursion_limit` must be a non-negative integer", + IntErrorKind::InvalidDigit => "not a valid integer", + IntErrorKind::Underflow => bug!("`recursion_limit` should never underflow"), + IntErrorKind::Zero => bug!("zero is a valid `recursion_limit`"), + kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), + }; + + err.span_label(value_span, error_str); + err.emit(); + } } } } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 3ca778354e413..674d4c7113801 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -255,8 +255,9 @@ pub mod guard { #[cfg(target_os = "macos")] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { - let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize - - libc::pthread_get_stacksize_np(libc::pthread_self()); + let th = libc::pthread_self(); + let stackaddr = + libc::pthread_get_stackaddr_np(th) as usize - libc::pthread_get_stacksize_np(th); Some(stackaddr as *mut libc::c_void) } diff --git a/src/test/debuginfo/empty-string.rs b/src/test/debuginfo/empty-string.rs index 8c5f67a66043e..bc4fac3183cea 100644 --- a/src/test/debuginfo/empty-string.rs +++ b/src/test/debuginfo/empty-string.rs @@ -2,6 +2,7 @@ // ignore-android: FIXME(#10381) // compile-flags:-g // min-gdb-version: 7.7 +// ignore-gdb-version: 7.11.90 - 8.0.9 // min-lldb-version: 310 // === GDB TESTS =================================================================================== diff --git a/src/test/ui/generator/async-generator-issue-67158.rs b/src/test/ui/generator/async-generator-issue-67158.rs new file mode 100644 index 0000000000000..8125a7a9bb664 --- /dev/null +++ b/src/test/ui/generator/async-generator-issue-67158.rs @@ -0,0 +1,6 @@ +#![feature(generators)] +// edition:2018 +// Regression test for #67158. +fn main() { + async { yield print!(":C") }; //~ ERROR `async` generators are not yet supported +} diff --git a/src/test/ui/generator/async-generator-issue-67158.stderr b/src/test/ui/generator/async-generator-issue-67158.stderr new file mode 100644 index 0000000000000..7270d188e8b88 --- /dev/null +++ b/src/test/ui/generator/async-generator-issue-67158.stderr @@ -0,0 +1,9 @@ +error[E0727]: `async` generators are not yet supported + --> $DIR/async-generator-issue-67158.rs:5:13 + | +LL | async { yield print!(":C") }; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0727`. diff --git a/src/test/ui/recursion_limit/empty.rs b/src/test/ui/recursion_limit/empty.rs new file mode 100644 index 0000000000000..2a064f3e11599 --- /dev/null +++ b/src/test/ui/recursion_limit/empty.rs @@ -0,0 +1,6 @@ +// Test the parse error for an empty recursion_limit + +#![recursion_limit = ""] //~ ERROR `recursion_limit` must be a non-negative integer + //~| `recursion_limit` must be a non-negative integer + +fn main() {} diff --git a/src/test/ui/recursion_limit/empty.stderr b/src/test/ui/recursion_limit/empty.stderr new file mode 100644 index 0000000000000..690c33a746307 --- /dev/null +++ b/src/test/ui/recursion_limit/empty.stderr @@ -0,0 +1,10 @@ +error: `recursion_limit` must be a non-negative integer + --> $DIR/empty.rs:3:1 + | +LL | #![recursion_limit = ""] + | ^^^^^^^^^^^^^^^^^^^^^--^ + | | + | `recursion_limit` must be a non-negative integer + +error: aborting due to previous error + diff --git a/src/test/ui/recursion_limit/invalid_digit.rs b/src/test/ui/recursion_limit/invalid_digit.rs new file mode 100644 index 0000000000000..903d804047696 --- /dev/null +++ b/src/test/ui/recursion_limit/invalid_digit.rs @@ -0,0 +1,6 @@ +// Test the parse error for an invalid digit in recursion_limit + +#![recursion_limit = "-100"] //~ ERROR `recursion_limit` must be a non-negative integer + //~| not a valid integer + +fn main() {} diff --git a/src/test/ui/recursion_limit/invalid_digit.stderr b/src/test/ui/recursion_limit/invalid_digit.stderr new file mode 100644 index 0000000000000..1dcfea547c0bd --- /dev/null +++ b/src/test/ui/recursion_limit/invalid_digit.stderr @@ -0,0 +1,10 @@ +error: `recursion_limit` must be a non-negative integer + --> $DIR/invalid_digit.rs:3:1 + | +LL | #![recursion_limit = "-100"] + | ^^^^^^^^^^^^^^^^^^^^^------^ + | | + | not a valid integer + +error: aborting due to previous error + diff --git a/src/test/ui/recursion_limit/overflow.rs b/src/test/ui/recursion_limit/overflow.rs new file mode 100644 index 0000000000000..6487b1350aa98 --- /dev/null +++ b/src/test/ui/recursion_limit/overflow.rs @@ -0,0 +1,7 @@ +// Test the parse error for an overflowing recursion_limit + +#![recursion_limit = "999999999999999999999999"] +//~^ ERROR `recursion_limit` must be a non-negative integer +//~| `recursion_limit` is too large + +fn main() {} diff --git a/src/test/ui/recursion_limit/overflow.stderr b/src/test/ui/recursion_limit/overflow.stderr new file mode 100644 index 0000000000000..c3fc11989dcec --- /dev/null +++ b/src/test/ui/recursion_limit/overflow.stderr @@ -0,0 +1,10 @@ +error: `recursion_limit` must be a non-negative integer + --> $DIR/overflow.rs:3:1 + | +LL | #![recursion_limit = "999999999999999999999999"] + | ^^^^^^^^^^^^^^^^^^^^^--------------------------^ + | | + | `recursion_limit` is too large + +error: aborting due to previous error + diff --git a/src/test/ui/recursion_limit/zero.rs b/src/test/ui/recursion_limit/zero.rs new file mode 100644 index 0000000000000..f7199944e0063 --- /dev/null +++ b/src/test/ui/recursion_limit/zero.rs @@ -0,0 +1,12 @@ +// Test that a `recursion_limit` of 0 is valid + +#![recursion_limit = "0"] + +macro_rules! test { + () => {}; + ($tt:tt) => { test!(); }; +} + +test!(test); //~ ERROR 10:1: 10:13: recursion limit reached while expanding `test!` + +fn main() {} diff --git a/src/test/ui/recursion_limit/zero.stderr b/src/test/ui/recursion_limit/zero.stderr new file mode 100644 index 0000000000000..6358805d89dee --- /dev/null +++ b/src/test/ui/recursion_limit/zero.stderr @@ -0,0 +1,10 @@ +error: recursion limit reached while expanding `test!` + --> $DIR/zero.rs:10:1 + | +LL | test!(test); + | ^^^^^^^^^^^^ + | + = help: consider adding a `#![recursion_limit="0"]` attribute to your crate (`zero`) + +error: aborting due to previous error +