diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000..ec6e107d547f0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +[*.md] +# double whitespace at end of line +# denotes a line break in Markdown +trim_trailing_whitespace = false + +[*.yml] +indent_size = 2 diff --git a/Cargo.lock b/Cargo.lock index 8bfdf23a30bf4..fb401ed4cd0bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,9 +496,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chalk-derive" -version = "0.36.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f88ce4deae1dace71e49b7611cfae2d5489de3530d6daba5758043c47ac3a10" +checksum = "3983193cacd81f0f924acb666b7fe5e1a0d81db9f113fa69203eda7ea8ce8b6c" dependencies = [ "proc-macro2", "quote", @@ -508,9 +508,9 @@ dependencies = [ [[package]] name = "chalk-engine" -version = "0.36.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e34c9b1b10616782143d7f49490f91ae94afaf2202de3ab0b2835e78b4f0ccc" +checksum = "05a171ce5abbf0fbd06f221ab80ab182c7ef78603d23b858bc44e7ce8a86a396" dependencies = [ "chalk-derive", "chalk-ir", @@ -521,19 +521,20 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.36.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63362c629c2014ab639b04029070763fb8224df136d1363d30e9ece4c8877da3" +checksum = "a522f53af971e7678f472d687e053120157b3ae26e2ebd5ecbc0f5ab124f2cb6" dependencies = [ + "bitflags", "chalk-derive", "lazy_static", ] [[package]] name = "chalk-solve" -version = "0.36.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac338a67af52a7f50bb2f8232e730a3518ce432dbe303246acfe525ddd838c7" +checksum = "cdf79fb77a567e456a170f7ec84ea6584163d4ba3f13660cd182013d34ca667c" dependencies = [ "chalk-derive", "chalk-ir", @@ -1783,9 +1784,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.79" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" +checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" dependencies = [ "rustc-std-workspace-core", ] @@ -4313,6 +4314,7 @@ dependencies = [ "chalk-ir", "chalk-solve", "rustc_ast", + "rustc_attr", "rustc_data_structures", "rustc_hir", "rustc_index", diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 35de744d274c9..73afa3ff94e25 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -28,7 +28,7 @@ pub trait ExpectOne { impl ExpectOne for SmallVec { fn expect_one(self, err: &'static str) -> A::Item { - assert!(self.len() == 1, err); + assert!(self.len() == 1, "{}", err); self.into_iter().next().unwrap() } } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 07fde27b5a314..39d08fbee3b7f 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -105,7 +105,6 @@ fn emit_aapcs_va_arg( let mut end = bx.build_sibling_block("va_arg.end"); let zero = bx.const_i32(0); let offset_align = Align::from_bytes(4).unwrap(); - assert_eq!(bx.tcx().sess.target.endian, Endian::Little); let gr_type = target_ty.is_any_ptr() || target_ty.is_integral(); let (reg_off, reg_top_index, slot_size) = if gr_type { @@ -144,9 +143,14 @@ fn emit_aapcs_va_arg( let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi); // reg_value = *(@top + reg_off_v); - let top = in_reg.gep(top, &[reg_off_v]); - let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx))); - let reg_value = in_reg.load(top, layout.align.abi); + let mut reg_addr = in_reg.gep(top, &[reg_off_v]); + if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size { + // On big-endian systems the value is right-aligned in its slot. + let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32); + reg_addr = in_reg.gep(reg_addr, &[offset]); + } + let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(layout.llvm_type(bx))); + let reg_value = in_reg.load(reg_addr, layout.align.abi); in_reg.br(&end.llbb()); // On Stack block diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e184e929b0745..aa88233209940 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -901,7 +901,7 @@ impl HandlerInner { fn span_bug(&mut self, sp: impl Into, msg: &str) -> ! { self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); - panic!(ExplicitBug); + panic::panic_any(ExplicitBug); } fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into) { @@ -955,7 +955,7 @@ impl HandlerInner { fn bug(&mut self, msg: &str) -> ! { self.emit_diagnostic(&Diagnostic::new(Bug, msg)); - panic!(ExplicitBug); + panic::panic_any(ExplicitBug); } fn delay_as_bug(&mut self, diagnostic: Diagnostic) { diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 9002d251f1237..aa4fd055d5ee0 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -353,10 +353,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { // `TyVar(vid)` is unresolved, track its universe index in the canonicalized // result. Err(mut ui) => { - if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk { - // FIXME: perf problem described in #55921. - ui = ty::UniverseIndex::ROOT; - } + // FIXME: perf problem described in #55921. + ui = ty::UniverseIndex::ROOT; self.canonicalize_ty_var( CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)), @@ -440,10 +438,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { // `ConstVar(vid)` is unresolved, track its universe index in the // canonicalized result Err(mut ui) => { - if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk { - // FIXME: perf problem described in #55921. - ui = ty::UniverseIndex::ROOT; - } + // FIXME: perf problem described in #55921. + ui = ty::UniverseIndex::ROOT; return self.canonicalize_const_var( CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) }, ct, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 2abb1c725b914..84aa19aedebf8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1855,7 +1855,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { diag.span_suggestion( span, &format!( - "you might have meant to use field `{}` of type `{}`", + "you might have meant to use field `{}` whose type is `{}`", name, ty ), suggestion, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 2336b52619ab8..96b2ff0837ddb 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -54,8 +54,8 @@ mod late; mod levels; mod methods; mod non_ascii_idents; +mod non_fmt_panic; mod nonstandard_style; -mod panic_fmt; mod passes; mod redundant_semicolon; mod traits; @@ -80,8 +80,8 @@ use builtin::*; use internal::*; use methods::*; use non_ascii_idents::*; +use non_fmt_panic::NonPanicFmt; use nonstandard_style::*; -use panic_fmt::PanicFmt; use redundant_semicolon::*; use traits::*; use types::*; @@ -168,7 +168,7 @@ macro_rules! late_lint_passes { ClashingExternDeclarations: ClashingExternDeclarations::new(), DropTraitConstraints: DropTraitConstraints, TemporaryCStringAsPtr: TemporaryCStringAsPtr, - PanicFmt: PanicFmt, + NonPanicFmt: NonPanicFmt, ] ); }; diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs new file mode 100644 index 0000000000000..e98297b692c92 --- /dev/null +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -0,0 +1,197 @@ +use crate::{LateContext, LateLintPass, LintContext}; +use rustc_ast as ast; +use rustc_errors::{pluralize, Applicability}; +use rustc_hir as hir; +use rustc_middle::ty; +use rustc_parse_format::{ParseMode, Parser, Piece}; +use rustc_span::{sym, symbol::kw, InnerSpan, Span, Symbol}; + +declare_lint! { + /// The `non_fmt_panic` lint detects `panic!(..)` invocations where the first + /// argument is not a formatting string. + /// + /// ### Example + /// + /// ```rust,no_run + /// panic!("{}"); + /// panic!(123); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// In Rust 2018 and earlier, `panic!(x)` directly uses `x` as the message. + /// That means that `panic!("{}")` panics with the message `"{}"` instead + /// of using it as a formatting string, and `panic!(123)` will panic with + /// an `i32` as message. + /// + /// Rust 2021 always interprets the first argument as format string. + NON_FMT_PANIC, + Warn, + "detect single-argument panic!() invocations in which the argument is not a format string", + report_in_external_macro +} + +declare_lint_pass!(NonPanicFmt => [NON_FMT_PANIC]); + +impl<'tcx> LateLintPass<'tcx> for NonPanicFmt { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Call(f, [arg]) = &expr.kind { + if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() { + if Some(def_id) == cx.tcx.lang_items().begin_panic_fn() + || Some(def_id) == cx.tcx.lang_items().panic_fn() + || Some(def_id) == cx.tcx.lang_items().panic_str() + { + if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id { + if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id) + || cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id) + { + check_panic(cx, f, arg); + } + } + } + } + } + } +} + +fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Lit(lit) = &arg.kind { + if let ast::LitKind::Str(sym, _) = lit.node { + // The argument is a string literal. + check_panic_str(cx, f, arg, &sym.as_str()); + return; + } + } + + // The argument is *not* a string literal. + + let (span, panic) = panic_call(cx, f); + + cx.struct_span_lint(NON_FMT_PANIC, arg.span, |lint| { + let mut l = lint.build("panic message is not a string literal"); + l.note("this is no longer accepted in Rust 2021"); + if span.contains(arg.span) { + l.span_suggestion_verbose( + arg.span.shrink_to_lo(), + "add a \"{}\" format string to Display the message", + "\"{}\", ".into(), + Applicability::MaybeIncorrect, + ); + if panic == sym::std_panic_macro { + l.span_suggestion_verbose( + span.until(arg.span), + "or use std::panic::panic_any instead", + "std::panic::panic_any(".into(), + Applicability::MachineApplicable, + ); + } + } + l.emit(); + }); +} + +fn check_panic_str<'tcx>( + cx: &LateContext<'tcx>, + f: &'tcx hir::Expr<'tcx>, + arg: &'tcx hir::Expr<'tcx>, + fmt: &str, +) { + if !fmt.contains(&['{', '}'][..]) { + // No brace, no problem. + return; + } + + let fmt_span = arg.span.source_callsite(); + + let (snippet, style) = match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) { + Ok(snippet) => { + // Count the number of `#`s between the `r` and `"`. + let style = snippet.strip_prefix('r').and_then(|s| s.find('"')); + (Some(snippet), style) + } + Err(_) => (None, None), + }; + + let mut fmt_parser = + Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format); + let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count(); + + let (span, _) = panic_call(cx, f); + + if n_arguments > 0 && fmt_parser.errors.is_empty() { + let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] { + [] => vec![fmt_span], + v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(), + }; + cx.struct_span_lint(NON_FMT_PANIC, arg_spans, |lint| { + let mut l = lint.build(match n_arguments { + 1 => "panic message contains an unused formatting placeholder", + _ => "panic message contains unused formatting placeholders", + }); + l.note("this message is not used as a format string when given without arguments, but will be in Rust 2021"); + if span.contains(arg.span) { + l.span_suggestion( + arg.span.shrink_to_hi(), + &format!("add the missing argument{}", pluralize!(n_arguments)), + ", ...".into(), + Applicability::HasPlaceholders, + ); + l.span_suggestion( + arg.span.shrink_to_lo(), + "or add a \"{}\" format string to use the message literally", + "\"{}\", ".into(), + Applicability::MachineApplicable, + ); + } + l.emit(); + }); + } else { + let brace_spans: Option> = + snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| { + s.char_indices() + .filter(|&(_, c)| c == '{' || c == '}') + .map(|(i, _)| fmt_span.from_inner(InnerSpan { start: i, end: i + 1 })) + .collect() + }); + let msg = match &brace_spans { + Some(v) if v.len() == 1 => "panic message contains a brace", + _ => "panic message contains braces", + }; + cx.struct_span_lint(NON_FMT_PANIC, brace_spans.unwrap_or(vec![span]), |lint| { + let mut l = lint.build(msg); + l.note("this message is not used as a format string, but will be in Rust 2021"); + if span.contains(arg.span) { + l.span_suggestion( + arg.span.shrink_to_lo(), + "add a \"{}\" format string to use the message literally", + "\"{}\", ".into(), + Applicability::MachineApplicable, + ); + } + l.emit(); + }); + } +} + +fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol) { + let mut expn = f.span.ctxt().outer_expn_data(); + + let mut panic_macro = kw::Empty; + + // Unwrap more levels of macro expansion, as panic_2015!() + // was likely expanded from panic!() and possibly from + // [debug_]assert!(). + for &i in + &[sym::std_panic_macro, sym::core_panic_macro, sym::assert_macro, sym::debug_assert_macro] + { + let parent = expn.call_site.ctxt().outer_expn_data(); + if parent.macro_def_id.map_or(false, |id| cx.tcx.is_diagnostic_item(i, id)) { + expn = parent; + panic_macro = i; + } + } + + (expn.call_site, panic_macro) +} diff --git a/compiler/rustc_lint/src/panic_fmt.rs b/compiler/rustc_lint/src/panic_fmt.rs deleted file mode 100644 index 4a6aca72acbbe..0000000000000 --- a/compiler/rustc_lint/src/panic_fmt.rs +++ /dev/null @@ -1,155 +0,0 @@ -use crate::{LateContext, LateLintPass, LintContext}; -use rustc_ast as ast; -use rustc_errors::{pluralize, Applicability}; -use rustc_hir as hir; -use rustc_middle::ty; -use rustc_parse_format::{ParseMode, Parser, Piece}; -use rustc_span::{sym, InnerSpan}; - -declare_lint! { - /// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal. - /// - /// ### Example - /// - /// ```rust,no_run - /// panic!("{}"); - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// In Rust 2018 and earlier, `panic!("{}")` panics with the message `"{}"`, - /// as a `panic!()` invocation with a single argument does not use `format_args!()`. - /// Rust 2021 interprets this string as format string, which breaks this. - PANIC_FMT, - Warn, - "detect braces in single-argument panic!() invocations", - report_in_external_macro -} - -declare_lint_pass!(PanicFmt => [PANIC_FMT]); - -impl<'tcx> LateLintPass<'tcx> for PanicFmt { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Call(f, [arg]) = &expr.kind { - if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() { - if Some(def_id) == cx.tcx.lang_items().begin_panic_fn() - || Some(def_id) == cx.tcx.lang_items().panic_fn() - { - check_panic(cx, f, arg); - } - } - } - } -} - -fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Lit(lit) = &arg.kind { - if let ast::LitKind::Str(sym, _) = lit.node { - let mut expn = f.span.ctxt().outer_expn_data(); - if let Some(id) = expn.macro_def_id { - if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id) - || cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id) - { - let fmt = sym.as_str(); - if !fmt.contains(&['{', '}'][..]) { - return; - } - - let fmt_span = arg.span.source_callsite(); - - let (snippet, style) = - match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) { - Ok(snippet) => { - // Count the number of `#`s between the `r` and `"`. - let style = snippet.strip_prefix('r').and_then(|s| s.find('"')); - (Some(snippet), style) - } - Err(_) => (None, None), - }; - - let mut fmt_parser = - Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format); - let n_arguments = - (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count(); - - // Unwrap more levels of macro expansion, as panic_2015!() - // was likely expanded from panic!() and possibly from - // [debug_]assert!(). - for &assert in &[ - sym::std_panic_macro, - sym::core_panic_macro, - sym::assert_macro, - sym::debug_assert_macro, - ] { - let parent = expn.call_site.ctxt().outer_expn_data(); - if parent - .macro_def_id - .map_or(false, |id| cx.tcx.is_diagnostic_item(assert, id)) - { - expn = parent; - } - } - - if n_arguments > 0 && fmt_parser.errors.is_empty() { - let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] { - [] => vec![fmt_span], - v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(), - }; - cx.struct_span_lint(PANIC_FMT, arg_spans, |lint| { - let mut l = lint.build(match n_arguments { - 1 => "panic message contains an unused formatting placeholder", - _ => "panic message contains unused formatting placeholders", - }); - l.note("this message is not used as a format string when given without arguments, but will be in a future Rust edition"); - if expn.call_site.contains(arg.span) { - l.span_suggestion( - arg.span.shrink_to_hi(), - &format!("add the missing argument{}", pluralize!(n_arguments)), - ", ...".into(), - Applicability::HasPlaceholders, - ); - l.span_suggestion( - arg.span.shrink_to_lo(), - "or add a \"{}\" format string to use the message literally", - "\"{}\", ".into(), - Applicability::MachineApplicable, - ); - } - l.emit(); - }); - } else { - let brace_spans: Option> = snippet - .filter(|s| s.starts_with('"') || s.starts_with("r#")) - .map(|s| { - s.char_indices() - .filter(|&(_, c)| c == '{' || c == '}') - .map(|(i, _)| { - fmt_span.from_inner(InnerSpan { start: i, end: i + 1 }) - }) - .collect() - }); - let msg = match &brace_spans { - Some(v) if v.len() == 1 => "panic message contains a brace", - _ => "panic message contains braces", - }; - cx.struct_span_lint(PANIC_FMT, brace_spans.unwrap_or(vec![expn.call_site]), |lint| { - let mut l = lint.build(msg); - l.note("this message is not used as a format string, but will be in a future Rust edition"); - if expn.call_site.contains(arg.span) { - l.span_suggestion( - arg.span.shrink_to_lo(), - "add a \"{}\" format string to use the message literally", - "\"{}\", ".into(), - Applicability::MachineApplicable, - ); - } - l.emit(); - }); - } - } - } - } - } -} diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 47b7768b410a1..d33aad3b71040 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,7 +26,7 @@ rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.36.0" +chalk-ir = "0.55.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "9.0.0" rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index f288ad8d1d4a3..4bb39fe4a527e 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -96,7 +96,7 @@ impl<'tcx> ConstValue<'tcx> { } /// A `Scalar` represents an immediate, primitive value existing outside of a -/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in +/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 16 bytes in /// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes /// of a simple value or a pointer into another `Allocation` #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, TyEncodable, TyDecodable, Hash)] diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs index f864ad8ebcd8a..74873778f74ba 100644 --- a/compiler/rustc_middle/src/traits/chalk.rs +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -72,6 +72,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { type InternedQuantifiedWhereClauses = Vec>; type InternedVariableKinds = Vec>; type InternedCanonicalVarKinds = Vec>; + type InternedVariances = Vec; type InternedConstraints = Vec>>; type DefId = DefId; type InternedAdtId = &'tcx AdtDef; @@ -86,17 +87,34 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { write!(fmt, "{:?}", pci.consequence)?; let conditions = pci.conditions.interned(); + let constraints = pci.constraints.interned(); let conds = conditions.len(); - if conds == 0 { + let consts = constraints.len(); + if conds == 0 && consts == 0 { return Ok(()); } write!(fmt, " :- ")?; - for cond in &conditions[..conds - 1] { - write!(fmt, "{:?}, ", cond)?; + + if conds != 0 { + for cond in &conditions[..conds - 1] { + write!(fmt, "{:?}, ", cond)?; + } + write!(fmt, "{:?}", conditions[conds - 1])?; + } + + if conds != 0 && consts != 0 { + write!(fmt, " ; ")?; } - write!(fmt, "{:?}", conditions[conds - 1])?; + + if consts != 0 { + for constraint in &constraints[..consts - 1] { + write!(fmt, "{:?}, ", constraint)?; + } + write!(fmt, "{:?}", constraints[consts - 1])?; + } + Ok(()) }; Some(write()) @@ -351,6 +369,20 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { ) -> &'a [chalk_ir::InEnvironment>] { constraints } + + fn intern_variances( + &self, + data: impl IntoIterator>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn variances_data<'a>( + &self, + variances: &'a Self::InternedVariances, + ) -> &'a [chalk_ir::Variance] { + variances + } } impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> { diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index e79adcdb54598..791d5060fe5c7 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -3,7 +3,7 @@ use crate::ty::{tls, TyCtxt}; use rustc_span::{MultiSpan, Span}; use std::fmt; -use std::panic::Location; +use std::panic::{panic_any, Location}; #[cold] #[inline(never)] @@ -32,7 +32,7 @@ fn opt_span_bug_fmt>( match (tcx, span) { (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), - (None, _) => panic!(msg), + (None, _) => panic_any(msg), } }); unreachable!(); diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 004c06029ffba..0bab33976b29d 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2415,7 +2415,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { _ => break, } } - break Some(e); + break Some(&e[..]); } Elide::Forbid => break None, }; @@ -2445,7 +2445,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_refs.len(), &lifetime_names, lifetime_spans, - error.map(|p| &p[..]).unwrap_or(&[]), + error.unwrap_or(&[]), ); err.emit(); } diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs index 1ab7722edab98..a5e985d471271 100644 --- a/compiler/rustc_target/src/abi/call/aarch64.rs +++ b/compiler/rustc_target/src/abi/call/aarch64.rs @@ -40,17 +40,7 @@ where let size = ret.layout.size; let bits = size.bits(); if bits <= 128 { - let unit = if bits <= 8 { - Reg::i8() - } else if bits <= 16 { - Reg::i16() - } else if bits <= 32 { - Reg::i32() - } else { - Reg::i64() - }; - - ret.cast_to(Uniform { unit, total: size }); + ret.cast_to(Uniform { unit: Reg::i64(), total: size }); return; } ret.make_indirect(); @@ -72,17 +62,7 @@ where let size = arg.layout.size; let bits = size.bits(); if bits <= 128 { - let unit = if bits <= 8 { - Reg::i8() - } else if bits <= 16 { - Reg::i16() - } else if bits <= 32 { - Reg::i32() - } else { - Reg::i64() - }; - - arg.cast_to(Uniform { unit, total: size }); + arg.cast_to(Uniform { unit: Reg::i64(), total: size }); return; } arg.make_indirect(); diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs index 26fed3bae4e48..b560e11fe1c5e 100644 --- a/compiler/rustc_target/src/abi/call/arm.rs +++ b/compiler/rustc_target/src/abi/call/arm.rs @@ -45,14 +45,7 @@ where let size = ret.layout.size; let bits = size.bits(); if bits <= 32 { - let unit = if bits <= 8 { - Reg::i8() - } else if bits <= 16 { - Reg::i16() - } else { - Reg::i32() - }; - ret.cast_to(Uniform { unit, total: size }); + ret.cast_to(Uniform { unit: Reg::i32(), total: size }); return; } ret.make_indirect(); diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..192c4661c7ce6 --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs @@ -0,0 +1,20 @@ +use crate::abi::Endian; +use crate::spec::{Target, TargetOptions}; + +pub fn target() -> Target { + let mut base = super::linux_gnu_base::opts(); + base.max_atomic_width = Some(128); + + Target { + llvm_target: "aarch64_be-unknown-linux-gnu".to_string(), + pointer_width: 64, + data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + options: TargetOptions { + unsupported_abis: super::arm_base::unsupported_abis(), + mcount: "\u{1}_mcount".to_string(), + endian: Endian::Big, + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs new file mode 100644 index 0000000000000..5b9e9c9519c54 --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs @@ -0,0 +1,20 @@ +use crate::abi::Endian; +use crate::spec::{Target, TargetOptions}; + +pub fn target() -> Target { + let mut base = super::linux_gnu_base::opts(); + base.max_atomic_width = Some(128); + + Target { + llvm_target: "aarch64_be-unknown-linux-gnu_ilp32".to_string(), + pointer_width: 32, + data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + options: TargetOptions { + unsupported_abis: super::arm_base::unsupported_abis(), + mcount: "\u{1}_mcount".to_string(), + endian: Endian::Big, + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs new file mode 100644 index 0000000000000..f2d7576280fd9 --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs @@ -0,0 +1,18 @@ +use crate::spec::{Target, TargetOptions}; + +pub fn target() -> Target { + let mut base = super::linux_gnu_base::opts(); + base.max_atomic_width = Some(128); + + Target { + llvm_target: "aarch64-unknown-linux-gnu_ilp32".to_string(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + options: TargetOptions { + unsupported_abis: super::arm_base::unsupported_abis(), + mcount: "\u{1}_mcount".to_string(), + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0227febd294a0..7a93bac72ca07 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -808,6 +808,10 @@ supported_targets! { ("mipsel-sony-psp", mipsel_sony_psp), ("mipsel-unknown-none", mipsel_unknown_none), ("thumbv4t-none-eabi", thumbv4t_none_eabi), + + ("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu), + ("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32), + ("aarch64_be-unknown-linux-gnu_ilp32", aarch64_be_unknown_linux_gnu_ilp32), } /// Everything `rustc` knows about how to compile for a specific target. diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 3facdd5f84c29..89820bb1417eb 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -16,8 +16,7 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::mir::abstract_const::{Node, NodeId}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind}; -use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::subst::SubstsRef; +use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::{DefId, LocalDefId}; @@ -43,10 +42,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>( for pred in param_env.caller_bounds() { match pred.kind().skip_binder() { ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => { - debug!( - "is_const_evaluatable: caller_bound={:?}, {:?}", - b_def, b_substs - ); if b_def == def && b_substs == substs { debug!("is_const_evaluatable: caller_bound ~~> ok"); return Ok(()); @@ -113,15 +108,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } FailureKind::MentionsParam => { // FIXME(const_evaluatable_checked): Better error message. - infcx - .tcx - .sess - .struct_span_err(span, "unconstrained generic constant") - .span_help( + let mut err = + infcx.tcx.sess.struct_span_err(span, "unconstrained generic constant"); + let const_span = tcx.def_span(def.did); + // FIXME(const_evaluatable_checked): Update this suggestion once + // explicit const evaluatable bounds are implemented. + if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(const_span) + { + err.span_help( tcx.def_span(def.did), + &format!("try adding a `where` bound using this expression: where [u8; {}]: Sized", snippet), + ); + } else { + err.span_help( + const_span, "consider adding a `where` bound for this expression", - ) - .emit(); + ); + } + err.emit(); return Err(ErrorHandled::Reported(ErrorReported)); } FailureKind::Concrete => { diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 8bd9e29629dce..8fdbc3b76b459 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -6,15 +6,16 @@ edition = "2018" [dependencies] tracing = "0.1" +rustc_attr = { path = "../rustc_attr" } rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.36.0" -chalk-solve = "0.36.0" -chalk-engine = "0.36.0" +chalk-ir = "0.55.0" +chalk-solve = "0.55.0" +chalk-engine = "0.55.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index bb48ed936188b..916186f4204e2 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -10,6 +10,9 @@ use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable}; +use rustc_ast::ast; +use rustc_attr as attr; + use rustc_hir::def_id::DefId; use rustc_span::symbol::sym; @@ -18,7 +21,6 @@ use std::fmt; use std::sync::Arc; use crate::chalk::lowering::{self, LowerInto}; -use rustc_ast::ast; pub struct RustIrDatabase<'tcx> { pub(crate) interner: RustInterner<'tcx>, @@ -205,12 +207,32 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn adt_repr( &self, adt_id: chalk_ir::AdtId>, - ) -> chalk_solve::rust_ir::AdtRepr { + ) -> Arc>> { let adt_def = adt_id.0; - chalk_solve::rust_ir::AdtRepr { - repr_c: adt_def.repr.c(), - repr_packed: adt_def.repr.packed(), - } + let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)).intern(&self.interner); + let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)).intern(&self.interner); + Arc::new(chalk_solve::rust_ir::AdtRepr { + c: adt_def.repr.c(), + packed: adt_def.repr.packed(), + int: adt_def.repr.int.map(|i| match i { + attr::IntType::SignedInt(ty) => match ty { + ast::IntTy::Isize => int(chalk_ir::IntTy::Isize), + ast::IntTy::I8 => int(chalk_ir::IntTy::I8), + ast::IntTy::I16 => int(chalk_ir::IntTy::I16), + ast::IntTy::I32 => int(chalk_ir::IntTy::I32), + ast::IntTy::I64 => int(chalk_ir::IntTy::I64), + ast::IntTy::I128 => int(chalk_ir::IntTy::I128), + }, + attr::IntType::UnsignedInt(ty) => match ty { + ast::UintTy::Usize => uint(chalk_ir::UintTy::Usize), + ast::UintTy::U8 => uint(chalk_ir::UintTy::U8), + ast::UintTy::U16 => uint(chalk_ir::UintTy::U16), + ast::UintTy::U32 => uint(chalk_ir::UintTy::U32), + ast::UintTy::U64 => uint(chalk_ir::UintTy::U64), + ast::UintTy::U128 => uint(chalk_ir::UintTy::U128), + }, + }), + }) } fn fn_def_datum( @@ -316,7 +338,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let self_ty = self_ty.fold_with(&mut regions_substitutor); let lowered_ty = self_ty.lower_into(&self.interner); - parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty) + parameters[0].assert_ty_ref(&self.interner).could_match( + &self.interner, + self.unification_database(), + &lowered_ty, + ) }); let impls = matched_impls.map(chalk_ir::ImplId).collect(); @@ -541,6 +567,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t Unsize => lang_items.unsize_trait(), Unpin => lang_items.unpin_trait(), CoerceUnsized => lang_items.coerce_unsized_trait(), + DiscriminantKind => lang_items.discriminant_kind_trait(), }; def_id.map(chalk_ir::TraitId) } @@ -586,7 +613,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let sig = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 2]; match sig.assert_ty_ref(&self.interner).kind(&self.interner) { chalk_ir::TyKind::Function(f) => { - let substitution = f.substitution.as_slice(&self.interner); + let substitution = f.substitution.0.as_slice(&self.interner); let return_type = substitution.last().unwrap().assert_ty_ref(&self.interner).clone(); // Closure arguments are tupled @@ -644,6 +671,51 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ) -> Arc>> { unimplemented!() } + + fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase> { + self + } + + fn discriminant_type( + &self, + _: chalk_ir::Ty>, + ) -> chalk_ir::Ty> { + unimplemented!() + } +} + +impl<'tcx> chalk_ir::UnificationDatabase> for RustIrDatabase<'tcx> { + fn fn_def_variance( + &self, + def_id: chalk_ir::FnDefId>, + ) -> chalk_ir::Variances> { + let variances = self.interner.tcx.variances_of(def_id.0); + chalk_ir::Variances::from_iter( + &self.interner, + variances.iter().map(|v| match v { + ty::Variance::Invariant => chalk_ir::Variance::Invariant, + ty::Variance::Covariant => chalk_ir::Variance::Covariant, + ty::Variance::Contravariant => chalk_ir::Variance::Contravariant, + ty::Variance::Bivariant => unimplemented!(), + }), + ) + } + + fn adt_variance( + &self, + def_id: chalk_ir::AdtId>, + ) -> chalk_ir::Variances> { + let variances = self.interner.tcx.variances_of(def_id.0.did); + chalk_ir::Variances::from_iter( + &self.interner, + variances.iter().map(|v| match v { + ty::Variance::Invariant => chalk_ir::Variance::Invariant, + ty::Variance::Covariant => chalk_ir::Variance::Covariant, + ty::Variance::Contravariant => chalk_ir::Variance::Contravariant, + ty::Variance::Bivariant => unimplemented!(), + }), + ) + } } /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 2a1a3f57e2313..7d3589c4b6bd8 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -287,12 +287,12 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { chalk_ir::TyKind::Function(chalk_ir::FnPointer { num_binders: binders.len(interner), sig: sig.lower_into(interner), - substitution: chalk_ir::Substitution::from_iter( + substitution: chalk_ir::FnSubst(chalk_ir::Substitution::from_iter( interner, inputs_and_outputs.iter().map(|ty| { chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner) }), - ), + )), }) } ty::Dynamic(predicates, region) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy { @@ -478,6 +478,10 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime ty::RegionKind::ReStatic, chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(), + chalk_ir::LifetimeData::Empty(ui) => { + ty::RegionKind::ReEmpty(ty::UniverseIndex::from_usize(ui.counter)) + } + chalk_ir::LifetimeData::Erased => ty::RegionKind::ReErased, }; interner.tcx.mk_region(kind) } diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index bd2f87f70a2f1..d98f18182c843 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -105,14 +105,40 @@ crate fn evaluate_goal<'tcx>( // really need this and so it's really minimal. // Right now, we also treat a `Unique` solution the same as // `Ambig(Definite)`. This really isn't right. - let make_solution = |subst: chalk_ir::Substitution<_>| { + let make_solution = |subst: chalk_ir::Substitution<_>, + binders: chalk_ir::CanonicalVarKinds<_>| { + use rustc_middle::infer::canonical::CanonicalVarInfo; + let mut var_values: IndexVec> = IndexVec::new(); subst.as_slice(&interner).iter().for_each(|p| { var_values.push(p.lower_into(&interner)); }); + let variables: Vec<_> = binders + .iter(&interner) + .map(|var| { + let kind = match var.kind { + chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind { + chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General( + ty::UniverseIndex::from_usize(var.skip_kind().counter), + ), + chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int, + chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float, + }), + chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region( + ty::UniverseIndex::from_usize(var.skip_kind().counter), + ), + chalk_ir::VariableKind::Const(_) => CanonicalVarKind::Const( + ty::UniverseIndex::from_usize(var.skip_kind().counter), + ), + }; + CanonicalVarInfo { kind } + }) + .collect(); + let max_universe = + binders.iter(&interner).map(|v| v.skip_kind().counter).max().unwrap_or(0); let sol = Canonical { - max_universe: ty::UniverseIndex::from_usize(0), - variables: obligation.variables.clone(), + max_universe: ty::UniverseIndex::from_usize(max_universe), + variables: tcx.intern_canonical_var_infos(&variables), value: QueryResponse { var_values: CanonicalVarValues { var_values }, region_constraints: QueryRegionConstraints::default(), @@ -126,11 +152,13 @@ crate fn evaluate_goal<'tcx>( .map(|s| match s { Solution::Unique(subst) => { // FIXME(chalk): handle constraints - make_solution(subst.value.subst) + make_solution(subst.value.subst, subst.binders) } Solution::Ambig(guidance) => { match guidance { - chalk_solve::Guidance::Definite(subst) => make_solution(subst.value), + chalk_solve::Guidance::Definite(subst) => { + make_solution(subst.value, subst.binders) + } chalk_solve::Guidance::Suggested(_) => unimplemented!(), chalk_solve::Guidance::Unknown => { // chalk_fulfill doesn't use the var_values here, so diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index a02e74d5e5a4d..6e502426df906 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -10,22 +10,23 @@ tests. `panic!` is closely tied with the `unwrap` method of both `panic!` when they are set to [`None`] or [`Err`] variants. This macro is used to inject panic into a Rust thread, causing the thread to -panic entirely. Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, -and the single-argument form of the `panic!` macro will be the value which -is transmitted. +panic entirely. This macro panics with a string and uses the [`format!`] syntax +for building the message. + +Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, +which contains either a `&str` or `String` for regular `panic!()` invocations. +To panic with a value of another other type, [`panic_any`] can be used. [`Result`] enum is often a better solution for recovering from errors than using the `panic!` macro. This macro should be used to avoid proceeding using incorrect values, such as from external sources. Detailed information about error handling is found in the [book]. -The multi-argument form of this macro panics with a string and has the -[`format!`] syntax for building a string. - See also the macro [`compile_error!`], for raising errors during compilation. [ounwrap]: Option::unwrap [runwrap]: Result::unwrap +[`panic_any`]: ../std/panic/fn.panic_any.html [`Box`]: ../std/boxed/struct.Box.html [`Any`]: crate::any::Any [`format!`]: ../std/macro.format.html @@ -42,6 +43,6 @@ program with code `101`. # #![allow(unreachable_code)] panic!(); panic!("this is a terrible mistake!"); -panic!(4); // panic with the value of 4 to be collected elsewhere panic!("this is a {} {message}", "fancy", message = "message"); +std::panic::panic_any(4); // panic with the value of 4 to be collected elsewhere ``` diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index 617c4098aa959..525102212c41e 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -247,17 +247,17 @@ mod arch { use crate::os::raw::{c_int, c_long}; #[stable(feature = "raw_ext", since = "1.1.0")] - pub type blkcnt_t = u64; + pub type blkcnt_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] - pub type blksize_t = u64; + pub type blksize_t = i32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; #[stable(feature = "raw_ext", since = "1.1.0")] - pub type nlink_t = u64; + pub type nlink_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] - pub type off_t = u64; + pub type off_t = i64; #[stable(feature = "raw_ext", since = "1.1.0")] - pub type time_t = i64; + pub type time_t = c_long; #[repr(C)] #[derive(Clone)] @@ -288,15 +288,15 @@ mod arch { #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blocks: i64, #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: i64, + pub st_atime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: i64, + pub st_mtime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: i64, + pub st_ctime: time_t, #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime_nsec: c_long, #[stable(feature = "raw_ext", since = "1.1.0")] diff --git a/library/term/src/terminfo/parm/tests.rs b/library/term/src/terminfo/parm/tests.rs index b975bd2d19882..1cc0967c8f42e 100644 --- a/library/term/src/terminfo/parm/tests.rs +++ b/library/term/src/terminfo/parm/tests.rs @@ -77,15 +77,15 @@ fn test_comparison_ops() { for &(op, bs) in v.iter() { let s = format!("%{{1}}%{{2}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), vec![b'0' + bs[0]]); let s = format!("%{{1}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), vec![b'0' + bs[1]]); let s = format!("%{{2}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), vec![b'0' + bs[2]]); } } @@ -95,13 +95,13 @@ fn test_conditionals() { let mut vars = Variables::new(); let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"; let res = expand(s, &[Number(1)], &mut vars); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::>()); let res = expand(s, &[Number(8)], &mut vars); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::>()); let res = expand(s, &[Number(42)], &mut vars); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::>()); } diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 99e12c973c4a2..f0586d510dbdb 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -199,7 +199,7 @@ fn test_should_panic_bad_message() { fn test_should_panic_non_string_message_type() { use crate::tests::TrFailedMsg; fn f() { - panic!(1i32); + std::panic::panic_any(1i32); } let expected = "foobar"; let failed_msg = format!( diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index ff1d82fc99040..faf554d285a9a 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -36,9 +36,12 @@ pub const unwinder_private_data_size: usize = 20; #[cfg(all(target_arch = "arm", target_os = "ios"))] pub const unwinder_private_data_size: usize = 5; -#[cfg(target_arch = "aarch64")] +#[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))] pub const unwinder_private_data_size: usize = 2; +#[cfg(all(target_arch = "aarch64", target_pointer_width = "32"))] +pub const unwinder_private_data_size: usize = 5; + #[cfg(target_arch = "mips")] pub const unwinder_private_data_size: usize = 2; diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ce8caae375e98..eb74041964701 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -156,11 +156,14 @@ target | std | host | notes `aarch64-apple-tvos` | * | | ARM64 tvOS `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ? | | +`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) `aarch64-unknown-netbsd` | ✓ | ✓ | `aarch64-unknown-openbsd` | ✓ | ✓ | ARM64 OpenBSD `aarch64-unknown-redox` | ? | | ARM64 Redox OS `aarch64-uwp-windows-msvc` | ? | | `aarch64-wrs-vxworks` | ? | | +`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) +`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `armv4t-unknown-linux-gnueabi` | ? | | `armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD diff --git a/src/llvm-project b/src/llvm-project index f9a8d70b6e036..70d09f218d1c8 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit f9a8d70b6e0365ac2172ca6b7f1de0341297458d +Subproject commit 70d09f218d1c84fedabdb74881e214dacd5b0c3d diff --git a/src/test/ui-fulldeps/issue-15149.rs b/src/test/ui-fulldeps/issue-15149.rs index c80628aabc83f..c7ef5ad70a114 100644 --- a/src/test/ui-fulldeps/issue-15149.rs +++ b/src/test/ui-fulldeps/issue-15149.rs @@ -50,7 +50,7 @@ fn test() { .output().unwrap(); assert!(child_output.status.success(), - format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - str::from_utf8(&child_output.stdout).unwrap(), - str::from_utf8(&child_output.stderr).unwrap())); + "child assertion failed\n child stdout:\n {}\n child stderr:\n {}", + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap()); } diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr index 8a298b47fffa7..92547ca4796a4 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr @@ -4,7 +4,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: consider adding a `where` bound for this expression +help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::() - 1]: Sized, @@ -16,7 +16,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: consider adding a `where` bound for this expression +help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] @@ -28,7 +28,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: consider adding a `where` bound for this expression +help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::() - 1]: Sized, @@ -40,7 +40,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: consider adding a `where` bound for this expression +help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] diff --git a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr index 1f6dddb04e56c..00efb61000401 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr @@ -4,7 +4,7 @@ error: unconstrained generic constant LL | [0; size_of::>()] | ^^^^^^^^^^^^^^^^^^^ | -help: consider adding a `where` bound for this expression +help: try adding a `where` bound using this expression: where [u8; size_of::>()]: Sized --> $DIR/different-fn.rs:10:9 | LL | [0; size_of::>()] diff --git a/src/test/ui/const_evaluatable/needs_where_clause.rs b/src/test/ui/const_evaluatable/needs_where_clause.rs new file mode 100644 index 0000000000000..498a2ae753361 --- /dev/null +++ b/src/test/ui/const_evaluatable/needs_where_clause.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +const fn complex_maths(n : usize) -> usize { + 2 * n + 1 +} + +struct Example { + a: [f32; N], + b: [f32; complex_maths::(N)], + //~^ ERROR unconstrained + c: T, +} diff --git a/src/test/ui/const_evaluatable/needs_where_clause.stderr b/src/test/ui/const_evaluatable/needs_where_clause.stderr new file mode 100644 index 0000000000000..e991c508c03f3 --- /dev/null +++ b/src/test/ui/const_evaluatable/needs_where_clause.stderr @@ -0,0 +1,14 @@ +error: unconstrained generic constant + --> $DIR/needs_where_clause.rs:11:6 + | +LL | b: [f32; complex_maths::(N)], + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try adding a `where` bound using this expression: where [u8; complex_maths::(N)]: Sized + --> $DIR/needs_where_clause.rs:11:12 + | +LL | b: [f32; complex_maths::(N)], + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const_evaluatable/no_where_clause.rs b/src/test/ui/const_evaluatable/no_where_clause.rs new file mode 100644 index 0000000000000..12f4a22038ef7 --- /dev/null +++ b/src/test/ui/const_evaluatable/no_where_clause.rs @@ -0,0 +1,29 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features, unused)] + +const fn complex_maths(n : usize) -> usize { + 2 * n + 1 +} + +pub struct Example { + a: [f32; N], + b: [f32; complex_maths(N)], + //~^ ERROR unconstrained generic +} + +impl Example { + pub fn new() -> Self { + Self { + a: [0.; N], + b: [0.; complex_maths(N)], + } + } +} + +impl Example<2> { + pub fn sum(&self) -> f32 { + self.a.iter().sum::() + self.b.iter().sum::() + } +} + +fn main() {} diff --git a/src/test/ui/const_evaluatable/no_where_clause.stderr b/src/test/ui/const_evaluatable/no_where_clause.stderr new file mode 100644 index 0000000000000..65100909e53d5 --- /dev/null +++ b/src/test/ui/const_evaluatable/no_where_clause.stderr @@ -0,0 +1,14 @@ +error: unconstrained generic constant + --> $DIR/no_where_clause.rs:10:6 + | +LL | b: [f32; complex_maths(N)], + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try adding a `where` bound using this expression: where [u8; complex_maths(N)]: Sized + --> $DIR/no_where_clause.rs:10:12 + | +LL | b: [f32; complex_maths(N)], + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-eval/const_panic.rs b/src/test/ui/consts/const-eval/const_panic.rs index 799c185fb8e4b..b33b1475a2221 100644 --- a/src/test/ui/consts/const-eval/const_panic.rs +++ b/src/test/ui/consts/const-eval/const_panic.rs @@ -1,4 +1,5 @@ #![feature(const_panic)] +#![allow(non_fmt_panic)] #![crate_type = "lib"] const MSG: &str = "hello"; diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index c2711952d5837..96f8b28d508e5 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -1,101 +1,101 @@ error: any use of this value will cause an error - --> $DIR/const_panic.rs:6:15 + --> $DIR/const_panic.rs:7:15 | LL | const Z: () = std::panic!("cheese"); | --------------^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:6:15 + | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:7:15 | = note: `#[deny(const_err)]` on by default = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:9:16 + --> $DIR/const_panic.rs:10:16 | LL | const Z2: () = std::panic!(); | ---------------^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:9:16 + | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:10:16 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:12:15 + --> $DIR/const_panic.rs:13:15 | LL | const Y: () = std::unreachable!(); | --------------^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:12:15 + | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:13:15 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:15:15 + --> $DIR/const_panic.rs:16:15 | LL | const X: () = std::unimplemented!(); | --------------^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:15:15 + | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:16:15 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:18:15 + --> $DIR/const_panic.rs:19:15 | LL | const W: () = std::panic!(MSG); | --------------^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'hello', $DIR/const_panic.rs:18:15 + | the evaluated program panicked at 'hello', $DIR/const_panic.rs:19:15 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:21:20 + --> $DIR/const_panic.rs:22:20 | LL | const Z_CORE: () = core::panic!("cheese"); | -------------------^^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:21:20 + | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:22:20 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:24:21 + --> $DIR/const_panic.rs:25:21 | LL | const Z2_CORE: () = core::panic!(); | --------------------^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:24:21 + | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:25:21 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:27:20 + --> $DIR/const_panic.rs:28:20 | LL | const Y_CORE: () = core::unreachable!(); | -------------------^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:27:20 + | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:28:20 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:30:20 + --> $DIR/const_panic.rs:31:20 | LL | const X_CORE: () = core::unimplemented!(); | -------------------^^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:30:20 + | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:31:20 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:33:20 + --> $DIR/const_panic.rs:34:20 | LL | const W_CORE: () = core::panic!(MSG); | -------------------^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'hello', $DIR/const_panic.rs:33:20 + | the evaluated program panicked at 'hello', $DIR/const_panic.rs:34:20 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index a952fe8e76e81..cb6d58a23d936 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -82,7 +82,7 @@ impl Allocator { self.cur_ops.set(self.cur_ops.get() + 1); if self.cur_ops.get() == self.failing_op { - panic!(InjectedFailure); + panic::panic_any(InjectedFailure); } } } diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index ddccee20e12a6..e28bedb982dd9 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -46,7 +46,7 @@ impl Allocator { self.cur_ops.set(self.cur_ops.get() + 1); if self.cur_ops.get() == self.failing_op { - panic!(InjectedFailure); + panic::panic_any(InjectedFailure); } let mut data = self.data.borrow_mut(); @@ -67,7 +67,7 @@ impl<'a> Drop for Ptr<'a> { self.1.cur_ops.set(self.1.cur_ops.get() + 1); if self.1.cur_ops.get() == self.1.failing_op { - panic!(InjectedFailure); + panic::panic_any(InjectedFailure); } } } diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs index 4e3fa9a3c589a..d5886a13558c6 100644 --- a/src/test/ui/fmt/format-args-capture.rs +++ b/src/test/ui/fmt/format-args-capture.rs @@ -31,7 +31,7 @@ fn panic_with_single_argument_does_not_get_formatted() { // RFC #2795 suggests that this may need to change so that captured arguments are formatted. // For stability reasons this will need to part of an edition change. - #[allow(panic_fmt)] + #[allow(non_fmt_panic)] let msg = std::panic::catch_unwind(|| { panic!("{foo}"); }).unwrap_err(); diff --git a/src/test/ui/macros/assert-macro-owned.rs b/src/test/ui/macros/assert-macro-owned.rs index b50fe65c0150f..2846f2a1f8353 100644 --- a/src/test/ui/macros/assert-macro-owned.rs +++ b/src/test/ui/macros/assert-macro-owned.rs @@ -2,6 +2,8 @@ // error-pattern:panicked at 'test-assert-owned' // ignore-emscripten no processes +#![allow(non_fmt_panic)] + fn main() { assert!(false, "test-assert-owned".to_string()); } diff --git a/src/test/ui/macros/macro-comma-behavior-rpass.rs b/src/test/ui/macros/macro-comma-behavior-rpass.rs index c46274d59b658..fd2c590ae5fd6 100644 --- a/src/test/ui/macros/macro-comma-behavior-rpass.rs +++ b/src/test/ui/macros/macro-comma-behavior-rpass.rs @@ -57,7 +57,7 @@ fn writeln_1arg() { // // (Example: Issue #48042) #[test] -#[allow(panic_fmt)] +#[allow(non_fmt_panic)] fn to_format_or_not_to_format() { // ("{}" is the easiest string to test because if this gets // sent to format_args!, it'll simply fail to compile. diff --git a/src/test/ui/mir/mir_drop_order.rs b/src/test/ui/mir/mir_drop_order.rs index 2949437b1e4b6..22c804abf5cc8 100644 --- a/src/test/ui/mir/mir_drop_order.rs +++ b/src/test/ui/mir/mir_drop_order.rs @@ -38,7 +38,7 @@ fn main() { assert_eq!(get(), vec![0, 2, 3, 1]); let _ = std::panic::catch_unwind(|| { - (d(4), &d(5), d(6), &d(7), panic!(InjectedFailure)); + (d(4), &d(5), d(6), &d(7), panic::panic_any(InjectedFailure)); }); // here, the temporaries (5/7) live until the end of the diff --git a/src/test/ui/panic-brace.rs b/src/test/ui/non-fmt-panic.rs similarity index 70% rename from src/test/ui/panic-brace.rs rename to src/test/ui/non-fmt-panic.rs index 754dcc287d0f9..25c53316e1290 100644 --- a/src/test/ui/panic-brace.rs +++ b/src/test/ui/non-fmt-panic.rs @@ -13,19 +13,27 @@ fn main() { core::panic!("Hello {}"); //~ WARN panic message contains an unused formatting placeholder assert!(false, "{:03x} {test} bla"); //~^ WARN panic message contains unused formatting placeholders + assert!(false, S); + //~^ WARN panic message is not a string literal debug_assert!(false, "{{}} bla"); //~ WARN panic message contains braces - panic!(C); // No warning (yet) - panic!(S); // No warning (yet) + panic!(C); //~ WARN panic message is not a string literal + panic!(S); //~ WARN panic message is not a string literal + std::panic!(123); //~ WARN panic message is not a string literal + core::panic!(&*"abc"); //~ WARN panic message is not a string literal panic!(concat!("{", "}")); //~ WARN panic message contains an unused formatting placeholder panic!(concat!("{", "{")); //~ WARN panic message contains braces fancy_panic::fancy_panic!("test {} 123"); //~^ WARN panic message contains an unused formatting placeholder + fancy_panic::fancy_panic!(S); + //~^ WARN panic message is not a string literal + // Check that the lint only triggers for std::panic and core::panic, // not any panic macro: macro_rules! panic { ($e:expr) => (); } panic!("{}"); // OK + panic!(S); // OK } diff --git a/src/test/ui/panic-brace.stderr b/src/test/ui/non-fmt-panic.stderr similarity index 52% rename from src/test/ui/panic-brace.stderr rename to src/test/ui/non-fmt-panic.stderr index 93808891c3c37..45187c518c423 100644 --- a/src/test/ui/panic-brace.stderr +++ b/src/test/ui/non-fmt-panic.stderr @@ -1,35 +1,35 @@ warning: panic message contains a brace - --> $DIR/panic-brace.rs:11:29 + --> $DIR/non-fmt-panic.rs:11:29 | LL | panic!("here's a brace: {"); | ^ | - = note: `#[warn(panic_fmt)]` on by default - = note: this message is not used as a format string, but will be in a future Rust edition + = note: `#[warn(non_fmt_panic)]` on by default + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | panic!("{}", "here's a brace: {"); | ^^^^^ warning: panic message contains a brace - --> $DIR/panic-brace.rs:12:31 + --> $DIR/non-fmt-panic.rs:12:31 | LL | std::panic!("another one: }"); | ^ | - = note: this message is not used as a format string, but will be in a future Rust edition + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | std::panic!("{}", "another one: }"); | ^^^^^ warning: panic message contains an unused formatting placeholder - --> $DIR/panic-brace.rs:13:25 + --> $DIR/non-fmt-panic.rs:13:25 | LL | core::panic!("Hello {}"); | ^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | LL | core::panic!("Hello {}", ...); @@ -40,12 +40,12 @@ LL | core::panic!("{}", "Hello {}"); | ^^^^^ warning: panic message contains unused formatting placeholders - --> $DIR/panic-brace.rs:14:21 + --> $DIR/non-fmt-panic.rs:14:21 | LL | assert!(false, "{:03x} {test} bla"); | ^^^^^^ ^^^^^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing arguments | LL | assert!(false, "{:03x} {test} bla", ...); @@ -55,25 +55,97 @@ help: or add a "{}" format string to use the message literally LL | assert!(false, "{}", "{:03x} {test} bla"); | ^^^^^ +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:16:20 + | +LL | assert!(false, S); + | ^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | assert!(false, "{}", S); + | ^^^^^ + warning: panic message contains braces - --> $DIR/panic-brace.rs:16:27 + --> $DIR/non-fmt-panic.rs:18:27 | LL | debug_assert!(false, "{{}} bla"); | ^^^^ | - = note: this message is not used as a format string, but will be in a future Rust edition + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | debug_assert!(false, "{}", "{{}} bla"); | ^^^^^ +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:19:12 + | +LL | panic!(C); + | ^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | panic!("{}", C); + | ^^^^^ +help: or use std::panic::panic_any instead + | +LL | std::panic::panic_any(C); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:20:12 + | +LL | panic!(S); + | ^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | panic!("{}", S); + | ^^^^^ +help: or use std::panic::panic_any instead + | +LL | std::panic::panic_any(S); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:21:17 + | +LL | std::panic!(123); + | ^^^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | std::panic!("{}", 123); + | ^^^^^ +help: or use std::panic::panic_any instead + | +LL | std::panic::panic_any(123); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:22:18 + | +LL | core::panic!(&*"abc"); + | ^^^^^^^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | core::panic!("{}", &*"abc"); + | ^^^^^ + warning: panic message contains an unused formatting placeholder - --> $DIR/panic-brace.rs:19:12 + --> $DIR/non-fmt-panic.rs:23:12 | LL | panic!(concat!("{", "}")); | ^^^^^^^^^^^^^^^^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | LL | panic!(concat!("{", "}"), ...); @@ -84,24 +156,32 @@ LL | panic!("{}", concat!("{", "}")); | ^^^^^ warning: panic message contains braces - --> $DIR/panic-brace.rs:20:5 + --> $DIR/non-fmt-panic.rs:24:5 | LL | panic!(concat!("{", "{")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this message is not used as a format string, but will be in a future Rust edition + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | panic!("{}", concat!("{", "{")); | ^^^^^ warning: panic message contains an unused formatting placeholder - --> $DIR/panic-brace.rs:22:37 + --> $DIR/non-fmt-panic.rs:26:37 | LL | fancy_panic::fancy_panic!("test {} 123"); | ^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:29:31 + | +LL | fancy_panic::fancy_panic!(S); + | ^ + | + = note: this is no longer accepted in Rust 2021 -warning: 8 warnings emitted +warning: 14 warnings emitted diff --git a/src/test/ui/panics/explicit-panic-msg.rs b/src/test/ui/panics/explicit-panic-msg.rs index 1789e2e62c8b2..bfcc12cd186bd 100644 --- a/src/test/ui/panics/explicit-panic-msg.rs +++ b/src/test/ui/panics/explicit-panic-msg.rs @@ -1,5 +1,6 @@ #![allow(unused_assignments)] #![allow(unused_variables)] +#![allow(non_fmt_panic)] // run-fail // error-pattern:wooooo diff --git a/src/test/ui/panics/panic-macro-any-wrapped.rs b/src/test/ui/panics/panic-macro-any-wrapped.rs index 80c87c6f32c4b..95ae6ffe8be02 100644 --- a/src/test/ui/panics/panic-macro-any-wrapped.rs +++ b/src/test/ui/panics/panic-macro-any-wrapped.rs @@ -2,6 +2,8 @@ // error-pattern:panicked at 'Box' // ignore-emscripten no processes +#![allow(non_fmt_panic)] + fn main() { panic!(Box::new(612_i64)); } diff --git a/src/test/ui/panics/panic-macro-any.rs b/src/test/ui/panics/panic-macro-any.rs index ffc7114c1f5f2..d2a7ba3713a51 100644 --- a/src/test/ui/panics/panic-macro-any.rs +++ b/src/test/ui/panics/panic-macro-any.rs @@ -3,6 +3,7 @@ // ignore-emscripten no processes #![feature(box_syntax)] +#![allow(non_fmt_panic)] fn main() { panic!(box 413 as Box); diff --git a/src/test/ui/panics/while-panic.rs b/src/test/ui/panics/while-panic.rs index 857f65a225228..3c6ee8fa3155e 100644 --- a/src/test/ui/panics/while-panic.rs +++ b/src/test/ui/panics/while-panic.rs @@ -5,7 +5,7 @@ // ignore-emscripten no processes fn main() { - panic!({ + panic!("{}", { while true { panic!("giraffe") } diff --git a/src/test/ui/suggestions/field-access.fixed b/src/test/ui/suggestions/field-access.fixed index 05a4a0eb1266d..ed9aef6e37444 100644 --- a/src/test/ui/suggestions/field-access.fixed +++ b/src/test/ui/suggestions/field-access.fixed @@ -18,17 +18,17 @@ union Foo { fn main() { let a = A { b: B::Fst }; if let B::Fst = a.b {}; //~ ERROR mismatched types [E0308] - //~^ HELP you might have meant to use field `b` of type `B` + //~^ HELP you might have meant to use field `b` whose type is `B` match a.b { - //~^ HELP you might have meant to use field `b` of type `B` - //~| HELP you might have meant to use field `b` of type `B` + //~^ HELP you might have meant to use field `b` whose type is `B` + //~| HELP you might have meant to use field `b` whose type is `B` B::Fst => (), //~ ERROR mismatched types [E0308] B::Snd => (), //~ ERROR mismatched types [E0308] } let foo = Foo { bar: 42 }; match unsafe { foo.bar } { - //~^ HELP you might have meant to use field `bar` of type `u32` + //~^ HELP you might have meant to use field `bar` whose type is `u32` 1u32 => (), //~ ERROR mismatched types [E0308] _ => (), } diff --git a/src/test/ui/suggestions/field-access.rs b/src/test/ui/suggestions/field-access.rs index ad23c0ffa2e74..d80488e8a45f5 100644 --- a/src/test/ui/suggestions/field-access.rs +++ b/src/test/ui/suggestions/field-access.rs @@ -18,17 +18,17 @@ union Foo { fn main() { let a = A { b: B::Fst }; if let B::Fst = a {}; //~ ERROR mismatched types [E0308] - //~^ HELP you might have meant to use field `b` of type `B` + //~^ HELP you might have meant to use field `b` whose type is `B` match a { - //~^ HELP you might have meant to use field `b` of type `B` - //~| HELP you might have meant to use field `b` of type `B` + //~^ HELP you might have meant to use field `b` whose type is `B` + //~| HELP you might have meant to use field `b` whose type is `B` B::Fst => (), //~ ERROR mismatched types [E0308] B::Snd => (), //~ ERROR mismatched types [E0308] } let foo = Foo { bar: 42 }; match foo { - //~^ HELP you might have meant to use field `bar` of type `u32` + //~^ HELP you might have meant to use field `bar` whose type is `u32` 1u32 => (), //~ ERROR mismatched types [E0308] _ => (), } diff --git a/src/test/ui/suggestions/field-access.stderr b/src/test/ui/suggestions/field-access.stderr index aad9872032a2a..b113b3746d87e 100644 --- a/src/test/ui/suggestions/field-access.stderr +++ b/src/test/ui/suggestions/field-access.stderr @@ -9,7 +9,7 @@ LL | if let B::Fst = a {}; | | | expected struct `A`, found enum `B` | -help: you might have meant to use field `b` of type `B` +help: you might have meant to use field `b` whose type is `B` | LL | if let B::Fst = a.b {}; | ^^^ @@ -26,7 +26,7 @@ LL | match a { LL | B::Fst => (), | ^^^^^^ expected struct `A`, found enum `B` | -help: you might have meant to use field `b` of type `B` +help: you might have meant to use field `b` whose type is `B` | LL | match a.b { | ^^^ @@ -43,7 +43,7 @@ LL | match a { LL | B::Snd => (), | ^^^^^^ expected struct `A`, found enum `B` | -help: you might have meant to use field `b` of type `B` +help: you might have meant to use field `b` whose type is `B` | LL | match a.b { | ^^^ @@ -57,7 +57,7 @@ LL | LL | 1u32 => (), | ^^^^ expected union `Foo`, found `u32` | -help: you might have meant to use field `bar` of type `u32` +help: you might have meant to use field `bar` whose type is `u32` | LL | match unsafe { foo.bar } { | ^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/.editorconfig b/src/tools/clippy/.editorconfig index a13173544d80a..ec6e107d547f0 100644 --- a/src/tools/clippy/.editorconfig +++ b/src/tools/clippy/.editorconfig @@ -13,6 +13,8 @@ indent_style = space indent_size = 4 [*.md] +# double whitespace at end of line +# denotes a line break in Markdown trim_trailing_whitespace = false [*.yml] diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 1647df8044ccc..292850bd9e277 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -38,6 +38,7 @@ const OS_TABLE: &[(&str, &str)] = &[ const ARCH_TABLE: &[(&str, &str)] = &[ ("aarch64", "aarch64"), + ("aarch64_be", "aarch64"), ("amd64", "x86_64"), ("arm", "arm"), ("arm64", "aarch64"), @@ -110,6 +111,7 @@ pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[ ]; const BIG_ENDIAN: &[&str] = &[ + "aarch64_be", "armebv7r", "mips", "mips64", @@ -160,7 +162,9 @@ pub fn matches_env(triple: &str, name: &str) -> bool { } pub fn get_pointer_width(triple: &str) -> &'static str { - if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") { + if (triple.contains("64") && !triple.ends_with("gnux32") && !triple.ends_with("gnu_ilp32")) + || triple.starts_with("s390x") + { "64bit" } else if triple.starts_with("avr") { "16bit"