Auto merge of #66656 - Centril:rollup-fivygwz, r=Centril

Rollup of 4 pull requests

Successful merges:

 - #65961 (add fn type_name_of_val)
 - #66574 (Update tidy check for error codes testing)
 - #66576 (made gdb pretty-printing more robust when printing uninitialized vec)
 - #66583 (Clarify Step Documentation)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-11-23 04:24:35 +00:00
commit d9025395c8
4 changed files with 107 additions and 24 deletions

View File

@ -284,10 +284,20 @@ class RustStdVecPrinter(object):
("(len: %i, cap: %i)" % (length, cap)))
def children(self):
saw_inaccessible = False
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(self.__val)
gdb_ptr = data_ptr.get_wrapped_value()
for index in xrange(0, length):
yield (str(index), (gdb_ptr + index).dereference())
if saw_inaccessible:
return
try:
# rust-lang/rust#64343: passing deref expr to `str` allows
# catching exception on garbage pointer
str((gdb_ptr + index).dereference())
yield (str(index), (gdb_ptr + index).dereference())
except RuntimeError:
saw_inaccessible = True
yield (str(index), "inaccessible")
class RustStdVecDequePrinter(object):

View File

@ -452,7 +452,7 @@ impl TypeId {
/// The current implementation uses the same infrastructure as compiler
/// diagnostics and debuginfo, but this is not guaranteed.
///
/// # Example
/// # Examples
///
/// ```rust
/// assert_eq!(
@ -465,3 +465,42 @@ impl TypeId {
pub const fn type_name<T: ?Sized>() -> &'static str {
intrinsics::type_name::<T>()
}
/// Returns the name of the type of the pointed-to value as a string slice.
/// This is the same as `type_name::<T>()`, but can be used where the type of a
/// variable is not easily available.
///
/// # Note
///
/// This is intended for diagnostic use. The exact contents and format of the
/// string are not specified, other than being a best-effort description of the
/// type. For example, `type_name_of::<Option<String>>(None)` could return the
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
/// `"foobar"`. In addition, the output may change between versions of the
/// compiler.
///
/// The type name should not be considered a unique identifier of a type;
/// multiple types may share the same type name.
///
/// The current implementation uses the same infrastructure as compiler
/// diagnostics and debuginfo, but this is not guaranteed.
///
/// # Examples
///
/// Prints the default integer and float types.
///
/// ```rust
/// #![feature(type_name_of_val)]
/// use std::any::type_name_of_val;
///
/// let x = 1;
/// println!("{}", type_name_of_val(&x));
/// let y = 1.0;
/// println!("{}", type_name_of_val(&y));
/// ```
#[unstable(feature = "type_name_of_val", issue = "66359")]
#[rustc_const_unstable(feature = "const_type_name")]
pub const fn type_name_of_val<T: ?Sized>(val: &T) -> &'static str {
let _ = val;
type_name::<T>()
}

View File

@ -20,10 +20,14 @@ pub trait Step: Clone + PartialOrd + Sized {
/// without overflow.
fn steps_between(start: &Self, end: &Self) -> Option<usize>;
/// Replaces this step with `1`, returning itself.
/// Replaces this step with `1`, returning a clone of itself.
///
/// The output of this method should always be greater than the output of replace_zero.
fn replace_one(&mut self) -> Self;
/// Replaces this step with `0`, returning itself.
/// Replaces this step with `0`, returning a clone of itself.
///
/// The output of this method should always be less than the output of replace_one.
fn replace_zero(&mut self) -> Self;
/// Adds one to this step, returning the result.

View File

@ -3,6 +3,8 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::read_to_string;
use std::io::Read;
use std::path::Path;
// A few of those error codes can't be tested but all the others can and *should* be tested!
@ -50,29 +52,60 @@ const WHITELIST: &[&str] = &[
"E0729",
];
fn extract_error_codes(f: &str, error_codes: &mut HashMap<String, bool>) {
fn check_error_code_explanation(
f: &str,
error_codes: &mut HashMap<String, bool>,
err_code: String,
) {
for line in f.lines() {
let s = line.trim();
if s.starts_with("```") && s.contains("compile_fail") && s.contains('E') {
error_codes.insert(err_code, true);
return;
} else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
error_codes.get_mut(&err_code).map(|x| *x = true);
return;
}
}
}
macro_rules! some_or_continue {
($e:expr) => (
match $e {
Some(e) => e,
None => continue,
}
);
}
fn extract_error_codes(f: &str, error_codes: &mut HashMap<String, bool>, path: &Path) {
let mut reached_no_explanation = false;
let mut last_error_code = None;
for line in f.lines() {
let s = line.trim();
if s.starts_with('E') && s.ends_with(": r##\"") {
if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
if let Some(err_code) = s.splitn(2, ':').next() {
let err_code = err_code.to_owned();
last_error_code = Some(err_code.clone());
if !error_codes.contains_key(&err_code) {
error_codes.insert(err_code, false);
error_codes.insert(err_code.clone(), false);
}
// Now we extract the tests from the markdown file!
let md = some_or_continue!(s.splitn(2, "include_str!(\"").skip(1).next());
let md_file_name = some_or_continue!(md.splitn(2, "\")").next());
let path = some_or_continue!(path.parent()).join(md_file_name);
match read_to_string(&path) {
Ok(content) => {
check_error_code_explanation(
&content,
error_codes,
err_code,
);
}
Err(e) => {
eprintln!("Couldn't read `{}`: {}", path.display(), e);
}
}
}
} else if s.starts_with("```") && s.contains("compile_fail") && s.contains('E') {
if let Some(err_code) = s.splitn(2, 'E').skip(1).next() {
if let Some(err_code) = err_code.splitn(2, ',').next() {
let nb = error_codes.entry(format!("E{}", err_code)).or_insert(false);
*nb = true;
}
}
} else if s == ";" {
reached_no_explanation = true;
} else if reached_no_explanation && s.starts_with('E') {
if let Some(err_code) = s.splitn(2, ',').next() {
let err_code = err_code.to_owned();
@ -80,11 +113,8 @@ fn extract_error_codes(f: &str, error_codes: &mut HashMap<String, bool>) {
error_codes.insert(err_code, false);
}
}
} else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
if let Some(last) = last_error_code {
error_codes.get_mut(&last).map(|x| *x = true);
}
last_error_code = None;
} else if s == ";" {
reached_no_explanation = true;
}
}
}
@ -111,7 +141,7 @@ pub fn check(path: &Path, bad: &mut bool) {
&mut |entry, contents| {
let file_name = entry.file_name();
if file_name == "error_codes.rs" {
extract_error_codes(contents, &mut error_codes);
extract_error_codes(contents, &mut error_codes, entry.path());
} else if entry.path().extension() == Some(OsStr::new("stderr")) {
extract_error_codes_from_tests(contents, &mut error_codes);
}