diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index f30f34acf5c6c..b89976eca26c4 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -291,15 +291,6 @@ fn main() { cmd.arg("-Z").arg("verify-llvm-ir"); } - let color = match env::var("RUSTC_COLOR") { - Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"), - Err(_) => 0, - }; - - if color != 0 { - cmd.arg("--color=always"); - } - if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none() { cmd.arg("-Dwarnings"); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4205d5aebffa1..608f2c982c2a5 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -29,7 +29,7 @@ use build_helper::{output, mtime, up_to_date}; use filetime::FileTime; use serde_json; -use util::{exe, libdir, is_dylib, CiEnv}; +use util::{exe, libdir, is_dylib}; use {Compiler, Mode, GitRepo}; use native; @@ -1034,29 +1034,6 @@ pub fn add_to_sysroot(builder: &Builder, sysroot_dst: &Path, stamp: &Path) { } } -// Avoiding a dependency on winapi to keep compile times down -#[cfg(unix)] -fn stderr_isatty() -> bool { - use libc; - unsafe { libc::isatty(libc::STDERR_FILENO) != 0 } -} -#[cfg(windows)] -fn stderr_isatty() -> bool { - type DWORD = u32; - type BOOL = i32; - type HANDLE = *mut u8; - const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; - extern "system" { - fn GetStdHandle(which: DWORD) -> HANDLE; - fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL; - } - unsafe { - let handle = GetStdHandle(STD_ERROR_HANDLE); - let mut out = 0; - GetConsoleMode(handle, &mut out) != 0 - } -} - pub fn run_cargo(builder: &Builder, cargo: &mut Command, tail_args: Vec, @@ -1218,15 +1195,6 @@ pub fn stream_cargo( cargo.arg("--message-format").arg("json") .stdout(Stdio::piped()); - if stderr_isatty() && builder.ci_env == CiEnv::None && - // if the terminal is reported as dumb, then we don't want to enable color for rustc - env::var_os("TERM").map(|t| t != *"dumb").unwrap_or(true) { - // since we pass message-format=json to cargo, we need to tell the rustc - // wrapper to give us colored output if necessary. This is because we - // only want Cargo's JSON output, not rustcs. - cargo.env("RUSTC_COLOR", "1"); - } - for arg in tail_args { cargo.arg(arg); } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index da4a56cfecd6e..aed9020d9d14a 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -119,7 +119,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn first(&self) -> Option<&T> { - if self.is_empty() { None } else { Some(&self[0]) } + self.get(0) } /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty. @@ -137,7 +137,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn first_mut(&mut self) -> Option<&mut T> { - if self.is_empty() { None } else { Some(&mut self[0]) } + self.get_mut(0) } /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty. @@ -239,7 +239,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn last(&self) -> Option<&T> { - if self.is_empty() { None } else { Some(&self[self.len() - 1]) } + let last_idx = self.len().checked_sub(1)?; + self.get(last_idx) } /// Returns a mutable pointer to the last item in the slice. @@ -257,9 +258,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn last_mut(&mut self) -> Option<&mut T> { - let len = self.len(); - if len == 0 { return None; } - Some(&mut self[len - 1]) + let last_idx = self.len().checked_sub(1)?; + self.get_mut(last_idx) } /// Returns a reference to an element or subslice depending on the type of @@ -1618,6 +1618,63 @@ impl [T] { } } + /// Copies elements from one part of the slice to another part of itself, + /// using a memmove. + /// + /// `src` is the range within `self` to copy from. `dest` is the starting + /// index of the range within `self` to copy to, which will have the same + /// length as `src`. The two ranges may overlap. The ends of the two ranges + /// must be less than or equal to `self.len()`. + /// + /// # Panics + /// + /// This function will panic if either range exceeds the end of the slice, + /// or if the end of `src` is before the start. + /// + /// # Examples + /// + /// Copying four bytes within a slice: + /// + /// ``` + /// # #![feature(copy_within)] + /// let mut bytes = *b"Hello, World!"; + /// + /// bytes.copy_within(1..5, 8); + /// + /// assert_eq!(&bytes, b"Hello, Wello!"); + /// ``` + #[unstable(feature = "copy_within", issue = "54236")] + pub fn copy_within>(&mut self, src: R, dest: usize) + where + T: Copy, + { + let src_start = match src.start_bound() { + ops::Bound::Included(&n) => n, + ops::Bound::Excluded(&n) => n + .checked_add(1) + .unwrap_or_else(|| slice_index_overflow_fail()), + ops::Bound::Unbounded => 0, + }; + let src_end = match src.end_bound() { + ops::Bound::Included(&n) => n + .checked_add(1) + .unwrap_or_else(|| slice_index_overflow_fail()), + ops::Bound::Excluded(&n) => n, + ops::Bound::Unbounded => self.len(), + }; + assert!(src_start <= src_end, "src end is before src start"); + assert!(src_end <= self.len(), "src is out of bounds"); + let count = src_end - src_start; + assert!(dest <= self.len() - count, "dest is out of bounds"); + unsafe { + ptr::copy( + self.get_unchecked(src_start), + self.get_unchecked_mut(dest), + count, + ); + } + } + /// Swaps all elements in `self` with those in `other`. /// /// The length of `other` must be the same as `self`. diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 4f3086575c0cf..8fc32f40b9920 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -39,6 +39,7 @@ #![feature(inner_deref)] #![feature(slice_internals)] #![feature(option_replace)] +#![feature(copy_within)] extern crate core; extern crate test; diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 012dc9bf5e0b9..d46a35ab82cfc 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1000,3 +1000,49 @@ fn test_align_to_empty_mid() { assert_eq!(mid.as_ptr() as usize % mem::align_of::(), 0); } } + +#[test] +fn test_copy_within() { + // Start to end, with a RangeTo. + let mut bytes = *b"Hello, World!"; + bytes.copy_within(..3, 10); + assert_eq!(&bytes, b"Hello, WorHel"); + + // End to start, with a RangeFrom. + let mut bytes = *b"Hello, World!"; + bytes.copy_within(10.., 0); + assert_eq!(&bytes, b"ld!lo, World!"); + + // Overlapping, with a RangeInclusive. + let mut bytes = *b"Hello, World!"; + bytes.copy_within(0..=11, 1); + assert_eq!(&bytes, b"HHello, World"); + + // Whole slice, with a RangeFull. + let mut bytes = *b"Hello, World!"; + bytes.copy_within(.., 0); + assert_eq!(&bytes, b"Hello, World!"); +} + +#[test] +#[should_panic(expected = "src is out of bounds")] +fn test_copy_within_panics_src_too_long() { + let mut bytes = *b"Hello, World!"; + // The length is only 13, so 14 is out of bounds. + bytes.copy_within(10..14, 0); +} + +#[test] +#[should_panic(expected = "dest is out of bounds")] +fn test_copy_within_panics_dest_too_long() { + let mut bytes = *b"Hello, World!"; + // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. + bytes.copy_within(0..4, 10); +} +#[test] +#[should_panic(expected = "src end is before src start")] +fn test_copy_within_panics_src_inverted() { + let mut bytes = *b"Hello, World!"; + // 2 is greater than 1, so this range is invalid. + bytes.copy_within(2..1, 0); +} diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 1a0dde3ccd7c3..d885f9b406f59 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -48,7 +48,7 @@ pub mod rustc; mod diagnostic; #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] -pub use diagnostic::{Diagnostic, Level}; +pub use diagnostic::{Diagnostic, Level, MultiSpan}; use std::{ascii, fmt, iter}; use std::path::PathBuf; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f9e717f8d456e..74e7c6c21edd9 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1937,8 +1937,7 @@ impl EarlyLintPass for KeywordIdents { let next_edition = match cx.sess.edition() { Edition::Edition2015 => { match &ident.as_str()[..] { - "async" | - "try" => Edition::Edition2018, + "async" | "try" | "dyn" => Edition::Edition2018, _ => return, } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index dfed41cb1defd..67e4394c9aaa0 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -22,6 +22,7 @@ use std::collections::VecDeque; use std::fmt; use syntax::symbol::keywords; use syntax_pos::Span; +use syntax::errors::Applicability; mod region_name; mod var_name; @@ -540,7 +541,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { RegionName::Named(name) => format!("{}", name), RegionName::Synthesized(_) => "'_".to_string(), }; - diag.span_suggestion( + diag.span_suggestion_with_applicability( span, &format!( "to allow this impl Trait to capture borrowed data with lifetime \ @@ -548,6 +549,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr_name, suggestable_fr_name, ), format!("{} + {}", snippet, suggestable_fr_name), + Applicability::MachineApplicable, ); } } diff --git a/src/librustc_target/spec/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs index 8b6bb5dec9138..8cb5a33cdb5f8 100644 --- a/src/librustc_target/spec/netbsd_base.rs +++ b/src/librustc_target/spec/netbsd_base.rs @@ -29,6 +29,7 @@ pub fn opts() -> TargetOptions { executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, + no_default_libraries: false, has_rpath: true, pre_link_args: args, position_independent_executables: true, diff --git a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs index af846653af727..684bf5a6c1026 100644 --- a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs +++ b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs @@ -21,7 +21,6 @@ pub fn target() -> TargetResult { base.has_rpath = false; base.position_independent_executables = false; base.disable_redzone = true; - base.no_default_libraries = false; base.exe_allocation_crate = None; base.stack_probes = true; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e8f1733e532de..98252b81fd57a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -272,6 +272,7 @@ impl DocAccessLevels for AccessLevels { pub fn new_handler(error_format: ErrorOutputType, source_map: Option>, treat_err_as_bug: bool, + ui_testing: bool, ) -> errors::Handler { // rustdoc doesn't override (or allow to override) anything from this that is relevant here, so // stick to the defaults @@ -283,7 +284,7 @@ pub fn new_handler(error_format: ErrorOutputType, source_map.map(|cm| cm as _), false, sessopts.debugging_opts.teach, - ).ui_testing(sessopts.debugging_opts.ui_testing) + ).ui_testing(ui_testing) ), ErrorOutputType::Json(pretty) => { let source_map = source_map.unwrap_or_else( @@ -293,7 +294,7 @@ pub fn new_handler(error_format: ErrorOutputType, None, source_map, pretty, - ).ui_testing(sessopts.debugging_opts.ui_testing) + ).ui_testing(ui_testing) ) }, ErrorOutputType::Short(color_config) => Box::new( @@ -335,6 +336,7 @@ pub fn run_core(search_paths: SearchPaths, mut manual_passes: Vec, mut default_passes: passes::DefaultPassOption, treat_err_as_bug: bool, + ui_testing: bool, ) -> (clean::Crate, RenderInfo, Vec) { // Parse, resolve, and typecheck the given crate. @@ -389,6 +391,8 @@ pub fn run_core(search_paths: SearchPaths, actually_rustdoc: true, debugging_opts: config::DebuggingOptions { force_unstable_if_unmarked, + treat_err_as_bug, + ui_testing, ..config::basic_debugging_options() }, error_format, @@ -400,7 +404,8 @@ pub fn run_core(search_paths: SearchPaths, let source_map = Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping())); let diagnostic_handler = new_handler(error_format, Some(source_map.clone()), - treat_err_as_bug); + treat_err_as_bug, + ui_testing); let mut sess = session::build_session_( sessopts, cpath, diagnostic_handler, source_map, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5607c97a49689..2456a5ad14acc 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -409,8 +409,11 @@ fn main_args(args: &[String]) -> isize { let treat_err_as_bug = matches.opt_strs("Z").iter().any(|x| { *x == "treat-err-as-bug" }); + let ui_testing = matches.opt_strs("Z").iter().any(|x| { + *x == "ui-testing" + }); - let diag = core::new_handler(error_format, None, treat_err_as_bug); + let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing); // check for deprecated options check_deprecated_options(&matches, &diag); @@ -565,7 +568,7 @@ fn main_args(args: &[String]) -> isize { let res = acquire_input(PathBuf::from(input), externs, edition, cg, &matches, error_format, move |out| { let Output { krate, passes, renderinfo } = out; - let diag = core::new_handler(error_format, None, treat_err_as_bug); + let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing); info!("going to format"); match output_format.as_ref().map(|s| &**s) { Some("html") | None => { @@ -702,6 +705,9 @@ where R: 'static + Send, let treat_err_as_bug = matches.opt_strs("Z").iter().any(|x| { *x == "treat-err-as-bug" }); + let ui_testing = matches.opt_strs("Z").iter().any(|x| { + *x == "ui-testing" + }); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -715,7 +721,7 @@ where R: 'static + Send, display_warnings, crate_name.clone(), force_unstable_if_unmarked, edition, cg, error_format, lint_opts, lint_cap, describe_lints, manual_passes, default_passes, - treat_err_as_bug); + treat_err_as_bug, ui_testing); info!("finished with rustc"); diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index e60ef46e738b4..34b7713ff6ff4 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -220,6 +220,126 @@ macro_rules! eprintln { }) } +/// A macro for quick and dirty debugging with which you can inspect +/// the value of a given expression. An example: +/// +/// ```rust +/// #![feature(dbg_macro)] +/// +/// let a = 2; +/// let b = dbg!(a * 2) + 1; +/// // ^-- prints: [src/main.rs:4] a * 2 = 4 +/// assert_eq!(b, 5); +/// ``` +/// +/// The macro works by using the `Debug` implementation of the type of +/// the given expression to print the value to [stderr] along with the +/// source location of the macro invocation as well as the source code +/// of the expression. +/// +/// Invoking the macro on an expression moves and takes ownership of it +/// before returning the evaluated expression unchanged. If the type +/// of the expression does not implement `Copy` and you don't want +/// to give up ownership, you can instead borrow with `dbg!(&expr)` +/// for some expression `expr`. +/// +/// Note that the macro is intended as a debugging tool and therefore you +/// should avoid having uses of it in version control for longer periods. +/// Use cases involving debug output that should be added to version control +/// may be better served by macros such as `debug!` from the `log` crate. +/// +/// # Stability +/// +/// The exact output printed by this macro should not be relied upon +/// and is subject to future changes. +/// +/// # Panics +/// +/// Panics if writing to `io::stderr` fails. +/// +/// # Further examples +/// +/// With a method call: +/// +/// ```rust +/// #![feature(dbg_macro)] +/// +/// fn foo(n: usize) { +/// if let Some(_) = dbg!(n.checked_sub(4)) { +/// // ... +/// } +/// } +/// +/// foo(3) +/// ``` +/// +/// This prints to [stderr]: +/// +/// ```text,ignore +/// [src/main.rs:4] n.checked_sub(4) = None +/// ``` +/// +/// Naive factorial implementation: +/// +/// ```rust +/// #![feature(dbg_macro)] +/// +/// fn factorial(n: u32) -> u32 { +/// if dbg!(n <= 1) { +/// dbg!(1) +/// } else { +/// dbg!(n * factorial(n - 1)) +/// } +/// } +/// +/// dbg!(factorial(4)); +/// ``` +/// +/// This prints to [stderr]: +/// +/// ```text,ignore +/// [src/main.rs:3] n <= 1 = false +/// [src/main.rs:3] n <= 1 = false +/// [src/main.rs:3] n <= 1 = false +/// [src/main.rs:3] n <= 1 = true +/// [src/main.rs:4] 1 = 1 +/// [src/main.rs:5] n * factorial(n - 1) = 2 +/// [src/main.rs:5] n * factorial(n - 1) = 6 +/// [src/main.rs:5] n * factorial(n - 1) = 24 +/// [src/main.rs:11] factorial(4) = 24 +/// ``` +/// +/// The `dbg!(..)` macro moves the input: +/// +/// ```compile_fail +/// #![feature(dbg_macro)] +/// +/// /// A wrapper around `usize` which importantly is not Copyable. +/// #[derive(Debug)] +/// struct NoCopy(usize); +/// +/// let a = NoCopy(42); +/// let _ = dbg!(a); // <-- `a` is moved here. +/// let _ = dbg!(a); // <-- `a` is moved again; error! +/// ``` +/// +/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr) +#[macro_export] +#[unstable(feature = "dbg_macro", issue = "54306")] +macro_rules! dbg { + ($val:expr) => { + // Use of `match` here is intentional because it affects the lifetimes + // of temporaries - https://stackoverflow.com/a/48732525/1063961 + match $val { + tmp => { + eprintln!("[{}:{}] {} = {:#?}", + file!(), line!(), stringify!($val), &tmp); + tmp + } + } + } +} + #[macro_export] #[unstable(feature = "await_macro", issue = "50547")] #[allow_internal_unstable] diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6ec1ad969ee70..f7af8a3c34cf3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1578,8 +1578,9 @@ impl<'a> Parser<'a> { impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus; TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) } else if self.check_keyword(keywords::Dyn) && - self.look_ahead(1, |t| t.can_begin_bound() && - !can_continue_type_after_non_fn_ident(t)) { + (self.span.edition() == Edition::Edition2018 || + self.look_ahead(1, |t| t.can_begin_bound() && + !can_continue_type_after_non_fn_ident(t))) { self.bump(); // `dyn` // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 6e8014284ec40..01bc7f6ad302b 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -136,6 +136,7 @@ fn ident_can_begin_type(ident: ast::Ident, is_raw: bool) -> bool { keywords::Unsafe.name(), keywords::Extern.name(), keywords::Typeof.name(), + keywords::Dyn.name(), ].contains(&ident.name) } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index defdca9abd15a..d412412fc655e 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -414,26 +414,25 @@ declare_keywords! { (50, Yield, "yield") // Edition-specific keywords reserved for future use. - (51, Async, "async") // >= 2018 Edition Only - (52, Try, "try") // >= 2018 Edition Only + (51, Async, "async") // >= 2018 Edition only + (52, Dyn, "dyn") // >= 2018 Edition only + (53, Try, "try") // >= 2018 Edition only // Special lifetime names - (53, UnderscoreLifetime, "'_") - (54, StaticLifetime, "'static") + (54, UnderscoreLifetime, "'_") + (55, StaticLifetime, "'static") // Weak keywords, have special meaning only in specific contexts. - (55, Auto, "auto") - (56, Catch, "catch") - (57, Default, "default") - (58, Dyn, "dyn") + (56, Auto, "auto") + (57, Catch, "catch") + (58, Default, "default") (59, Union, "union") (60, Existential, "existential") } impl Symbol { fn is_unused_keyword_2018(self) -> bool { - self >= keywords::Async.name() && - self <= keywords::Try.name() + self >= keywords::Async.name() && self <= keywords::Try.name() } } diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 66ee48ed4c9c0..b82cbc1ab36fd 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -1,13 +1,13 @@ error: `[v2]` cannot be resolved, ignoring it... --> $DIR/deny-intra-link-resolution-failure.rs:13:6 | -13 | /// [v2] //~ ERROR +LL | /// [v2] //~ ERROR | ^^ cannot be resolved, ignoring | note: lint level defined here --> $DIR/deny-intra-link-resolution-failure.rs:11:9 | -11 | #![deny(intra_doc_link_resolution_failure)] +LL | #![deny(intra_doc_link_resolution_failure)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` diff --git a/src/test/rustdoc-ui/deprecated-attrs.stderr b/src/test/rustdoc-ui/deprecated-attrs.stderr index 77ba4b2a2b67e..5bd62d60b48f3 100644 --- a/src/test/rustdoc-ui/deprecated-attrs.stderr +++ b/src/test/rustdoc-ui/deprecated-attrs.stderr @@ -1,9 +1,9 @@ warning: the `#![doc(no_default_passes)]` attribute is considered deprecated - | - = warning: please see https://github.com/rust-lang/rust/issues/44136 - = help: you may want to use `#![doc(document_private_items)]` + | + = warning: please see https://github.com/rust-lang/rust/issues/44136 + = help: you may want to use `#![doc(document_private_items)]` warning: the `#![doc(passes = "...")]` attribute is considered deprecated - | - = warning: please see https://github.com/rust-lang/rust/issues/44136 + | + = warning: please see https://github.com/rust-lang/rust/issues/44136 diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr index 231963976ea75..498d02a7d1caf 100644 --- a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr @@ -1,13 +1,13 @@ error: `[TypeAlias::hoge]` cannot be resolved, ignoring it... --> $DIR/intra-doc-alias-ice.rs:15:30 | -15 | /// [broken cross-reference](TypeAlias::hoge) //~ ERROR +LL | /// [broken cross-reference](TypeAlias::hoge) //~ ERROR | ^^^^^^^^^^^^^^^ cannot be resolved, ignoring | note: lint level defined here --> $DIR/intra-doc-alias-ice.rs:11:9 | -11 | #![deny(intra_doc_link_resolution_failure)] +LL | #![deny(intra_doc_link_resolution_failure)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 2a51e94b1f5d7..c05f99fadc9e4 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -1,7 +1,7 @@ warning: `[Foo::baz]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:13:23 | -13 | //! Test with [Foo::baz], [Bar::foo], ... +LL | //! Test with [Foo::baz], [Bar::foo], ... | ^^^^^^^^ cannot be resolved, ignoring | = note: #[warn(intra_doc_link_resolution_failure)] on by default @@ -10,7 +10,7 @@ warning: `[Foo::baz]` cannot be resolved, ignoring it... warning: `[Bar::foo]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:13:35 | -13 | //! Test with [Foo::baz], [Bar::foo], ... +LL | //! Test with [Foo::baz], [Bar::foo], ... | ^^^^^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -18,7 +18,7 @@ warning: `[Bar::foo]` cannot be resolved, ignoring it... warning: `[Uniooon::X]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:14:13 | -14 | //! , [Uniooon::X] and [Qux::Z]. +LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -26,7 +26,7 @@ warning: `[Uniooon::X]` cannot be resolved, ignoring it... warning: `[Qux::Z]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:14:30 | -14 | //! , [Uniooon::X] and [Qux::Z]. +LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -34,7 +34,7 @@ warning: `[Qux::Z]` cannot be resolved, ignoring it... warning: `[Uniooon::X]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:16:14 | -16 | //! , [Uniooon::X] and [Qux::Z]. +LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -42,7 +42,7 @@ warning: `[Uniooon::X]` cannot be resolved, ignoring it... warning: `[Qux::Z]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:16:31 | -16 | //! , [Uniooon::X] and [Qux::Z]. +LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -50,7 +50,7 @@ warning: `[Qux::Z]` cannot be resolved, ignoring it... warning: `[Qux:Y]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:18:13 | -18 | /// [Qux:Y] +LL | /// [Qux:Y] | ^^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -58,7 +58,7 @@ warning: `[Qux:Y]` cannot be resolved, ignoring it... warning: `[BarA]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:24:10 | -24 | /// bar [BarA] bar +LL | /// bar [BarA] bar | ^^^^ cannot be resolved, ignoring | = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` @@ -66,11 +66,11 @@ warning: `[BarA]` cannot be resolved, ignoring it... warning: `[BarB]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:28:1 | -28 | / /** -29 | | * Foo -30 | | * bar [BarB] bar -31 | | * baz -32 | | */ +LL | / /** +LL | | * Foo +LL | | * bar [BarB] bar +LL | | * baz +LL | | */ | |___^ | = note: the link appears in this line: @@ -82,13 +82,13 @@ warning: `[BarB]` cannot be resolved, ignoring it... warning: `[BarC]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:35:1 | -35 | / /** Foo -36 | | -37 | | bar [BarC] bar -38 | | baz +LL | / /** Foo +LL | | +LL | | bar [BarC] bar +LL | | baz ... | -44 | | -45 | | */ +LL | | +LL | | */ | |__^ | = note: the link appears in this line: @@ -100,7 +100,7 @@ warning: `[BarC]` cannot be resolved, ignoring it... warning: `[BarD]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:48:1 | -48 | #[doc = "Foo/nbar [BarD] bar/nbaz"] +LL | #[doc = "Foo/nbar [BarD] bar/nbaz"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: @@ -112,10 +112,10 @@ warning: `[BarD]` cannot be resolved, ignoring it... warning: `[BarF]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:53:9 | -53 | #[doc = $f] +LL | #[doc = $f] | ^^^^^^^^^^^ ... -57 | f!("Foo/nbar [BarF] bar/nbaz"); +LL | f!("Foo/nbar [BarF] bar/nbaz"); | ------------------------------- in this macro invocation | = note: the link appears in this line: diff --git a/src/test/ui/issues/issue-38940.rs b/src/test/ui/issues/issue-38940.rs new file mode 100644 index 0000000000000..7f9b141e02e3c --- /dev/null +++ b/src/test/ui/issues/issue-38940.rs @@ -0,0 +1,46 @@ +// issue-38940: error printed twice for deref recursion limit exceeded +// Test that the recursion limit can be changed. In this case, we have +// deeply nested types that will fail the `Send` check by overflow +// when the recursion limit is set very low. +#![allow(dead_code)] +#![recursion_limit="10"] +macro_rules! link { + ($outer:ident, $inner:ident) => { + struct $outer($inner); + impl $outer { + fn new() -> $outer { + $outer($inner::new()) + } + } + impl std::ops::Deref for $outer { + type Target = $inner; + fn deref(&self) -> &$inner { + &self.0 + } + } + } +} +struct Bottom; +impl Bottom { + fn new() -> Bottom { + Bottom + } +} +link!(Top, A); +link!(A, B); +link!(B, C); +link!(C, D); +link!(D, E); +link!(E, F); +link!(F, G); +link!(G, H); +link!(H, I); +link!(I, J); +link!(J, K); +link!(K, Bottom); +fn main() { + let t = Top::new(); + let x: &Bottom = &t; + //~^ ERROR mismatched types + //~| ERROR reached the recursion limit while auto-dereferencing I +} diff --git a/src/test/ui/issues/issue-38940.stderr b/src/test/ui/issues/issue-38940.stderr new file mode 100644 index 0000000000000..2d3cfda9a5f72 --- /dev/null +++ b/src/test/ui/issues/issue-38940.stderr @@ -0,0 +1,21 @@ +error[E0055]: reached the recursion limit while auto-dereferencing I + --> $DIR/issue-38940.rs:43:22 + | +LL | let x: &Bottom = &t; + | ^^ deref recursion limit reached + | + = help: consider adding a `#![recursion_limit="20"]` attribute to your crate + +error[E0308]: mismatched types + --> $DIR/issue-38940.rs:43:22 + | +LL | let x: &Bottom = &t; + | ^^ expected struct `Bottom`, found struct `Top` + | + = note: expected type `&Bottom` + found type `&Top` + +error: aborting due to 2 previous errors + +Some errors occurred: E0055, E0308. +For more information about an error, try `rustc --explain E0055`. diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs new file mode 100644 index 0000000000000..3f4656004e7a5 --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs @@ -0,0 +1,119 @@ +// run-pass + +// Tests ensuring that `dbg!(expr)` has the expected run-time behavior. +// as well as some compile time properties we expect. + +#![feature(dbg_macro)] + +#[derive(Copy, Clone, Debug)] +struct Unit; + +#[derive(Copy, Clone, Debug, PartialEq)] +struct Point { + x: T, + y: T, +} + +#[derive(Debug, PartialEq)] +struct NoCopy(usize); + +fn test() { + let a: Unit = dbg!(Unit); + let _: Unit = dbg!(a); + // We can move `a` because it's Copy. + drop(a); + + // `Point` will be faithfully formatted according to `{:#?}`. + let a = Point { x: 42, y: 24 }; + let b: Point = dbg!(Point { x: 42, y: 24 }); // test stringify!(..) + let c: Point = dbg!(b); + // Identity conversion: + assert_eq!(a, b); + assert_eq!(a, c); + // We can move `b` because it's Copy. + drop(b); + + // Test that we can borrow and that successive applications is still identity. + let a = NoCopy(1337); + let b: &NoCopy = dbg!(dbg!(&a)); + assert_eq!(&a, b); + + // Test involving lifetimes of temporaries: + fn f<'a>(x: &'a u8) -> &'a u8 { x } + let a: &u8 = dbg!(f(&42)); + assert_eq!(a, &42); + + // Test side effects: + let mut foo = 41; + assert_eq!(7331, dbg!({ + foo += 1; + eprintln!("before"); + 7331 + })); + assert_eq!(foo, 42); +} + +fn validate_stderr(stderr: Vec) { + assert_eq!(stderr, &[ + ":21] Unit = Unit", + + ":22] a = Unit", + + ":28] Point{x: 42, y: 24,} = Point {", + " x: 42,", + " y: 24", + "}", + + ":29] b = Point {", + " x: 42,", + " y: 24", + "}", + + ":38] &a = NoCopy(", + " 1337", + ")", + + ":38] dbg!(& a) = NoCopy(", + " 1337", + ")", + ":43] f(&42) = 42", + + "before", + ":48] { foo += 1; eprintln!(\"before\"); 7331 } = 7331", + ]); +} + +fn main() { + // The following is a hack to deal with compiletest's inability + // to check the output (to stdout) of run-pass tests. + use std::env; + use std::process::Command; + + let mut args = env::args(); + let prog = args.next().unwrap(); + let child = args.next(); + if let Some("child") = child.as_ref().map(|s| &**s) { + // Only run the test if we've been spawned as 'child' + test() + } else { + // This essentially spawns as 'child' to run the tests + // and then it collects output of stderr and checks the output + // against what we expect. + let out = Command::new(&prog).arg("child").output().unwrap(); + assert!(out.status.success()); + assert!(out.stdout.is_empty()); + + let stderr = String::from_utf8(out.stderr).unwrap(); + let stderr = stderr.lines().map(|mut s| { + if s.starts_with("[") { + // Strip `[` and file path: + s = s.trim_start_matches("["); + assert!(s.starts_with(file!())); + s = s.trim_start_matches(file!()); + } + s.to_owned() + }).collect(); + + validate_stderr(stderr); + } +} diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.rs new file mode 100644 index 0000000000000..b237c6f147bf7 --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.rs @@ -0,0 +1,5 @@ +// Feature gate test for `dbg!(..)`. + +fn main() { + dbg!(1); +} diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.stderr new file mode 100644 index 0000000000000..64df1e196d285 --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.stderr @@ -0,0 +1,11 @@ +error[E0658]: macro dbg! is unstable (see issue #54306) + --> $DIR/dbg-macro-feature-gate.rs:4:5 + | +LL | dbg!(1); + | ^^^^^^^^ + | + = help: add #![feature(dbg_macro)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr new file mode 100644 index 0000000000000..bf99fef3bbd2f --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `a` + --> $DIR/dbg-macro-move-semantics.rs:11:18 + | +LL | let _ = dbg!(a); + | ------- value moved here +LL | let _ = dbg!(a); + | ^ value used here after move + | + = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs new file mode 100644 index 0000000000000..bcf508d9af5d7 --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs @@ -0,0 +1,12 @@ +// Test ensuring that `dbg!(expr)` will take ownership of the argument. + +#![feature(dbg_macro)] + +#[derive(Debug)] +struct NoCopy(usize); + +fn main() { + let a = NoCopy(0); + let _ = dbg!(a); + let _ = dbg!(a); +} diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr new file mode 100644 index 0000000000000..1064317438515 --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr @@ -0,0 +1,25 @@ +error[E0382]: use of moved value: `a` + --> $DIR/dbg-macro-move-semantics.rs:11:18 + | +LL | let _ = dbg!(a); + | ------- value moved here +LL | let _ = dbg!(a); + | ^ value used here after move + | + = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error[E0382]: use of moved value: `a` + --> $DIR/dbg-macro-move-semantics.rs:11:13 + | +LL | let _ = dbg!(a); + | ------- value moved here +LL | let _ = dbg!(a); + | ^^^^^^^ value used here after move + | + = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs new file mode 100644 index 0000000000000..8e6f3b226fc1e --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs @@ -0,0 +1,9 @@ +// Test ensuring that `dbg!(expr)` requires the passed type to implement `Debug`. + +#![feature(dbg_macro)] + +struct NotDebug; + +fn main() { + let _: NotDebug = dbg!(NotDebug); +} diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr new file mode 100644 index 0000000000000..a3b6a1761b991 --- /dev/null +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -0,0 +1,15 @@ +error[E0277]: `NotDebug` doesn't implement `std::fmt::Debug` + --> $DIR/dbg-macro-requires-debug.rs:8:23 + | +LL | let _: NotDebug = dbg!(NotDebug); + | ^^^^^^^^^^^^^^ `NotDebug` cannot be formatted using `{:?}` + | + = help: the trait `std::fmt::Debug` is not implemented for `NotDebug` + = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&NotDebug` + = note: required by `std::fmt::Debug::fmt` + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/rust-2018/dyn-keyword.fixed b/src/test/ui/rust-2018/dyn-keyword.fixed new file mode 100644 index 0000000000000..e9cda1af93932 --- /dev/null +++ b/src/test/ui/rust-2018/dyn-keyword.fixed @@ -0,0 +1,10 @@ +// edition:2015 +// run-rustfix + +#![allow(unused_variables)] +#![deny(keyword_idents)] + +fn main() { + let r#dyn = (); //~ ERROR dyn + //~^ WARN hard error in the 2018 edition +} diff --git a/src/test/ui/rust-2018/dyn-keyword.rs b/src/test/ui/rust-2018/dyn-keyword.rs new file mode 100644 index 0000000000000..bdd3a90cab9ec --- /dev/null +++ b/src/test/ui/rust-2018/dyn-keyword.rs @@ -0,0 +1,10 @@ +// edition:2015 +// run-rustfix + +#![allow(unused_variables)] +#![deny(keyword_idents)] + +fn main() { + let dyn = (); //~ ERROR dyn + //~^ WARN hard error in the 2018 edition +} diff --git a/src/test/ui/rust-2018/dyn-keyword.stderr b/src/test/ui/rust-2018/dyn-keyword.stderr new file mode 100644 index 0000000000000..5a3e00ab1d96a --- /dev/null +++ b/src/test/ui/rust-2018/dyn-keyword.stderr @@ -0,0 +1,16 @@ +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-keyword.rs:8:9 + | +LL | let dyn = (); //~ ERROR dyn + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | +note: lint level defined here + --> $DIR/dyn-keyword.rs:5:9 + | +LL | #![deny(keyword_idents)] + | ^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: aborting due to previous error + diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.rs b/src/test/ui/rust-2018/dyn-trait-compatibility.rs new file mode 100644 index 0000000000000..9548df5959bd4 --- /dev/null +++ b/src/test/ui/rust-2018/dyn-trait-compatibility.rs @@ -0,0 +1,8 @@ +// edition:2018 + +type A0 = dyn; +type A1 = dyn::dyn; //~ERROR expected identifier, found reserved keyword +type A2 = dyn; //~ERROR expected identifier, found `<` +type A3 = dyn<::dyn>; + +fn main() {} diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr new file mode 100644 index 0000000000000..ea0483394b5ea --- /dev/null +++ b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr @@ -0,0 +1,14 @@ +error: expected identifier, found reserved keyword `dyn` + --> $DIR/dyn-trait-compatibility.rs:4:16 + | +LL | type A1 = dyn::dyn; //~ERROR expected identifier, found reserved keyword + | ^^^ expected identifier, found reserved keyword + +error: expected identifier, found `<` + --> $DIR/dyn-trait-compatibility.rs:5:14 + | +LL | type A2 = dyn; //~ERROR expected identifier, found `<` + | ^ expected identifier + +error: aborting due to 2 previous errors +