Skip to content
Closed
20 changes: 7 additions & 13 deletions src/libcore/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1890,17 +1890,15 @@ where
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
// 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]
Expand All @@ -1916,17 +1914,13 @@ where

#[inline]
fn last(mut self) -> Option<I::Item> {
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]
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/map/hir_id_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(hash_raw_entry)]
#![feature(int_error_matching)]
#![recursion_limit = "512"]

#[macro_use]
Expand Down
46 changes: 40 additions & 6 deletions src/librustc/middle/recursion_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<usize>, name: Symbol, default: usize) {
fn update_limit(
sess: &Session,
krate: &ast::Crate,
limit: &Once<usize>,
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();
}
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/libstd/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
1 change: 1 addition & 0 deletions src/test/debuginfo/empty-string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ===================================================================================
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/generator/async-generator-issue-67158.rs
Original file line number Diff line number Diff line change
@@ -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
}
9 changes: 9 additions & 0 deletions src/test/ui/generator/async-generator-issue-67158.stderr
Original file line number Diff line number Diff line change
@@ -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`.
6 changes: 6 additions & 0 deletions src/test/ui/recursion_limit/empty.rs
Original file line number Diff line number Diff line change
@@ -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() {}
10 changes: 10 additions & 0 deletions src/test/ui/recursion_limit/empty.stderr
Original file line number Diff line number Diff line change
@@ -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

6 changes: 6 additions & 0 deletions src/test/ui/recursion_limit/invalid_digit.rs
Original file line number Diff line number Diff line change
@@ -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() {}
10 changes: 10 additions & 0 deletions src/test/ui/recursion_limit/invalid_digit.stderr
Original file line number Diff line number Diff line change
@@ -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

7 changes: 7 additions & 0 deletions src/test/ui/recursion_limit/overflow.rs
Original file line number Diff line number Diff line change
@@ -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() {}
10 changes: 10 additions & 0 deletions src/test/ui/recursion_limit/overflow.stderr
Original file line number Diff line number Diff line change
@@ -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

12 changes: 12 additions & 0 deletions src/test/ui/recursion_limit/zero.rs
Original file line number Diff line number Diff line change
@@ -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() {}
10 changes: 10 additions & 0 deletions src/test/ui/recursion_limit/zero.stderr
Original file line number Diff line number Diff line change
@@ -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