Auto merge of #93738 - m-ou-se:rollup-zjyd2et, r=m-ou-se
Rollup of 13 pull requests Successful merges: - #88313 (Make the pre-commit script pre-push instead) - #91530 (Suggest 1-tuple parentheses on exprs without existing parens) - #92724 (Cleanup c_str.rs) - #93208 (Impl {Add,Sub,Mul,Div,Rem,BitXor,BitOr,BitAnd}Assign<$t> for Wrapping<$t> for rust 1.60.0) - #93394 (Don't allow {} to refer to implicit captures in format_args.) - #93416 (remove `allow_fail` test flag) - #93487 (Fix linking stage1 toolchain in `./x.py setup`) - #93673 (Linkify sidebar headings for sibling items) - #93680 (Drop json::from_reader) - #93682 (Update tracking issue for `const_fn_trait_bound`) - #93722 (Use shallow clones for submodules managed by rustbuild, not just bootstrap.py) - #93723 (Rerun bootstrap's build script when RUSTC changes) - #93737 (bootstrap: prefer using '--config' over 'RUST_BOOTSTRAP_CONFIG') Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f52c31840d
@ -25,6 +25,7 @@ enum ArgumentType {
|
||||
|
||||
enum Position {
|
||||
Exact(usize),
|
||||
Capture(usize),
|
||||
Named(Symbol),
|
||||
}
|
||||
|
||||
@ -49,6 +50,8 @@ struct Context<'a, 'b> {
|
||||
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
|
||||
/// * `names` (in JSON): `{"foo": 2}`
|
||||
args: Vec<P<ast::Expr>>,
|
||||
/// The number of arguments that were added by implicit capturing.
|
||||
num_captured_args: usize,
|
||||
/// Placeholder slot numbers indexed by argument.
|
||||
arg_types: Vec<Vec<usize>>,
|
||||
/// Unique format specs seen for each argument.
|
||||
@ -231,6 +234,11 @@ fn parse_args<'a>(
|
||||
}
|
||||
|
||||
impl<'a, 'b> Context<'a, 'b> {
|
||||
/// The number of arguments that were explicitly given.
|
||||
fn num_args(&self) -> usize {
|
||||
self.args.len() - self.num_captured_args
|
||||
}
|
||||
|
||||
fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
|
||||
// NOTE: the `unwrap_or` branch is needed in case of invalid format
|
||||
// arguments, e.g., `format_args!("{foo}")`.
|
||||
@ -345,7 +353,7 @@ fn verify_count(&mut self, c: parse::Count) {
|
||||
}
|
||||
|
||||
fn describe_num_args(&self) -> Cow<'_, str> {
|
||||
match self.args.len() {
|
||||
match self.num_args() {
|
||||
0 => "no arguments were given".into(),
|
||||
1 => "there is 1 argument".into(),
|
||||
x => format!("there are {} arguments", x).into(),
|
||||
@ -371,7 +379,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
|
||||
|
||||
let count = self.pieces.len()
|
||||
+ self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
|
||||
if self.names.is_empty() && !numbered_position_args && count != self.args.len() {
|
||||
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
|
||||
e = self.ecx.struct_span_err(
|
||||
sp,
|
||||
&format!(
|
||||
@ -419,7 +427,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
|
||||
if let Some(span) = fmt.precision_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
match fmt.precision {
|
||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
e.span_label(
|
||||
span,
|
||||
&format!(
|
||||
@ -462,7 +470,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
|
||||
if let Some(span) = fmt.width_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
match fmt.width {
|
||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
e.span_label(
|
||||
span,
|
||||
&format!(
|
||||
@ -494,12 +502,15 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
|
||||
/// Actually verifies and tracks a given format placeholder
|
||||
/// (a.k.a. argument).
|
||||
fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
|
||||
if let Exact(arg) = arg {
|
||||
if arg >= self.num_args() {
|
||||
self.invalid_refs.push((arg, self.curpiece));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
match arg {
|
||||
Exact(arg) => {
|
||||
if self.args.len() <= arg {
|
||||
self.invalid_refs.push((arg, self.curpiece));
|
||||
return;
|
||||
}
|
||||
Exact(arg) | Capture(arg) => {
|
||||
match ty {
|
||||
Placeholder(_) => {
|
||||
// record every (position, type) combination only once
|
||||
@ -526,7 +537,7 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
|
||||
match self.names.get(&name) {
|
||||
Some(&idx) => {
|
||||
// Treat as positional arg.
|
||||
self.verify_arg_type(Exact(idx), ty)
|
||||
self.verify_arg_type(Capture(idx), ty)
|
||||
}
|
||||
None => {
|
||||
// For the moment capturing variables from format strings expanded from macros is
|
||||
@ -541,9 +552,10 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
|
||||
} else {
|
||||
self.fmtsp
|
||||
};
|
||||
self.num_captured_args += 1;
|
||||
self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
|
||||
self.names.insert(name, idx);
|
||||
self.verify_arg_type(Exact(idx), ty)
|
||||
self.verify_arg_type(Capture(idx), ty)
|
||||
} else {
|
||||
let msg = format!("there is no argument named `{}`", name);
|
||||
let sp = if self.is_literal {
|
||||
@ -1051,6 +1063,7 @@ pub fn expand_preparsed_format_args(
|
||||
let mut cx = Context {
|
||||
ecx,
|
||||
args,
|
||||
num_captured_args: 0,
|
||||
arg_types,
|
||||
arg_unique_types,
|
||||
names,
|
||||
|
@ -252,11 +252,6 @@ pub fn expand_test_or_bench(
|
||||
"ignore",
|
||||
cx.expr_bool(sp, should_ignore(&cx.sess, &item)),
|
||||
),
|
||||
// allow_fail: true | false
|
||||
field(
|
||||
"allow_fail",
|
||||
cx.expr_bool(sp, should_fail(&cx.sess, &item)),
|
||||
),
|
||||
// compile_fail: true | false
|
||||
field("compile_fail", cx.expr_bool(sp, false)),
|
||||
// no_run: true | false
|
||||
@ -359,10 +354,6 @@ fn should_ignore(sess: &Session, i: &ast::Item) -> bool {
|
||||
sess.contains_name(&i.attrs, sym::ignore)
|
||||
}
|
||||
|
||||
fn should_fail(sess: &Session, i: &ast::Item) -> bool {
|
||||
sess.contains_name(&i.attrs, sym::allow_fail)
|
||||
}
|
||||
|
||||
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
|
||||
match cx.sess.find_by_name(&i.attrs, sym::should_panic) {
|
||||
Some(attr) => {
|
||||
|
@ -277,8 +277,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
||||
(incomplete, adt_const_params, "1.56.0", Some(44580), None),
|
||||
/// Allows defining an `#[alloc_error_handler]`.
|
||||
(active, alloc_error_handler, "1.29.0", Some(51540), None),
|
||||
/// Allows a test to fail without failing the whole suite.
|
||||
(active, allow_fail, "1.19.0", Some(46488), None),
|
||||
/// Allows explicit discriminants on non-unit enum variants.
|
||||
(active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
|
||||
/// Allows trait methods with arbitrary self types.
|
||||
@ -332,7 +330,7 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
||||
/// Allows using and casting function pointers in a `const fn`.
|
||||
(active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
|
||||
/// Allows trait bounds in `const fn`.
|
||||
(active, const_fn_trait_bound, "1.53.0", Some(57563), None),
|
||||
(active, const_fn_trait_bound, "1.53.0", Some(93706), None),
|
||||
/// Allows `for _ in _` loops in const contexts.
|
||||
(active, const_for, "1.56.0", Some(87575), None),
|
||||
/// Allows argument and return position `impl Trait` in a `const fn`.
|
||||
|
@ -403,7 +403,6 @@ pub struct BuiltinAttribute {
|
||||
},
|
||||
|
||||
// Testing:
|
||||
gated!(allow_fail, Normal, template!(Word), WarnFollowing, experimental!(allow_fail)),
|
||||
gated!(
|
||||
test_runner, CrateLevel, template!(List: "path"), ErrorFollowing, custom_test_frameworks,
|
||||
"custom test frameworks are an unstable feature",
|
||||
|
@ -48,6 +48,8 @@ macro_rules! declare_features {
|
||||
(removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
|
||||
Some("merged into `#![feature(slice_patterns)]`")),
|
||||
(removed, allocator, "1.0.0", None, None, None),
|
||||
/// Allows a test to fail without failing the whole suite.
|
||||
(removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")),
|
||||
(removed, await_macro, "1.38.0", Some(50547), None,
|
||||
Some("subsumed by `.await` syntax")),
|
||||
/// Allows comparing raw pointers during const eval.
|
||||
|
@ -2044,19 +2044,8 @@ pub fn report_and_explain_type_error(
|
||||
// If a tuple of length one was expected and the found expression has
|
||||
// parentheses around it, perhaps the user meant to write `(expr,)` to
|
||||
// build a tuple (issue #86100)
|
||||
(ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
|
||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
|
||||
if let Some(code) =
|
||||
code.strip_prefix('(').and_then(|s| s.strip_suffix(')'))
|
||||
{
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"use a trailing comma to create a tuple with one element",
|
||||
format!("({},)", code),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
(ty::Tuple(_), _) => {
|
||||
self.emit_tuple_wrap_err(&mut err, span, found, expected)
|
||||
}
|
||||
// If a character was expected and the found expression is a string literal
|
||||
// containing a single character, perhaps the user meant to write `'c'` to
|
||||
@ -2119,6 +2108,41 @@ pub fn report_and_explain_type_error(
|
||||
diag
|
||||
}
|
||||
|
||||
fn emit_tuple_wrap_err(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
span: Span,
|
||||
found: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
) {
|
||||
let [expected_tup_elem] = &expected.tuple_fields().collect::<Vec<_>>()[..]
|
||||
else { return };
|
||||
|
||||
if !same_type_modulo_infer(expected_tup_elem, found) {
|
||||
return;
|
||||
}
|
||||
|
||||
let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||
else { return };
|
||||
|
||||
let msg = "use a trailing comma to create a tuple with one element";
|
||||
if code.starts_with('(') && code.ends_with(')') {
|
||||
let before_close = span.hi() - BytePos::from_u32(1);
|
||||
err.span_suggestion(
|
||||
span.with_hi(before_close).shrink_to_hi(),
|
||||
msg,
|
||||
",".into(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.multipart_suggestion(
|
||||
msg,
|
||||
vec![(span.shrink_to_lo(), "(".into()), (span.shrink_to_hi(), ",)".into())],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn values_str(
|
||||
&self,
|
||||
values: ValuePairs<'tcx>,
|
||||
|
@ -185,8 +185,6 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::mem::swap;
|
||||
use std::num::FpCategory as Fp;
|
||||
use std::ops::Index;
|
||||
@ -250,7 +248,6 @@ pub enum ErrorCode {
|
||||
pub enum ParserError {
|
||||
/// msg, line, col
|
||||
SyntaxError(ErrorCode, usize, usize),
|
||||
IoError(io::ErrorKind, String),
|
||||
}
|
||||
|
||||
// Builder and Parser have the same errors.
|
||||
@ -329,10 +326,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
fn io_error_to_error(io: io::Error) -> ParserError {
|
||||
IoError(io.kind(), io.to_string())
|
||||
}
|
||||
|
||||
impl fmt::Display for ParserError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// FIXME this should be a nicer error
|
||||
@ -2163,21 +2156,6 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decodes a json value from an `&mut io::Read`
|
||||
pub fn from_reader(rdr: &mut dyn Read) -> Result<Json, BuilderError> {
|
||||
let mut contents = Vec::new();
|
||||
match rdr.read_to_end(&mut contents) {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(io_error_to_error(e)),
|
||||
};
|
||||
let s = match str::from_utf8(&contents).ok() {
|
||||
Some(s) => s,
|
||||
_ => return Err(SyntaxError(NotUtf8, 0, 0)),
|
||||
};
|
||||
let mut builder = Builder::new(s.chars());
|
||||
builder.build()
|
||||
}
|
||||
|
||||
/// Decodes a json value from a string
|
||||
pub fn from_str(s: &str) -> Result<Json, BuilderError> {
|
||||
let mut builder = Builder::new(s.chars());
|
||||
|
@ -2148,8 +2148,8 @@ pub fn search(
|
||||
use std::fs;
|
||||
|
||||
fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
|
||||
let contents = fs::read(path).map_err(|e| e.to_string())?;
|
||||
let obj = json::from_reader(&mut &contents[..]).map_err(|e| e.to_string())?;
|
||||
let contents = fs::read_to_string(path).map_err(|e| e.to_string())?;
|
||||
let obj = json::from_str(&contents).map_err(|e| e.to_string())?;
|
||||
Target::from_json(obj)
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,16 @@ fn add_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const AddAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: $t) {
|
||||
*self = *self + Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Sub for Wrapping<$t> {
|
||||
@ -262,6 +272,16 @@ fn sub_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const SubAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: $t) {
|
||||
*self = *self - Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Mul for Wrapping<$t> {
|
||||
@ -285,6 +305,16 @@ fn mul_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const MulAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, other: $t) {
|
||||
*self = *self * Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "wrapping_div", since = "1.3.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Div for Wrapping<$t> {
|
||||
@ -308,6 +338,16 @@ fn div_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const DivAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, other: $t) {
|
||||
*self = *self / Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "wrapping_impls", since = "1.7.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Rem for Wrapping<$t> {
|
||||
@ -331,6 +371,16 @@ fn rem_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const RemAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn rem_assign(&mut self, other: $t) {
|
||||
*self = *self % Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Not for Wrapping<$t> {
|
||||
@ -367,6 +417,16 @@ fn bitxor_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const BitXorAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn bitxor_assign(&mut self, other: $t) {
|
||||
*self = *self ^ Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const BitOr for Wrapping<$t> {
|
||||
@ -390,6 +450,16 @@ fn bitor_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const BitOrAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn bitor_assign(&mut self, other: $t) {
|
||||
*self = *self | Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const BitAnd for Wrapping<$t> {
|
||||
@ -413,6 +483,16 @@ fn bitand_assign(&mut self, other: Wrapping<$t>) {
|
||||
}
|
||||
forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const BitAndAssign<$t> for Wrapping<$t> {
|
||||
#[inline]
|
||||
fn bitand_assign(&mut self, other: $t) {
|
||||
*self = *self & Wrapping(other);
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t }
|
||||
|
||||
#[stable(feature = "wrapping_neg", since = "1.10.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
impl const Neg for Wrapping<$t> {
|
||||
|
@ -1252,15 +1252,16 @@ pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
|
||||
/// assert!(cstr.is_err());
|
||||
/// ```
|
||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||
pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> {
|
||||
pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
|
||||
let nul_pos = memchr::memchr(0, bytes);
|
||||
if let Some(nul_pos) = nul_pos {
|
||||
if nul_pos + 1 != bytes.len() {
|
||||
return Err(FromBytesWithNulError::interior_nul(nul_pos));
|
||||
match nul_pos {
|
||||
Some(nul_pos) if nul_pos + 1 == bytes.len() => {
|
||||
// SAFETY: We know there is only one nul byte, at the end
|
||||
// of the byte slice.
|
||||
Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
|
||||
}
|
||||
Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) })
|
||||
} else {
|
||||
Err(FromBytesWithNulError::not_nul_terminated())
|
||||
Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
|
||||
None => Err(FromBytesWithNulError::not_nul_terminated()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,6 @@ pub struct ConsoleTestState {
|
||||
pub passed: usize,
|
||||
pub failed: usize,
|
||||
pub ignored: usize,
|
||||
pub allowed_fail: usize,
|
||||
pub filtered_out: usize,
|
||||
pub measured: usize,
|
||||
pub exec_time: Option<TestSuiteExecTime>,
|
||||
@ -71,7 +70,6 @@ pub fn new(opts: &TestOpts) -> io::Result<ConsoleTestState> {
|
||||
passed: 0,
|
||||
failed: 0,
|
||||
ignored: 0,
|
||||
allowed_fail: 0,
|
||||
filtered_out: 0,
|
||||
measured: 0,
|
||||
exec_time: None,
|
||||
@ -112,7 +110,6 @@ pub fn write_log_result(
|
||||
TestResult::TrFailed => "failed".to_owned(),
|
||||
TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
|
||||
TestResult::TrIgnored => "ignored".to_owned(),
|
||||
TestResult::TrAllowedFail => "failed (allowed)".to_owned(),
|
||||
TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
|
||||
TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
|
||||
},
|
||||
@ -126,7 +123,7 @@ pub fn write_log_result(
|
||||
}
|
||||
|
||||
fn current_test_count(&self) -> usize {
|
||||
self.passed + self.failed + self.ignored + self.measured + self.allowed_fail
|
||||
self.passed + self.failed + self.ignored + self.measured
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +188,6 @@ fn handle_test_result(st: &mut ConsoleTestState, completed_test: CompletedTest)
|
||||
st.not_failures.push((test, stdout));
|
||||
}
|
||||
TestResult::TrIgnored => st.ignored += 1,
|
||||
TestResult::TrAllowedFail => st.allowed_fail += 1,
|
||||
TestResult::TrBench(bs) => {
|
||||
st.metrics.insert_metric(
|
||||
test.name.as_slice(),
|
||||
|
@ -124,15 +124,6 @@ fn write_result(
|
||||
self.write_event("test", desc.name.as_slice(), "ignored", exec_time, stdout, None)
|
||||
}
|
||||
|
||||
TestResult::TrAllowedFail => self.write_event(
|
||||
"test",
|
||||
desc.name.as_slice(),
|
||||
"allowed_failure",
|
||||
exec_time,
|
||||
stdout,
|
||||
None,
|
||||
),
|
||||
|
||||
TestResult::TrBench(ref bs) => {
|
||||
let median = bs.ns_iter_summ.median as usize;
|
||||
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
|
||||
@ -172,14 +163,12 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
|
||||
\"event\": \"{}\", \
|
||||
\"passed\": {}, \
|
||||
\"failed\": {}, \
|
||||
\"allowed_fail\": {}, \
|
||||
\"ignored\": {}, \
|
||||
\"measured\": {}, \
|
||||
\"filtered_out\": {}",
|
||||
if state.failed == 0 { "ok" } else { "failed" },
|
||||
state.passed,
|
||||
state.failed + state.allowed_fail,
|
||||
state.allowed_fail,
|
||||
state.failed,
|
||||
state.ignored,
|
||||
state.measured,
|
||||
state.filtered_out,
|
||||
|
@ -121,7 +121,7 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
|
||||
))?;
|
||||
}
|
||||
|
||||
TestResult::TrOk | TestResult::TrAllowedFail => {
|
||||
TestResult::TrOk => {
|
||||
self.write_message(&*format!(
|
||||
"<testcase classname=\"{}\" \
|
||||
name=\"{}\" time=\"{}\"/>",
|
||||
|
@ -49,10 +49,6 @@ pub fn write_ignored(&mut self) -> io::Result<()> {
|
||||
self.write_short_result("ignored", term::color::YELLOW)
|
||||
}
|
||||
|
||||
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
|
||||
self.write_short_result("FAILED (allowed)", term::color::YELLOW)
|
||||
}
|
||||
|
||||
pub fn write_time_failed(&mut self) -> io::Result<()> {
|
||||
self.write_short_result("FAILED (time limit exceeded)", term::color::RED)
|
||||
}
|
||||
@ -219,7 +215,6 @@ fn write_result(
|
||||
TestResult::TrOk => self.write_ok()?,
|
||||
TestResult::TrFailed | TestResult::TrFailedMsg(_) => self.write_failed()?,
|
||||
TestResult::TrIgnored => self.write_ignored()?,
|
||||
TestResult::TrAllowedFail => self.write_allowed_fail()?,
|
||||
TestResult::TrBench(ref bs) => {
|
||||
self.write_bench()?;
|
||||
self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?;
|
||||
@ -263,22 +258,10 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
|
||||
self.write_pretty("FAILED", term::color::RED)?;
|
||||
}
|
||||
|
||||
let s = if state.allowed_fail > 0 {
|
||||
format!(
|
||||
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out",
|
||||
state.passed,
|
||||
state.failed + state.allowed_fail,
|
||||
state.allowed_fail,
|
||||
state.ignored,
|
||||
state.measured,
|
||||
state.filtered_out
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
|
||||
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
|
||||
)
|
||||
};
|
||||
let s = format!(
|
||||
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
|
||||
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
|
||||
);
|
||||
|
||||
self.write_plain(&s)?;
|
||||
|
||||
|
@ -54,10 +54,6 @@ pub fn write_ignored(&mut self) -> io::Result<()> {
|
||||
self.write_short_result("i", term::color::YELLOW)
|
||||
}
|
||||
|
||||
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
|
||||
self.write_short_result("a", term::color::YELLOW)
|
||||
}
|
||||
|
||||
pub fn write_bench(&mut self) -> io::Result<()> {
|
||||
self.write_pretty("bench", term::color::CYAN)
|
||||
}
|
||||
@ -207,7 +203,6 @@ fn write_result(
|
||||
self.write_failed()
|
||||
}
|
||||
TestResult::TrIgnored => self.write_ignored(),
|
||||
TestResult::TrAllowedFail => self.write_allowed_fail(),
|
||||
TestResult::TrBench(ref bs) => {
|
||||
if self.is_multithreaded {
|
||||
self.write_test_name(desc)?;
|
||||
@ -244,22 +239,10 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
|
||||
self.write_pretty("FAILED", term::color::RED)?;
|
||||
}
|
||||
|
||||
let s = if state.allowed_fail > 0 {
|
||||
format!(
|
||||
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out",
|
||||
state.passed,
|
||||
state.failed + state.allowed_fail,
|
||||
state.allowed_fail,
|
||||
state.ignored,
|
||||
state.measured,
|
||||
state.filtered_out
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
|
||||
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
|
||||
)
|
||||
};
|
||||
let s = format!(
|
||||
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
|
||||
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
|
||||
);
|
||||
|
||||
self.write_plain(&s)?;
|
||||
|
||||
|
@ -19,7 +19,6 @@ pub enum TestResult {
|
||||
TrFailed,
|
||||
TrFailedMsg(String),
|
||||
TrIgnored,
|
||||
TrAllowedFail,
|
||||
TrBench(BenchSamples),
|
||||
TrTimedFail,
|
||||
}
|
||||
@ -42,8 +41,6 @@ pub fn calc_result<'a>(
|
||||
|
||||
if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) {
|
||||
TestResult::TrOk
|
||||
} else if desc.allow_fail {
|
||||
TestResult::TrAllowedFail
|
||||
} else if let Some(panic_str) = maybe_panic_str {
|
||||
TestResult::TrFailedMsg(format!(
|
||||
r#"panic did not contain expected string
|
||||
@ -64,7 +61,6 @@ pub fn calc_result<'a>(
|
||||
(&ShouldPanic::Yes, Ok(())) | (&ShouldPanic::YesWithMessage(_), Ok(())) => {
|
||||
TestResult::TrFailedMsg("test did not panic as expected".to_string())
|
||||
}
|
||||
_ if desc.allow_fail => TestResult::TrAllowedFail,
|
||||
_ => TestResult::TrFailed,
|
||||
};
|
||||
|
||||
@ -90,11 +86,10 @@ pub fn get_result_from_exit_code(
|
||||
time_opts: &Option<time::TestTimeOptions>,
|
||||
exec_time: &Option<time::TestExecTime>,
|
||||
) -> TestResult {
|
||||
let result = match (desc.allow_fail, code) {
|
||||
(_, TR_OK) => TestResult::TrOk,
|
||||
(true, TR_FAILED) => TestResult::TrAllowedFail,
|
||||
(false, TR_FAILED) => TestResult::TrFailed,
|
||||
(_, _) => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
|
||||
let result = match code {
|
||||
TR_OK => TestResult::TrOk,
|
||||
TR_FAILED => TestResult::TrFailed,
|
||||
_ => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
|
||||
};
|
||||
|
||||
// If test is already failed (or allowed to fail), do not change the result.
|
||||
|
@ -62,10 +62,11 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
|
||||
name: StaticTestName("1"),
|
||||
ignore: true,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(move || {})),
|
||||
},
|
||||
@ -74,10 +75,11 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
|
||||
name: StaticTestName("2"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(move || {})),
|
||||
},
|
||||
@ -94,10 +96,11 @@ fn f() {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: true,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -115,10 +118,11 @@ fn f() {}
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: true,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -140,10 +144,11 @@ fn f() {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::Yes,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -165,10 +170,11 @@ fn f() {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::YesWithMessage("error message"),
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -195,10 +201,11 @@ fn f() {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::YesWithMessage(expected),
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -229,10 +236,11 @@ fn f() {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::YesWithMessage(expected),
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -255,10 +263,11 @@ fn f() {}
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -289,10 +298,11 @@ fn f() {}
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -324,10 +334,11 @@ fn f() {}
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
@ -363,10 +374,11 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,10 +488,11 @@ pub fn exclude_should_panic_option() {
|
||||
name: StaticTestName("3"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::Yes,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(move || {})),
|
||||
});
|
||||
@ -500,10 +513,11 @@ fn tests() -> Vec<TestDescAndFn> {
|
||||
name: StaticTestName(name),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(move || {})),
|
||||
})
|
||||
@ -589,10 +603,11 @@ fn testfn() {}
|
||||
name: DynTestName((*name).clone()),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(testfn)),
|
||||
};
|
||||
@ -740,10 +755,11 @@ fn f(_: &mut Bencher) {}
|
||||
name: StaticTestName("f"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
};
|
||||
|
||||
crate::bench::benchmark(TestId(0), desc, tx, true, f);
|
||||
@ -762,10 +778,11 @@ fn f(b: &mut Bencher) {
|
||||
name: StaticTestName("f"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
};
|
||||
|
||||
crate::bench::benchmark(TestId(0), desc, tx, true, f);
|
||||
@ -778,20 +795,22 @@ fn should_sort_failures_before_printing_them() {
|
||||
name: StaticTestName("a"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
};
|
||||
|
||||
let test_b = TestDesc {
|
||||
name: StaticTestName("b"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::No,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
};
|
||||
|
||||
let mut out = PrettyFormatter::new(OutputLocation::Raw(Vec::new()), false, 10, false, None);
|
||||
@ -802,7 +821,6 @@ fn should_sort_failures_before_printing_them() {
|
||||
passed: 0,
|
||||
failed: 0,
|
||||
ignored: 0,
|
||||
allowed_fail: 0,
|
||||
filtered_out: 0,
|
||||
measured: 0,
|
||||
exec_time: None,
|
||||
|
@ -118,10 +118,11 @@ pub struct TestDesc {
|
||||
pub name: TestName,
|
||||
pub ignore: bool,
|
||||
pub should_panic: options::ShouldPanic,
|
||||
pub allow_fail: bool,
|
||||
pub compile_fail: bool,
|
||||
pub no_run: bool,
|
||||
pub test_type: TestType,
|
||||
#[cfg(bootstrap)]
|
||||
pub allow_fail: bool,
|
||||
}
|
||||
|
||||
impl TestDesc {
|
||||
@ -150,9 +151,6 @@ pub fn test_mode(&self) -> Option<&'static str> {
|
||||
}
|
||||
options::ShouldPanic::No => {}
|
||||
}
|
||||
if self.allow_fail {
|
||||
return Some("allow fail");
|
||||
}
|
||||
if self.compile_fail {
|
||||
return Some("compile fail");
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ fn main() {
|
||||
println!("{}", suggestion);
|
||||
}
|
||||
|
||||
let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
|
||||
Build::new(config).build();
|
||||
|
||||
if suggest_setup {
|
||||
@ -42,6 +43,19 @@ fn main() {
|
||||
println!("{}", suggestion);
|
||||
}
|
||||
|
||||
// Give a warning if the pre-commit script is in pre-commit and not pre-push.
|
||||
// HACK: Since the commit script uses hard links, we can't actually tell if it was installed by x.py setup or not.
|
||||
// We could see if it's identical to src/etc/pre-push.sh, but pre-push may have been modified in the meantime.
|
||||
// Instead, look for this comment, which is almost certainly not in any custom hook.
|
||||
if std::fs::read_to_string(pre_commit).map_or(false, |contents| {
|
||||
contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
|
||||
}) {
|
||||
println!(
|
||||
"warning: You have the pre-push script installed to .git/hooks/pre-commit. \
|
||||
Consider moving it to .git/hooks/pre-push instead, which runs less often."
|
||||
);
|
||||
}
|
||||
|
||||
if suggest_setup || changelog_suggestion.is_some() {
|
||||
println!("note: this message was printed twice to make it more likely to be seen");
|
||||
}
|
||||
|
@ -1221,9 +1221,9 @@ def bootstrap(help_triggered):
|
||||
build.verbose = args.verbose
|
||||
build.clean = args.clean
|
||||
|
||||
# Read from `RUST_BOOTSTRAP_CONFIG`, then `--config`, then fallback to `config.toml` (if it
|
||||
# Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then fallback to `config.toml` (if it
|
||||
# exists).
|
||||
toml_path = os.getenv('RUST_BOOTSTRAP_CONFIG') or args.config
|
||||
toml_path = args.config or os.getenv('RUST_BOOTSTRAP_CONFIG')
|
||||
if not toml_path and os.path.exists('config.toml'):
|
||||
toml_path = 'config.toml'
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-env-changed=RUSTC");
|
||||
println!("cargo:rerun-if-env-changed=PATH");
|
||||
println!("cargo:rustc-env=BUILD_TRIPLE={}", env::var("HOST").unwrap());
|
||||
|
||||
// This may not be a canonicalized path.
|
||||
|
@ -527,7 +527,7 @@ fn dir_is_empty(dir: &Path) -> bool {
|
||||
// Try passing `--progress` to start, then run git again without if that fails.
|
||||
let update = |progress: bool| {
|
||||
let mut git = Command::new("git");
|
||||
git.args(&["submodule", "update", "--init", "--recursive"]);
|
||||
git.args(&["submodule", "update", "--init", "--recursive", "--depth=1"]);
|
||||
if progress {
|
||||
git.arg("--progress");
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
use crate::TargetSelection;
|
||||
use crate::{t, VERSION};
|
||||
use std::env::consts::EXE_SUFFIX;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs::File;
|
||||
use std::path::{Path, PathBuf, MAIN_SEPARATOR};
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::{
|
||||
@ -109,7 +111,8 @@ pub fn setup(src_path: &Path, profile: Profile) {
|
||||
println!("`x.py` will now use the configuration at {}", include_path.display());
|
||||
|
||||
let build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
|
||||
let stage_path = ["build", build.rustc_target_arg(), "stage1"].join("/");
|
||||
let stage_path =
|
||||
["build", build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
|
||||
|
||||
println!();
|
||||
|
||||
@ -171,6 +174,13 @@ fn attempt_toolchain_link(stage_path: &str) {
|
||||
return;
|
||||
}
|
||||
|
||||
if !ensure_stage1_toolchain_placeholder_exists(stage_path) {
|
||||
println!(
|
||||
"Failed to create a template for stage 1 toolchain or confirm that it already exists"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if try_link_toolchain(&stage_path[..]) {
|
||||
println!(
|
||||
"Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
|
||||
@ -219,6 +229,33 @@ fn try_link_toolchain(stage_path: &str) -> bool {
|
||||
.map_or(false, |output| output.status.success())
|
||||
}
|
||||
|
||||
fn ensure_stage1_toolchain_placeholder_exists(stage_path: &str) -> bool {
|
||||
let pathbuf = PathBuf::from(stage_path);
|
||||
|
||||
if fs::create_dir_all(pathbuf.join("lib")).is_err() {
|
||||
return false;
|
||||
};
|
||||
|
||||
let pathbuf = pathbuf.join("bin");
|
||||
if fs::create_dir_all(&pathbuf).is_err() {
|
||||
return false;
|
||||
};
|
||||
|
||||
let pathbuf = pathbuf.join(format!("rustc{}", EXE_SUFFIX));
|
||||
|
||||
if pathbuf.exists() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Take care not to overwrite the file
|
||||
let result = File::options().append(true).create(true).open(&pathbuf);
|
||||
if result.is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Used to get the path for `Subcommand::Setup`
|
||||
pub fn interactive_path() -> io::Result<Profile> {
|
||||
fn abbrev_all() -> impl Iterator<Item = ((String, String), Profile)> {
|
||||
@ -271,9 +308,9 @@ fn install_git_hook_maybe(src_path: &Path) -> io::Result<()> {
|
||||
let mut input = String::new();
|
||||
println!(
|
||||
"Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
|
||||
If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` on each commit
|
||||
to ensure your code is up to par. If you decide later that this behavior is undesirable,
|
||||
simply delete the `pre-commit` file from .git/hooks."
|
||||
If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` before
|
||||
pushing your code to ensure your code is up to par. If you decide later that this behavior is
|
||||
undesirable, simply delete the `pre-push` file from .git/hooks."
|
||||
);
|
||||
|
||||
let should_install = loop {
|
||||
@ -293,21 +330,21 @@ fn install_git_hook_maybe(src_path: &Path) -> io::Result<()> {
|
||||
};
|
||||
|
||||
if should_install {
|
||||
let src = src_path.join("src").join("etc").join("pre-commit.sh");
|
||||
let src = src_path.join("src").join("etc").join("pre-push.sh");
|
||||
let git = t!(Command::new("git").args(&["rev-parse", "--git-common-dir"]).output().map(
|
||||
|output| {
|
||||
assert!(output.status.success(), "failed to run `git`");
|
||||
PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
|
||||
}
|
||||
));
|
||||
let dst = git.join("hooks").join("pre-commit");
|
||||
let dst = git.join("hooks").join("pre-push");
|
||||
match fs::hard_link(src, &dst) {
|
||||
Err(e) => println!(
|
||||
"error: could not create hook {}: do you already have the git hook installed?\n{}",
|
||||
dst.display(),
|
||||
e
|
||||
),
|
||||
Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-commit`"),
|
||||
Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-push`"),
|
||||
};
|
||||
} else {
|
||||
println!("Ok, skipping installation!");
|
||||
|
@ -16,7 +16,7 @@ if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
||||
COMMAND="python $COMMAND"
|
||||
fi
|
||||
|
||||
echo "Running pre-commit script '$COMMAND'"
|
||||
echo "Running pre-push script '$COMMAND'"
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
@ -951,10 +951,11 @@ fn add_test(&mut self, test: String, config: LangString, line: usize) {
|
||||
},
|
||||
// compiler failures are test failures
|
||||
should_panic: test::ShouldPanic::No,
|
||||
allow_fail: config.allow_fail,
|
||||
compile_fail: config.compile_fail,
|
||||
no_run,
|
||||
test_type: test::TestType::DocTest,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
},
|
||||
testfn: test::DynTestFn(box move || {
|
||||
let report_unused_externs = |uext| {
|
||||
|
@ -847,7 +847,6 @@ fn error_invalid_codeblock_attr(&self, msg: &str, help: &str) {
|
||||
crate test_harness: bool,
|
||||
crate compile_fail: bool,
|
||||
crate error_codes: Vec<String>,
|
||||
crate allow_fail: bool,
|
||||
crate edition: Option<Edition>,
|
||||
}
|
||||
|
||||
@ -869,7 +868,6 @@ fn default() -> Self {
|
||||
test_harness: false,
|
||||
compile_fail: false,
|
||||
error_codes: Vec::new(),
|
||||
allow_fail: false,
|
||||
edition: None,
|
||||
}
|
||||
}
|
||||
@ -943,10 +941,6 @@ fn parse(
|
||||
seen_rust_tags = !seen_other_tags;
|
||||
}
|
||||
}
|
||||
"allow_fail" => {
|
||||
data.allow_fail = true;
|
||||
seen_rust_tags = !seen_other_tags;
|
||||
}
|
||||
"rust" => {
|
||||
data.rust = true;
|
||||
seen_rust_tags = true;
|
||||
@ -994,12 +988,6 @@ fn parse(
|
||||
"the code block will either not be tested if not marked as a rust one \
|
||||
or will be run (which you might not want)",
|
||||
))
|
||||
} else if s == "allow-fail" || s == "allow_fail" || s == "allowfail" {
|
||||
Some((
|
||||
"allow_fail",
|
||||
"the code block will either not be tested if not marked as a rust one \
|
||||
or will be run (which you might not want)",
|
||||
))
|
||||
} else if s == "test-harness" || s == "test_harness" || s == "testharness" {
|
||||
Some((
|
||||
"test_harness",
|
||||
|
@ -70,7 +70,6 @@ fn t(lg: LangString) {
|
||||
compile_fail: true,
|
||||
..Default::default()
|
||||
});
|
||||
t(LangString { original: "allow_fail".into(), allow_fail: true, ..Default::default() });
|
||||
t(LangString { original: "no_run,example".into(), no_run: true, ..Default::default() });
|
||||
t(LangString {
|
||||
original: "sh,should_panic".into(),
|
||||
|
@ -472,6 +472,7 @@ nav.sub {
|
||||
}
|
||||
.block ul, .block li {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
@ -502,8 +503,6 @@ nav.sub {
|
||||
font-weight: 500;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.sidebar-links,
|
||||
|
@ -559,7 +559,15 @@ function hideThemeButtonState() {
|
||||
others.appendChild(div);
|
||||
}
|
||||
|
||||
function block(shortty, longty) {
|
||||
/**
|
||||
* Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
|
||||
*
|
||||
* @param {string} shortty - A short type name, like "primitive", "mod", or "macro"
|
||||
* @param {string} id - The HTML id of the corresponding section on the module page.
|
||||
* @param {string} longty - A long, capitalized, plural name, like "Primitive Types",
|
||||
* "Modules", or "Macros".
|
||||
*/
|
||||
function block(shortty, id, longty) {
|
||||
var filtered = items[shortty];
|
||||
if (!filtered) {
|
||||
return;
|
||||
@ -568,7 +576,7 @@ function hideThemeButtonState() {
|
||||
var div = document.createElement("div");
|
||||
div.className = "block " + shortty;
|
||||
var h3 = document.createElement("h3");
|
||||
h3.textContent = longty;
|
||||
h3.innerHTML = `<a href="index.html#${id}">${longty}</a>`;
|
||||
div.appendChild(h3);
|
||||
var ul = document.createElement("ul");
|
||||
|
||||
@ -607,20 +615,20 @@ function hideThemeButtonState() {
|
||||
|
||||
var isModule = hasClass(document.body, "mod");
|
||||
if (!isModule) {
|
||||
block("primitive", "Primitive Types");
|
||||
block("mod", "Modules");
|
||||
block("macro", "Macros");
|
||||
block("struct", "Structs");
|
||||
block("enum", "Enums");
|
||||
block("union", "Unions");
|
||||
block("constant", "Constants");
|
||||
block("static", "Statics");
|
||||
block("trait", "Traits");
|
||||
block("fn", "Functions");
|
||||
block("type", "Type Definitions");
|
||||
block("foreigntype", "Foreign Types");
|
||||
block("keyword", "Keywords");
|
||||
block("traitalias", "Trait Aliases");
|
||||
block("primitive", "primitives", "Primitive Types");
|
||||
block("mod", "modules", "Modules");
|
||||
block("macro", "macros", "Macros");
|
||||
block("struct", "structs", "Structs");
|
||||
block("enum", "enums", "Enums");
|
||||
block("union", "unions", "Unions");
|
||||
block("constant", "constants", "Constants");
|
||||
block("static", "static", "Statics");
|
||||
block("trait", "traits", "Traits");
|
||||
block("fn", "functions", "Functions");
|
||||
block("type", "types", "Type Definitions");
|
||||
block("foreigntype", "foreign-types", "Foreign Types");
|
||||
block("keyword", "keywords", "Keywords");
|
||||
block("traitalias", "trait-aliases", "Trait Aliases");
|
||||
}
|
||||
|
||||
// `crates{version}.js` should always be loaded before this script, so we can use
|
||||
|
@ -7,4 +7,4 @@
|
||||
{ "type": "test", "name": "c", "event": "ok" }
|
||||
{ "type": "test", "event": "started", "name": "d" }
|
||||
{ "type": "test", "name": "d", "event": "ignored" }
|
||||
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
|
||||
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
|
||||
|
@ -7,4 +7,4 @@
|
||||
{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
|
||||
{ "type": "test", "event": "started", "name": "d" }
|
||||
{ "type": "test", "name": "d", "event": "ignored" }
|
||||
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
|
||||
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
|
||||
|
@ -39,4 +39,4 @@ assert-position: ("#method\.must_use", {"y": 45})
|
||||
// Check that the bottom-most item on the sidebar menu can be scrolled fully into view.
|
||||
click: ".sidebar-menu-toggle"
|
||||
scroll-to: ".block.keyword li:nth-child(1)"
|
||||
assert-position: (".block.keyword li:nth-child(1)", {"y": 542.96875})
|
||||
assert-position: (".block.keyword li:nth-child(1)", {"y": 542.234375})
|
||||
|
@ -78,3 +78,10 @@ assert-text: ("#functions + .item-table .item-left > a", "foo")
|
||||
// Links to trait implementations in the sidebar should not wrap even if they are long.
|
||||
goto: file://|DOC_PATH|/lib2/struct.HasALongTraitWithParams.html
|
||||
assert-property: (".sidebar-links a", {"offsetHeight": 29})
|
||||
|
||||
// Test that clicking on of the "In <module>" headings in the sidebar links to the
|
||||
// appropriate anchor in index.html.
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html
|
||||
click: ".block.mod h3 a"
|
||||
// PAGE: index.html
|
||||
assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"})
|
||||
|
@ -23,13 +23,6 @@ pub fn bar() {}
|
||||
/// ```
|
||||
pub fn foobar() {}
|
||||
|
||||
/// barfoo
|
||||
///
|
||||
/// ```allow-fail,allowfail,allOw_fail
|
||||
/// boo
|
||||
/// ```
|
||||
pub fn barfoo() {}
|
||||
|
||||
/// b
|
||||
///
|
||||
/// ```test-harness,testharness,tesT_harness
|
||||
|
@ -111,77 +111,41 @@ error: unknown attribute `nO_run`. Did you mean `no_run`?
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `allow-fail`. Did you mean `allow_fail`?
|
||||
--> $DIR/check-attr-test.rs:26:1
|
||||
|
|
||||
26 | / /// barfoo
|
||||
27 | | ///
|
||||
28 | | /// ```allow-fail,allowfail,allOw_fail
|
||||
29 | | /// boo
|
||||
30 | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `allowfail`. Did you mean `allow_fail`?
|
||||
--> $DIR/check-attr-test.rs:26:1
|
||||
|
|
||||
26 | / /// barfoo
|
||||
27 | | ///
|
||||
28 | | /// ```allow-fail,allowfail,allOw_fail
|
||||
29 | | /// boo
|
||||
30 | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `allOw_fail`. Did you mean `allow_fail`?
|
||||
--> $DIR/check-attr-test.rs:26:1
|
||||
|
|
||||
26 | / /// barfoo
|
||||
27 | | ///
|
||||
28 | | /// ```allow-fail,allowfail,allOw_fail
|
||||
29 | | /// boo
|
||||
30 | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `test-harness`. Did you mean `test_harness`?
|
||||
--> $DIR/check-attr-test.rs:33:1
|
||||
--> $DIR/check-attr-test.rs:26:1
|
||||
|
|
||||
33 | / /// b
|
||||
34 | | ///
|
||||
35 | | /// ```test-harness,testharness,tesT_harness
|
||||
36 | | /// boo
|
||||
37 | | /// ```
|
||||
26 | / /// b
|
||||
27 | | ///
|
||||
28 | | /// ```test-harness,testharness,tesT_harness
|
||||
29 | | /// boo
|
||||
30 | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
|
||||
|
||||
error: unknown attribute `testharness`. Did you mean `test_harness`?
|
||||
--> $DIR/check-attr-test.rs:33:1
|
||||
--> $DIR/check-attr-test.rs:26:1
|
||||
|
|
||||
33 | / /// b
|
||||
34 | | ///
|
||||
35 | | /// ```test-harness,testharness,tesT_harness
|
||||
36 | | /// boo
|
||||
37 | | /// ```
|
||||
26 | / /// b
|
||||
27 | | ///
|
||||
28 | | /// ```test-harness,testharness,tesT_harness
|
||||
29 | | /// boo
|
||||
30 | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
|
||||
|
||||
error: unknown attribute `tesT_harness`. Did you mean `test_harness`?
|
||||
--> $DIR/check-attr-test.rs:33:1
|
||||
--> $DIR/check-attr-test.rs:26:1
|
||||
|
|
||||
33 | / /// b
|
||||
34 | | ///
|
||||
35 | | /// ```test-harness,testharness,tesT_harness
|
||||
36 | | /// boo
|
||||
37 | | /// ```
|
||||
26 | / /// b
|
||||
27 | | ///
|
||||
28 | | /// ```test-harness,testharness,tesT_harness
|
||||
29 | | /// boo
|
||||
30 | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
@ -30,16 +30,6 @@ pub fn bar() {}
|
||||
/// ```
|
||||
pub fn foobar() {}
|
||||
|
||||
/// barfoo
|
||||
//~^ ERROR
|
||||
//~^^ ERROR
|
||||
//~^^^ ERROR
|
||||
///
|
||||
/// ```allow-fail,allowfail,alLow_fail
|
||||
/// boo
|
||||
/// ```
|
||||
pub fn barfoo() {}
|
||||
|
||||
/// b
|
||||
//~^ ERROR
|
||||
//~^^ ERROR
|
||||
|
@ -129,50 +129,8 @@ LL | | /// ```
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `allow-fail`. Did you mean `allow_fail`?
|
||||
--> $DIR/check-attr.rs:33:1
|
||||
|
|
||||
LL | / /// barfoo
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | /// boo
|
||||
LL | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `allowfail`. Did you mean `allow_fail`?
|
||||
--> $DIR/check-attr.rs:33:1
|
||||
|
|
||||
LL | / /// barfoo
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | /// boo
|
||||
LL | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `alLow_fail`. Did you mean `allow_fail`?
|
||||
--> $DIR/check-attr.rs:33:1
|
||||
|
|
||||
LL | / /// barfoo
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | /// boo
|
||||
LL | | /// ```
|
||||
| |_______^
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
|
||||
|
||||
error: unknown attribute `test-harness`. Did you mean `test_harness`?
|
||||
--> $DIR/check-attr.rs:43:1
|
||||
--> $DIR/check-attr.rs:33:1
|
||||
|
|
||||
LL | / /// b
|
||||
LL | |
|
||||
@ -186,7 +144,7 @@ LL | | /// ```
|
||||
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
|
||||
|
||||
error: unknown attribute `testharness`. Did you mean `test_harness`?
|
||||
--> $DIR/check-attr.rs:43:1
|
||||
--> $DIR/check-attr.rs:33:1
|
||||
|
|
||||
LL | / /// b
|
||||
LL | |
|
||||
@ -200,7 +158,7 @@ LL | | /// ```
|
||||
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
|
||||
|
||||
error: unknown attribute `teSt_harness`. Did you mean `test_harness`?
|
||||
--> $DIR/check-attr.rs:43:1
|
||||
--> $DIR/check-attr.rs:33:1
|
||||
|
|
||||
LL | / /// b
|
||||
LL | |
|
||||
@ -213,5 +171,5 @@ LL | | /// ```
|
||||
|
|
||||
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
@ -6,6 +6,10 @@ LL | const TUP: (usize,) = 5usize << 64;
|
||||
|
|
||||
= note: expected tuple `(usize,)`
|
||||
found type `usize`
|
||||
help: use a trailing comma to create a tuple with one element
|
||||
|
|
||||
LL | const TUP: (usize,) = (5usize << 64,);
|
||||
| + ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
|
||||
LL | const fn test1<T: std::ops::Add>() {}
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -13,7 +13,7 @@ error[E0658]: trait objects in const fn are unstable
|
||||
LL | const fn test2(_x: &dyn Send) {}
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -22,7 +22,7 @@ error[E0658]: trait objects in const fn are unstable
|
||||
LL | const fn test3() -> &'static dyn Send { loop {} }
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -136,7 +136,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
|
||||
LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
@ -145,7 +145,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
|
||||
LL | const fn foo11_2<T: Send>(t: T) -> T { t }
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0013]: constant functions cannot refer to statics
|
||||
@ -218,7 +218,7 @@ LL |
|
||||
LL | const fn foo(&self) {}
|
||||
| ------------------- function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
@ -230,7 +230,7 @@ LL |
|
||||
LL | const fn foo2(&self) {}
|
||||
| -------------------- function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
@ -242,7 +242,7 @@ LL |
|
||||
LL | const fn foo3(&self) {}
|
||||
| -------------------- function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
@ -251,7 +251,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
|
||||
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
@ -268,7 +268,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
|
||||
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
@ -285,7 +285,7 @@ error[E0658]: trait objects in const fn are unstable
|
||||
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -294,7 +294,7 @@ error[E0658]: trait objects in const fn are unstable
|
||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -305,7 +305,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
|
||||
| |
|
||||
| function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -316,7 +316,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
|
||||
| |
|
||||
| function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -327,7 +327,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
|
||||
| |
|
||||
| function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
|
@ -6,7 +6,7 @@ LL | const fn no_inner_dyn_trait2(x: Hide) {
|
||||
LL | x.0.field;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: trait objects in const fn are unstable
|
||||
@ -17,7 +17,7 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||
| |
|
||||
| function declared as const here
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,8 +0,0 @@
|
||||
// check that #[allow_fail] is feature-gated
|
||||
|
||||
#[allow_fail] //~ ERROR the `#[allow_fail]` attribute is an experimental feature
|
||||
fn ok_to_fail() {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,12 +0,0 @@
|
||||
error[E0658]: the `#[allow_fail]` attribute is an experimental feature
|
||||
--> $DIR/feature-gate-allow_fail.rs:3:1
|
||||
|
|
||||
LL | #[allow_fail]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #46488 <https://github.com/rust-lang/rust/issues/46488> for more information
|
||||
= help: add `#![feature(allow_fail)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
11
src/test/ui/fmt/format-args-capture-issue-93378.rs
Normal file
11
src/test/ui/fmt/format-args-capture-issue-93378.rs
Normal file
@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
let a = "a";
|
||||
let b = "b";
|
||||
|
||||
println!("{a} {b} {} {} {c} {}", c = "c");
|
||||
//~^ ERROR: invalid reference to positional arguments 1 and 2 (there is 1 argument)
|
||||
|
||||
let n = 1;
|
||||
println!("{a:.n$} {b:.*}");
|
||||
//~^ ERROR: invalid reference to positional argument 0 (no arguments were given)
|
||||
}
|
22
src/test/ui/fmt/format-args-capture-issue-93378.stderr
Normal file
22
src/test/ui/fmt/format-args-capture-issue-93378.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error: invalid reference to positional arguments 1 and 2 (there is 1 argument)
|
||||
--> $DIR/format-args-capture-issue-93378.rs:5:26
|
||||
|
|
||||
LL | println!("{a} {b} {} {} {c} {}", c = "c");
|
||||
| ^^ ^^
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
|
||||
error: invalid reference to positional argument 0 (no arguments were given)
|
||||
--> $DIR/format-args-capture-issue-93378.rs:9:23
|
||||
|
|
||||
LL | println!("{a:.n$} {b:.*}");
|
||||
| ------- ^^^--^
|
||||
| | |
|
||||
| | this precision flag adds an extra required argument at position 0, which is why there are 3 arguments expected
|
||||
| this parameter corresponds to the precision flag
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -5,6 +5,7 @@ fn main() {
|
||||
named_argument_takes_precedence_to_captured();
|
||||
formatting_parameters_can_be_captured();
|
||||
capture_raw_strings_and_idents();
|
||||
repeated_capture();
|
||||
|
||||
#[cfg(panic = "unwind")]
|
||||
{
|
||||
@ -80,3 +81,10 @@ fn formatting_parameters_can_be_captured() {
|
||||
let s = format!("{x:-^width$.precision$}");
|
||||
assert_eq!(&s, "--7.000--");
|
||||
}
|
||||
|
||||
fn repeated_capture() {
|
||||
let a = 1;
|
||||
let b = 2;
|
||||
let s = format!("{a} {b} {a}");
|
||||
assert_eq!(&s, "1 2 1");
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ error[E0658]: trait objects in const fn are unstable
|
||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
|
||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -10,6 +10,12 @@ fn main() {
|
||||
|
||||
let _: Option<(i8,)> = Some();
|
||||
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
|
||||
|
||||
let _: Option<(i32,)> = Some(5_usize);
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
let _: Option<(i32,)> = Some((5_usize));
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn int_bool(_: (i32, bool)) {
|
||||
|
@ -15,7 +15,7 @@ LL | int_bool(1, 2);
|
||||
| expected 1 argument
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/args-instead-of-tuple-errors.rs:15:4
|
||||
--> $DIR/args-instead-of-tuple-errors.rs:21:4
|
||||
|
|
||||
LL | fn int_bool(_: (i32, bool)) {
|
||||
| ^^^^^^^^ --------------
|
||||
@ -28,6 +28,25 @@ LL | let _: Option<(i8,)> = Some();
|
||||
| |
|
||||
| expected 1 argument
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/args-instead-of-tuple-errors.rs:14:34
|
||||
|
|
||||
LL | let _: Option<(i32,)> = Some(5_usize);
|
||||
| ^^^^^^^ expected tuple, found `usize`
|
||||
|
|
||||
= note: expected tuple `(i32,)`
|
||||
found type `usize`
|
||||
|
||||
For more information about this error, try `rustc --explain E0061`.
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/args-instead-of-tuple-errors.rs:17:34
|
||||
|
|
||||
LL | let _: Option<(i32,)> = Some((5_usize));
|
||||
| ^^^^^^^^^ expected tuple, found `usize`
|
||||
|
|
||||
= note: expected tuple `(i32,)`
|
||||
found type `usize`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0061, E0308.
|
||||
For more information about an error, try `rustc --explain E0061`.
|
||||
|
@ -11,6 +11,12 @@ fn main() {
|
||||
let _: Option<()> = Some(());
|
||||
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
|
||||
|
||||
let _: Option<(i32,)> = Some((3,));
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
let _: Option<(i32,)> = Some((3,));
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
two_ints((1, 2)); //~ ERROR this function takes 1 argument
|
||||
|
||||
with_generic((3, 4)); //~ ERROR this function takes 1 argument
|
||||
|
@ -11,6 +11,12 @@ fn main() {
|
||||
let _: Option<()> = Some();
|
||||
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
|
||||
|
||||
let _: Option<(i32,)> = Some(3);
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
let _: Option<(i32,)> = Some((3));
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
two_ints(1, 2); //~ ERROR this function takes 1 argument
|
||||
|
||||
with_generic(3, 4); //~ ERROR this function takes 1 argument
|
||||
|
@ -31,14 +31,40 @@ help: expected the unit value `()`; create it with empty parentheses
|
||||
LL | let _: Option<()> = Some(());
|
||||
| ++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/args-instead-of-tuple.rs:14:34
|
||||
|
|
||||
LL | let _: Option<(i32,)> = Some(3);
|
||||
| ^ expected tuple, found integer
|
||||
|
|
||||
= note: expected tuple `(i32,)`
|
||||
found type `{integer}`
|
||||
help: use a trailing comma to create a tuple with one element
|
||||
|
|
||||
LL | let _: Option<(i32,)> = Some((3,));
|
||||
| + ++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/args-instead-of-tuple.rs:17:34
|
||||
|
|
||||
LL | let _: Option<(i32,)> = Some((3));
|
||||
| ^^^ expected tuple, found integer
|
||||
|
|
||||
= note: expected tuple `(i32,)`
|
||||
found type `{integer}`
|
||||
help: use a trailing comma to create a tuple with one element
|
||||
|
|
||||
LL | let _: Option<(i32,)> = Some((3,));
|
||||
| +
|
||||
|
||||
error[E0061]: this function takes 1 argument but 2 arguments were supplied
|
||||
--> $DIR/args-instead-of-tuple.rs:14:5
|
||||
--> $DIR/args-instead-of-tuple.rs:20:5
|
||||
|
|
||||
LL | two_ints(1, 2);
|
||||
| ^^^^^^^^ - - supplied 2 arguments
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/args-instead-of-tuple.rs:19:4
|
||||
--> $DIR/args-instead-of-tuple.rs:25:4
|
||||
|
|
||||
LL | fn two_ints(_: (i32, i32)) {
|
||||
| ^^^^^^^^ -------------
|
||||
@ -48,13 +74,13 @@ LL | two_ints((1, 2));
|
||||
| + +
|
||||
|
||||
error[E0061]: this function takes 1 argument but 2 arguments were supplied
|
||||
--> $DIR/args-instead-of-tuple.rs:16:5
|
||||
--> $DIR/args-instead-of-tuple.rs:22:5
|
||||
|
|
||||
LL | with_generic(3, 4);
|
||||
| ^^^^^^^^^^^^ - - supplied 2 arguments
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/args-instead-of-tuple.rs:22:4
|
||||
--> $DIR/args-instead-of-tuple.rs:28:4
|
||||
|
|
||||
LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
|
||||
| ^^^^^^^^^^^^ ----------------
|
||||
@ -64,13 +90,13 @@ LL | with_generic((3, 4));
|
||||
| + +
|
||||
|
||||
error[E0061]: this function takes 1 argument but 2 arguments were supplied
|
||||
--> $DIR/args-instead-of-tuple.rs:25:9
|
||||
--> $DIR/args-instead-of-tuple.rs:31:9
|
||||
|
|
||||
LL | with_generic(a, b);
|
||||
| ^^^^^^^^^^^^ - - supplied 2 arguments
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/args-instead-of-tuple.rs:22:4
|
||||
--> $DIR/args-instead-of-tuple.rs:28:4
|
||||
|
|
||||
LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
|
||||
| ^^^^^^^^^^^^ ----------------
|
||||
@ -79,6 +105,7 @@ help: use parentheses to construct a tuple
|
||||
LL | with_generic((a, b));
|
||||
| + +
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0061`.
|
||||
Some errors have detailed explanations: E0061, E0308.
|
||||
For more information about an error, try `rustc --explain E0061`.
|
||||
|
@ -11,7 +11,7 @@ LL | let _x: (i32,) = (5);
|
||||
help: use a trailing comma to create a tuple with one element
|
||||
|
|
||||
LL | let _x: (i32,) = (5,);
|
||||
| ~~~~
|
||||
| +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-86100-tuple-paren-comma.rs:13:9
|
||||
@ -24,7 +24,7 @@ LL | foo((Some(3)));
|
||||
help: use a trailing comma to create a tuple with one element
|
||||
|
|
||||
LL | foo((Some(3),));
|
||||
| ~~~~~~~~~~
|
||||
| +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-86100-tuple-paren-comma.rs:17:22
|
||||
@ -37,7 +37,7 @@ LL | let _s = S { _s: ("abc".to_string()) };
|
||||
help: use a trailing comma to create a tuple with one element
|
||||
|
|
||||
LL | let _s = S { _s: ("abc".to_string(),) };
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
| +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-86100-tuple-paren-comma.rs:23:22
|
||||
|
@ -1,17 +0,0 @@
|
||||
// run-pass
|
||||
// compile-flags: --test
|
||||
#![feature(allow_fail)]
|
||||
#![feature(cfg_panic)]
|
||||
|
||||
#[test]
|
||||
#[allow_fail]
|
||||
fn test1() {
|
||||
#[cfg(not(panic = "abort"))]
|
||||
panic!();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow_fail]
|
||||
fn test2() {
|
||||
assert!(true);
|
||||
}
|
@ -922,10 +922,11 @@ pub fn make_test_description<R: Read>(
|
||||
name,
|
||||
ignore,
|
||||
should_panic,
|
||||
allow_fail: false,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
test_type: test::TestType::Unknown,
|
||||
#[cfg(bootstrap)]
|
||||
allow_fail: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user