diff --git a/.mailmap b/.mailmap index d265f45c5cafa..0733086284947 100644 --- a/.mailmap +++ b/.mailmap @@ -161,6 +161,7 @@ Michael Woerister MickaΓ«l Raybaud-Roig m-r-r Ms2ger Mukilan Thiagarajan +Nathan West Nathan Wilson Nathaniel Herman Nathaniel Herman Neil Pankey diff --git a/RELEASES.md b/RELEASES.md index 841467b69c986..4cda02c5c2ebe 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,10 +4,10 @@ Version 1.33.0 (2019-02-28) Language -------- - [You can now use the `cfg(target_vendor)` attribute.][57465] E.g. - `#[cfg(target_vendor="linux")] fn main() { println!("Hello Linux!"); }` + `#[cfg(target_vendor="apple")] fn main() { println!("Hello Apple!"); }` - [Integer patterns such as in a match expression can now be exhaustive.][56362] E.g. You can have match statement on a `u8` that covers `0..=255` and - you would no longer be required to have a `_ => unreachable!()` case. + you would no longer be required to have a `_ => unreachable!()` case. - [You can now have multiple patterns in `if let` and `while let` expressions.][57532] You can do this with the same syntax as a `match` expression. E.g. @@ -51,8 +51,7 @@ Language // Allowed as there is only one `Read` in the module. pub trait Read {} ``` -- [`extern` functions will now abort by default when panicking.][55982] - This was previously undefined behaviour. +- [You may now use `Rc`, `Arc`, and `Pin` as method receivers][56805]. Compiler -------- @@ -109,27 +108,30 @@ Compatibility Notes are now deprecated in the standard library, and their usage will now produce a warning. Please use the `str::{trim_start, trim_end, trim_start_matches, trim_end_matches}` methods instead. +- The `Error::cause` method has been deprecated in favor of `Error::source` which supports + downcasting. -[57615]: https://github.com/rust-lang/rust/pull/57615/ -[57465]: https://github.com/rust-lang/rust/pull/57465/ -[57532]: https://github.com/rust-lang/rust/pull/57532/ -[57535]: https://github.com/rust-lang/rust/pull/57535/ -[57566]: https://github.com/rust-lang/rust/pull/57566/ +[55982]: https://github.com/rust-lang/rust/pull/55982/ +[56303]: https://github.com/rust-lang/rust/pull/56303/ +[56351]: https://github.com/rust-lang/rust/pull/56351/ +[56362]: https://github.com/rust-lang/rust/pull/56362 +[56642]: https://github.com/rust-lang/rust/pull/56642/ +[56769]: https://github.com/rust-lang/rust/pull/56769/ +[56805]: https://github.com/rust-lang/rust/pull/56805 +[56947]: https://github.com/rust-lang/rust/pull/56947/ +[57049]: https://github.com/rust-lang/rust/pull/57049/ +[57067]: https://github.com/rust-lang/rust/pull/57067/ +[57105]: https://github.com/rust-lang/rust/pull/57105 [57130]: https://github.com/rust-lang/rust/pull/57130/ [57167]: https://github.com/rust-lang/rust/pull/57167/ [57175]: https://github.com/rust-lang/rust/pull/57175/ [57234]: https://github.com/rust-lang/rust/pull/57234/ [57332]: https://github.com/rust-lang/rust/pull/57332/ -[56947]: https://github.com/rust-lang/rust/pull/56947/ -[57049]: https://github.com/rust-lang/rust/pull/57049/ -[57067]: https://github.com/rust-lang/rust/pull/57067/ -[56769]: https://github.com/rust-lang/rust/pull/56769/ -[56642]: https://github.com/rust-lang/rust/pull/56642/ -[56303]: https://github.com/rust-lang/rust/pull/56303/ -[56351]: https://github.com/rust-lang/rust/pull/56351/ -[55982]: https://github.com/rust-lang/rust/pull/55982/ -[56362]: https://github.com/rust-lang/rust/pull/56362 -[57105]: https://github.com/rust-lang/rust/pull/57105 +[57465]: https://github.com/rust-lang/rust/pull/57465/ +[57532]: https://github.com/rust-lang/rust/pull/57532/ +[57535]: https://github.com/rust-lang/rust/pull/57535/ +[57566]: https://github.com/rust-lang/rust/pull/57566/ +[57615]: https://github.com/rust-lang/rust/pull/57615/ [cargo/6484]: https://github.com/rust-lang/cargo/pull/6484/ [`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at [`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at @@ -170,7 +172,7 @@ Language - [You can now match against literals in macros with the `literal` specifier.][56072] This will match against a literal of any type. E.g. `1`, `'A'`, `"Hello World"` -- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g. +- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g. ```rust struct Point(i32, i32); @@ -460,7 +462,7 @@ Version 1.31.0 (2018-12-06) Language -------- -- πŸŽ‰ [This version marks the release of the 2018 edition of Rust.][54057] πŸŽ‰ +- πŸŽ‰ [This version marks the release of the 2018 edition of Rust.][54057] πŸŽ‰ - [New lifetime elision rules now allow for eliding lifetimes in functions and impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be `impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined diff --git a/config.toml.example b/config.toml.example index 8f6bf03489f06..0631d7c83eaf7 100644 --- a/config.toml.example +++ b/config.toml.example @@ -61,7 +61,7 @@ # support. You'll need to write a target specification at least, and most # likely, teach rustc about the C ABI of the target. Get in touch with the # Rust team and file an issue if you need assistance in porting! -#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon" +#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;MSP430;Sparc;NVPTX;Hexagon" # LLVM experimental targets to build support for. These targets are specified in # the same format as above, but since these targets are experimental, they are diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index c98d8b8ecf437..8af7aa4856c38 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -262,6 +262,10 @@ def default_build_triple(): cputype = 'arm' if ostype == 'linux-android': ostype = 'linux-androideabi' + elif ostype == 'unknown-freebsd': + cputype = subprocess.check_output( + ['uname', '-p']).strip().decode(default_encoding) + ostype = 'unknown-freebsd' elif cputype == 'armv6l': cputype = 'arm' if ostype == 'linux-android': diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 2dae3f9135d84..2c40dd6d2961d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -904,6 +904,8 @@ impl Step for Src { "src/stdsimd", "src/libproc_macro", "src/tools/rustc-std-workspace-core", + "src/librustc", + "src/libsyntax", ]; copy_src_dirs(builder, &std_src_dirs[..], &[], &dst_src); diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 60aed7ce09d7f..46dfe28da622c 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1286,7 +1286,7 @@ impl> FromIterator> for Option { /// # Examples /// /// Here is an example which increments every integer in a vector. - /// `We use the checked variant of `add` that returns `None` when the + /// We use the checked variant of `add` that returns `None` when the /// calculation would result in an overflow. /// /// ``` diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2fafc57ce4b2d..709e0513202e9 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -379,9 +379,22 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, let body = ir.tcx.hir().body(body_id); for arg in &body.arguments { + let is_shorthand = match arg.pat.node { + crate::hir::PatKind::Struct(..) => true, + _ => false, + }; arg.pat.each_binding(|_bm, hir_id, _x, ident| { debug!("adding argument {:?}", hir_id); - fn_maps.add_variable(Arg(hir_id, ident.name)); + let var = if is_shorthand { + Local(LocalInfo { + id: hir_id, + name: ident.name, + is_shorthand: true, + }) + } else { + Arg(hir_id, ident.name) + }; + fn_maps.add_variable(var); }) }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index a4c587b5ca761..a44d815025e92 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -816,6 +816,8 @@ macro_rules! options { Some("crate=integer"); pub const parse_unpretty: Option<&str> = Some("`string` or `string=string`"); + pub const parse_treat_err_as_bug: Option<&str> = + Some("either no value or a number bigger than 0"); pub const parse_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \ `fat`, or omitted"); @@ -1022,6 +1024,13 @@ macro_rules! options { } } + fn parse_treat_err_as_bug(slot: &mut Option, v: Option<&str>) -> bool { + match v { + Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 } + None => { *slot = Some(1); true } + } + } + fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool { if v.is_some() { let mut bool_arg = None; @@ -1236,8 +1245,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "load proc macros for both target and host, but only link to the target"), no_codegen: bool = (false, parse_bool, [TRACKED], "run all passes except codegen; no output"), - treat_err_as_bug: bool = (false, parse_bool, [TRACKED], - "treat all errors that occur as bugs"), + treat_err_as_bug: Option = (None, parse_treat_err_as_bug, [TRACKED], + "treat error number `val` that occurs as bug"), report_delayed_bugs: bool = (false, parse_bool, [TRACKED], "immediately print bugs registered with `delay_span_bug`"), external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], @@ -3214,7 +3223,7 @@ mod tests { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.treat_err_as_bug = true; + opts.debugging_opts.treat_err_as_bug = Some(1); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 774bc8b450b59..751fa7e95e3a8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1315,7 +1315,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { Box::new(EmitterWriter::stderr(color_config, None, true, false)) } }; - let handler = errors::Handler::with_emitter(true, false, emitter); + let handler = errors::Handler::with_emitter(true, None, emitter); handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal); errors::FatalError.raise(); } @@ -1330,7 +1330,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) { Box::new(EmitterWriter::stderr(color_config, None, true, false)) } }; - let handler = errors::Handler::with_emitter(true, false, emitter); + let handler = errors::Handler::with_emitter(true, None, emitter); handler.emit(&MultiSpan::new(), msg, errors::Level::Warning); } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 448b0f26d5616..c7674ae7a28a2 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -599,11 +599,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - pub fn report_selection_error(&self, - obligation: &PredicateObligation<'tcx>, - error: &SelectionError<'tcx>, - fallback_has_occurred: bool) - { + pub fn report_selection_error( + &self, + obligation: &PredicateObligation<'tcx>, + error: &SelectionError<'tcx>, + fallback_has_occurred: bool, + ) { let span = obligation.cause.span; let mut err = match *error { @@ -673,6 +674,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); self.suggest_remove_reference(&obligation, &mut err, &trait_ref); + self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); // Try to report a help message if !trait_ref.has_infer_types() && @@ -900,9 +902,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a /// suggestion to borrow the initializer in order to use have a slice instead. - fn suggest_borrow_on_unsized_slice(&self, - code: &ObligationCauseCode<'tcx>, - err: &mut DiagnosticBuilder<'tcx>) { + fn suggest_borrow_on_unsized_slice( + &self, + code: &ObligationCauseCode<'tcx>, + err: &mut DiagnosticBuilder<'tcx>, + ) { if let &ObligationCauseCode::VariableType(node_id) = code { let parent_node = self.tcx.hir().get_parent_node(node_id); if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) { @@ -924,10 +928,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`, /// suggest removing these references until we reach a type that implements the trait. - fn suggest_remove_reference(&self, - obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'tcx>, - trait_ref: &ty::Binder>) { + fn suggest_remove_reference( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut DiagnosticBuilder<'tcx>, + trait_ref: &ty::Binder>, + ) { let trait_ref = trait_ref.skip_binder(); let span = obligation.cause.span; @@ -969,6 +975,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + fn suggest_semicolon_removal( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut DiagnosticBuilder<'tcx>, + span: Span, + trait_ref: &ty::Binder>, + ) { + let hir = self.tcx.hir(); + let parent_node = hir.get_parent_node( + hir.hir_to_node_id(obligation.cause.body_id), + ); + let node = hir.find(parent_node); + if let Some(hir::Node::Item(hir::Item { + node: hir::ItemKind::Fn(decl, _, _, body_id), + .. + })) = node { + let body = hir.body(*body_id); + if let hir::ExprKind::Block(blk, _) = &body.value.node { + if decl.output.span().overlaps(span) && blk.expr.is_none() && + "()" == &trait_ref.self_ty().to_string() + { + // FIXME(estebank): When encountering a method with a trait + // bound not satisfied in the return type with a body that has + // no return, suggest removal of semicolon on last statement. + // Once that is added, close #54771. + if let Some(ref stmt) = blk.stmts.last() { + let sp = self.tcx.sess.source_map().end_point(stmt.span); + err.span_label(sp, "consider removing this semicolon"); + } + } + } + } + } + /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the /// arguments it expects. This can be supplied to diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 5b8c7461bcb60..258391ba8360f 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -123,9 +123,9 @@ impl ExtraBackendMethods for LlvmCodegenBackend { ) -> EncodedMetadata { base::write_metadata(tcx, metadata) } - fn codegen_allocator( + fn codegen_allocator<'b, 'gcx>( &self, - tcx: TyCtxt<'_, '_, '_>, + tcx: TyCtxt<'b, 'gcx, 'gcx>, mods: &mut ModuleLlvm, kind: AllocatorKind ) { diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 4bccc2a6d1f7b..c84b38cde8185 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -247,7 +247,7 @@ pub struct CodegenContext { impl CodegenContext { pub fn create_diag_handler(&self) -> Handler { - Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone())) + Handler::with_emitter(true, None, Box::new(self.diag_emitter.clone())) } pub fn config(&self, kind: ModuleKind) -> &ModuleConfig { diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index c1b7502cd8fb2..bc77097425bd1 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -673,6 +673,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( .zip(state_tys) .enumerate() .filter_map(move |(i, (decl, ty))| { + let ty = fx.monomorphize(&ty); decl.name.map(|name| (i + upvar_count + 1, name, false, ty)) }) }).into_iter().flatten(); diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 00eae9098e74f..a9e0eadb198a8 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -38,9 +38,9 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se tcx: TyCtxt<'b, 'gcx, 'gcx>, metadata: &mut Self::Module, ) -> EncodedMetadata; - fn codegen_allocator( + fn codegen_allocator<'b, 'gcx>( &self, - tcx: TyCtxt<'_, '_, '_>, + tcx: TyCtxt<'b, 'gcx, 'gcx>, mods: &mut Self::Module, kind: AllocatorKind ); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cc1b8916c1074..656d8e463dbd0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -148,7 +148,7 @@ pub fn run(run_compiler: F) -> isize true, false ); - let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); + let handler = errors::Handler::with_emitter(true, None, Box::new(emitter)); handler.emit(&MultiSpan::new(), "aborting due to previous error(s)", errors::Level::Fatal); @@ -1327,7 +1327,7 @@ pub fn monitor(f: F) -> Result<(), CompilationFail None, false, false)); - let handler = errors::Handler::with_emitter(true, false, emitter); + let handler = errors::Handler::with_emitter(true, None, emitter); // a .span_bug or .bug call has already printed what // it wants to print. diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 65f8ce75bd113..3d52f1d44ba29 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -113,7 +113,7 @@ fn test_env_with_pool( ) where F: FnOnce(Env), { - let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter); + let diagnostic_handler = errors::Handler::with_emitter(true, None, emitter); let sess = session::build_session_( options, None, diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 0c808a07f9bac..c8d47339fb365 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -103,7 +103,9 @@ impl<'a> DiagnosticBuilder<'a> { /// Buffers the diagnostic for later emission, unless handler /// has disabled such buffering. pub fn buffer(mut self, buffered_diagnostics: &mut Vec) { - if self.handler.flags.dont_buffer_diagnostics || self.handler.flags.treat_err_as_bug { + if self.handler.flags.dont_buffer_diagnostics || + self.handler.flags.treat_err_as_bug.is_some() + { self.emit(); return; } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 87b4751526835..7c7698ddd3d73 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -330,7 +330,7 @@ pub struct HandlerFlags { pub can_emit_warnings: bool, /// If true, error-level diagnostics are upgraded to bug-level. /// (rustc: see `-Z treat-err-as-bug`) - pub treat_err_as_bug: bool, + pub treat_err_as_bug: Option, /// If true, immediately emit diagnostics that would otherwise be buffered. /// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`) pub dont_buffer_diagnostics: bool, @@ -360,7 +360,7 @@ impl Drop for Handler { impl Handler { pub fn with_tty_emitter(color_config: ColorConfig, can_emit_warnings: bool, - treat_err_as_bug: bool, + treat_err_as_bug: Option, cm: Option>) -> Handler { Handler::with_tty_emitter_and_flags( @@ -382,7 +382,7 @@ impl Handler { } pub fn with_emitter(can_emit_warnings: bool, - treat_err_as_bug: bool, + treat_err_as_bug: Option, e: Box) -> Handler { Handler::with_emitter_and_flags( @@ -516,8 +516,20 @@ impl Handler { } fn panic_if_treat_err_as_bug(&self) { - if self.flags.treat_err_as_bug { - panic!("encountered error with `-Z treat_err_as_bug"); + if self.treat_err_as_bug() { + let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) { + (0, _) => return, + (1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(), + (1, _) => return, + (count, as_bug) => { + format!( + "aborting after {} errors due to `-Z treat-err-as-bug={}`", + count, + as_bug, + ) + } + }; + panic!(s); } } @@ -558,7 +570,7 @@ impl Handler { panic!(ExplicitBug); } pub fn delay_span_bug>(&self, sp: S, msg: &str) { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { // FIXME: don't abort here if report_delayed_bugs is off self.span_bug(sp, msg); } @@ -593,14 +605,14 @@ impl Handler { DiagnosticBuilder::new(self, FailureNote, msg).emit() } pub fn fatal(&self, msg: &str) -> FatalError { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { self.bug(msg); } DiagnosticBuilder::new(self, Fatal, msg).emit(); FatalError } pub fn err(&self, msg: &str) { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { self.bug(msg); } let mut db = DiagnosticBuilder::new(self, Error, msg); @@ -610,6 +622,9 @@ impl Handler { let mut db = DiagnosticBuilder::new(self, Warning, msg); db.emit(); } + fn treat_err_as_bug(&self) -> bool { + self.flags.treat_err_as_bug.map(|c| self.err_count() >= c).unwrap_or(false) + } pub fn note_without_error(&self, msg: &str) { let mut db = DiagnosticBuilder::new(self, Note, msg); db.emit(); @@ -624,8 +639,8 @@ impl Handler { } fn bump_err_count(&self) { - self.panic_if_treat_err_as_bug(); self.err_count.fetch_add(1, SeqCst); + self.panic_if_treat_err_as_bug(); } pub fn err_count(&self) -> usize { @@ -642,6 +657,9 @@ impl Handler { 1 => "aborting due to previous error".to_string(), _ => format!("aborting due to {} previous errors", self.err_count()) }; + if self.treat_err_as_bug() { + return; + } let _ = self.fatal(&s); diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs new file mode 100644 index 0000000000000..39886a16a7403 --- /dev/null +++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + let base = super::freebsd_base::opts(); + Ok(Target { + llvm_target: "armv6-unknown-freebsd-gnueabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "freebsd".to_string(), + target_env: "gnueabihf".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + features: "+v6,+vfp2".to_string(), + max_atomic_width: Some(64), + abi_blacklist: super::arm_base::abi_blacklist(), + .. base + } + }) +} diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/src/librustc_target/spec/armv7_unknown_freebsd.rs new file mode 100644 index 0000000000000..ba63fd2bf053f --- /dev/null +++ b/src/librustc_target/spec/armv7_unknown_freebsd.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + let base = super::freebsd_base::opts(); + Ok(Target { + llvm_target: "armv7-unknown-freebsd-gnueabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "freebsd".to_string(), + target_env: "gnueabihf".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + max_atomic_width: Some(64), + abi_blacklist: super::arm_base::abi_blacklist(), + .. base + } + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index bef2afc7b6292..2824d9cb6c3bb 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -376,6 +376,8 @@ supported_targets! { ("aarch64-linux-android", aarch64_linux_android), ("aarch64-unknown-freebsd", aarch64_unknown_freebsd), + ("armv6-unknown-freebsd", armv6_unknown_freebsd), + ("armv7-unknown-freebsd", armv7_unknown_freebsd), ("i686-unknown-freebsd", i686_unknown_freebsd), ("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd), ("x86_64-unknown-freebsd", x86_64_unknown_freebsd), diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index f736e7ac29d08..32ca854b27744 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -367,6 +367,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Maybe remove `&`? hir::ExprKind::AddrOf(_, ref expr) => { if !cm.span_to_filename(expr.span).is_real() { + if let Ok(code) = cm.span_to_snippet(sp) { + if code.chars().next() == Some('&') { + return Some(( + sp, + "consider removing the borrow", + code[1..].to_string()), + ); + } + } return None; } if let Ok(code) = cm.span_to_snippet(expr.span) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index c7bab8d170904..81fc38e743f44 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -251,11 +251,14 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let needs_drop_copy = || { packed && { let ty = variant.fields.last().unwrap().ty; - let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx) + fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx) + .map(|ty| ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))) .unwrap_or_else(|| { - span_bug!(item.span, "inference variables in {:?}", ty) - }); - ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)) + fcx_tcx.sess.delay_span_bug( + item.span, &format!("inference variables in {:?}", ty)); + // Just treat unresolved type expression as if it needs drop. + true + }) } }; let all_sized = @@ -881,7 +884,9 @@ fn receiver_is_valid<'fcx, 'tcx, 'gcx>( } else { debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty); - return false + // If he receiver already has errors reported due to it, consider it valid to avoid + // unecessary errors (#58712). + return receiver_ty.references_error(); } // without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8fe116bd9c873..205e424991076 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -277,7 +277,7 @@ impl DocAccessLevels for AccessLevels { /// will be created for the handler. pub fn new_handler(error_format: ErrorOutputType, source_map: Option>, - treat_err_as_bug: bool, + treat_err_as_bug: Option, ui_testing: bool, ) -> errors::Handler { // rustdoc doesn't override (or allow to override) anything from this that is relevant here, so diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index c3c0875bc7d24..856365847ae17 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -67,7 +67,7 @@ pub fn run(mut options: Options) -> isize { let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping())); let handler = errors::Handler::with_tty_emitter(ColorConfig::Auto, - true, false, + true, None, Some(source_map.clone())); let mut sess = session::build_session_( @@ -272,7 +272,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, false); // Compile the code - let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); + let diagnostic_handler = errors::Handler::with_emitter(true, None, box emitter); let mut sess = session::build_session_( sessopts, None, diagnostic_handler, source_map, Default::default(), @@ -424,7 +424,7 @@ pub fn make_test(s: &str, // send all the errors that libsyntax emits directly into a `Sink` instead of stderr. let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let emitter = EmitterWriter::new(box io::sink(), None, false, false); - let handler = Handler::with_emitter(false, false, box emitter); + let handler = Handler::with_emitter(false, None, box emitter); let sess = ParseSess::with_span_handler(handler, cm); let mut found_main = false; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index a51847c92b51e..928de29b297fc 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2341,6 +2341,11 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { elem: FullBucket>, } +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, K: 'a + Send, V: 'a + Send> Send for OccupiedEntry<'a, K, V> {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, K: 'a + Sync, V: 'a + Sync> Sync for OccupiedEntry<'a, K, V> {} + #[stable(feature= "debug_hash_map", since = "1.12.0")] impl Debug for OccupiedEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -2362,6 +2367,11 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> { elem: VacantEntryState>, } +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, K: 'a + Send, V: 'a + Send> Send for VacantEntry<'a, K, V> {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, K: 'a + Sync, V: 'a + Sync> Sync for VacantEntry<'a, K, V> {} + #[stable(feature= "debug_hash_map", since = "1.12.0")] impl Debug for VacantEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index fdc5625ff1841..614b79124cc68 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -556,6 +556,14 @@ impl error::Error for Error { Repr::Custom(ref c) => c.error.cause(), } } + + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self.repr { + Repr::Os(..) => None, + Repr::Simple(..) => None, + Repr::Custom(ref c) => c.error.source(), + } + } } fn _assert_error_is_sync_send() { diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 3a876e05eccbd..7ad6b124e3a38 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -40,13 +40,16 @@ use crate::mem; /// }); /// /// // each thread starts out with the initial value of 1 -/// thread::spawn(move|| { +/// let t = thread::spawn(move|| { /// FOO.with(|f| { /// assert_eq!(*f.borrow(), 1); /// *f.borrow_mut() = 3; /// }); /// }); /// +/// // wait for the thread to complete and bail out on panic +/// t.join().unwrap(); +/// /// // we retain our original value of 2 despite the child thread /// FOO.with(|f| { /// assert_eq!(*f.borrow(), 2); diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index e7937f57002f3..e93e15f9012a7 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -285,8 +285,8 @@ impl<'a> Parser<'a> { } let found = self.this_token_to_string(); - let msg = format!("expected unsuffixed literal or identifier, found {}", found); - Err(self.diagnostic().struct_span_err(lo, &msg)) + let msg = format!("expected unsuffixed literal or identifier, found `{}`", found); + Err(self.diagnostic().struct_span_err(self.span, &msg)) } /// matches meta_seq = ( COMMASEP(meta_item_inner) ) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index a7cde5fbb92cd..db5b8dcda4eab 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1920,7 +1920,7 @@ mod tests { false, false); ParseSess { - span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)), + span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)), unstable_features: UnstableFeatures::from_environment(), config: CrateConfig::default(), included_mod_stack: Lock::new(Vec::new()), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6583458b44694..98b5fe563b8a9 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -54,7 +54,7 @@ impl ParseSess { let cm = Lrc::new(SourceMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, - false, + None, Some(cm.clone())); ParseSess::with_span_handler(handler, cm) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7e63da2704996..fe31311094b89 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1818,7 +1818,7 @@ impl<'a> Parser<'a> { let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; if parse_plus { self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded - bounds.append(&mut self.parse_generic_bounds(None)?); + bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?); } Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } @@ -5538,6 +5538,7 @@ impl<'a> Parser<'a> { let mut bounds = Vec::new(); let mut negative_bounds = Vec::new(); let mut last_plus_span = None; + let mut was_negative = false; loop { // This needs to be synchronized with `Token::can_begin_bound`. let is_bound_start = self.check_path() || self.check_lifetime() || @@ -5582,9 +5583,10 @@ impl<'a> Parser<'a> { } let poly_span = lo.to(self.prev_span); if is_negative { - negative_bounds.push( - last_plus_span.or(colon_span).unwrap() - .to(poly_span)); + was_negative = true; + if let Some(sp) = last_plus_span.or(colon_span) { + negative_bounds.push(sp.to(poly_span)); + } } else { let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span); let modifier = if question.is_some() { @@ -5606,26 +5608,28 @@ impl<'a> Parser<'a> { } } - if !negative_bounds.is_empty() { + if !negative_bounds.is_empty() || was_negative { let plural = negative_bounds.len() > 1; let mut err = self.struct_span_err(negative_bounds, "negative trait bounds are not supported"); - let bound_list = colon_span.unwrap().to(self.prev_span); - let mut new_bound_list = String::new(); - if !bounds.is_empty() { - let mut snippets = bounds.iter().map(|bound| bound.span()) - .map(|span| self.sess.source_map().span_to_snippet(span)); - while let Some(Ok(snippet)) = snippets.next() { - new_bound_list.push_str(" + "); - new_bound_list.push_str(&snippet); - } - new_bound_list = new_bound_list.replacen(" +", ":", 1); - } - err.span_suggestion_short(bound_list, - &format!("remove the trait bound{}", - if plural { "s" } else { "" }), - new_bound_list, - Applicability::MachineApplicable); + if let Some(bound_list) = colon_span { + let bound_list = bound_list.to(self.prev_span); + let mut new_bound_list = String::new(); + if !bounds.is_empty() { + let mut snippets = bounds.iter().map(|bound| bound.span()) + .map(|span| self.sess.source_map().span_to_snippet(span)); + while let Some(Ok(snippet)) = snippets.next() { + new_bound_list.push_str(" + "); + new_bound_list.push_str(&snippet); + } + new_bound_list = new_bound_list.replacen(" +", ":", 1); + } + err.span_suggestion_short(bound_list, + &format!("remove the trait bound{}", + if plural { "s" } else { "" }), + new_bound_list, + Applicability::MachineApplicable); + } err.emit(); } @@ -5661,7 +5665,7 @@ impl<'a> Parser<'a> { // Parse optional colon and param bounds. let bounds = if self.eat(&token::Colon) { - self.parse_generic_bounds(None)? + self.parse_generic_bounds(Some(self.prev_span))? } else { Vec::new() }; @@ -6106,7 +6110,7 @@ impl<'a> Parser<'a> { // or with mandatory equality sign and the second type. let ty = self.parse_ty()?; if self.eat(&token::Colon) { - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds(Some(self.prev_span))?; where_clause.predicates.push(ast::WherePredicate::BoundPredicate( ast::WhereBoundPredicate { span: lo.to(self.prev_span), @@ -7665,7 +7669,7 @@ impl<'a> Parser<'a> { tps.where_clause = self.parse_where_clause()?; let alias = if existential { self.expect(&token::Colon)?; - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds(Some(self.prev_span))?; AliasKind::Existential(bounds) } else { self.expect(&token::Eq)?; diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index cf39090e1888b..2b3d18835d543 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -58,7 +58,7 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & Some(source_map.clone()), false, false); - let handler = Handler::with_emitter(true, false, Box::new(emitter)); + let handler = Handler::with_emitter(true, None, Box::new(emitter)); handler.span_err(msp, "foo"); assert!(expected_output.chars().next() == Some('\n'), diff --git a/src/test/incremental/cyclic-trait-hierarchy.rs b/src/test/incremental/cyclic-trait-hierarchy.rs new file mode 100644 index 0000000000000..4102eb32580f0 --- /dev/null +++ b/src/test/incremental/cyclic-trait-hierarchy.rs @@ -0,0 +1,14 @@ +// Adapated from rust-lang/rust#58813 + +// revisions: rpass1 cfail2 + +#[cfg(rpass1)] +pub trait T2 { } +#[cfg(cfail2)] +pub trait T2: T1 { } +//[cfail2]~^ ERROR cycle detected when computing the supertraits of `T2` +//[cfail2]~| ERROR cycle detected when computing the supertraits of `T2` + +pub trait T1: T2 { } + +fn main() { } diff --git a/src/test/run-make-fulldeps/treat-err-as-bug/Makefile b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile index f99e4611174ca..9b3bcef2faf32 100644 --- a/src/test/run-make-fulldeps/treat-err-as-bug/Makefile +++ b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile @@ -2,4 +2,4 @@ all: $(RUSTC) err.rs -Z treat-err-as-bug 2>&1 \ - | $(CGREP) "panicked at 'encountered error with \`-Z treat_err_as_bug'" + | $(CGREP) "panicked at 'aborting due to \`-Z treat-err-as-bug=1\`'" diff --git a/src/test/run-pass/generator/issue-57084.rs b/src/test/run-pass/generator/issue-57084.rs new file mode 100644 index 0000000000000..8aaa6a0e427d1 --- /dev/null +++ b/src/test/run-pass/generator/issue-57084.rs @@ -0,0 +1,28 @@ +// This issue reproduces an ICE on compile (E.g. fails on 2018-12-19 nightly). +// "cannot relate bound region: ReLateBound(DebruijnIndex(1), BrAnon(1)) <= '_#1r" +// run-pass +// edition:2018 +#![feature(generators,generator_trait)] +use std::ops::Generator; + +fn with(f: F) -> impl Generator +where F: Fn() -> () +{ + move || { + loop { + match f() { + _ => yield, + } + } + } +} + +fn main() { + let data = &vec![1]; + || { + let _to_pin = with(move || println!("{:p}", data)); + loop { + yield + } + }; +} diff --git a/src/test/run-pass/generator/issue-58888.rs b/src/test/run-pass/generator/issue-58888.rs new file mode 100644 index 0000000000000..43b37a9afc2cc --- /dev/null +++ b/src/test/run-pass/generator/issue-58888.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: -g + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +struct Database; + +impl Database { + fn get_connection(&self) -> impl Iterator { + Some(()).into_iter() + } + + fn check_connection(&self) -> impl Generator + '_ { + move || { + let iter = self.get_connection(); + for i in iter { + yield i + } + } + } +} + +fn main() { + Database.check_connection(); +} diff --git a/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs b/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs new file mode 100644 index 0000000000000..94e2b2563df59 --- /dev/null +++ b/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs @@ -0,0 +1,17 @@ +// The const-evaluator was at one point ICE'ing while trying to +// evaluate the body of `fn id` during the `s.id()` call in main. + +struct S(T); + +impl S { + const ID: fn(&S) -> &S = |s| s; + pub fn id(&self) -> &Self { + Self::ID(self) // This, plus call below ... + } +} + +fn main() { + let s = S(10u32); + assert!(S::::ID(&s).0 == 10); // Works fine + assert!(s.id().0 == 10); // ... causes compiler to panic +} diff --git a/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs b/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs index 812cf89751efd..fd53bb607f79d 100644 --- a/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs +++ b/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs @@ -53,6 +53,7 @@ fn main() { is_sync_send!(BTreeSet::::new(), union(&BTreeSet::::new())); all_sync_send!(HashMap::::new(), iter, iter_mut, drain, into_iter, keys, values); + is_sync_send!(HashMap::::new(), entry(0)); all_sync_send!(HashSet::::new(), iter, drain, into_iter); is_sync_send!(HashSet::::new(), difference(&HashSet::::new())); is_sync_send!(HashSet::::new(), symmetric_difference(&HashSet::::new())); diff --git a/src/test/ui/block-result/issue-5500.stderr b/src/test/ui/block-result/issue-5500.stderr index 0d9c9d8143d31..6a13b31fe932f 100644 --- a/src/test/ui/block-result/issue-5500.stderr +++ b/src/test/ui/block-result/issue-5500.stderr @@ -4,7 +4,10 @@ error[E0308]: mismatched types LL | fn main() { | - expected `()` because of default return type LL | &panic!() - | ^^^^^^^^^ expected (), found reference + | ^^^^^^^^^ + | | + | expected (), found reference + | help: consider removing the borrow: `panic!()` | = note: expected type `()` found type `&_` diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs index c5aa903f9491f..7f0648b381dbd 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs @@ -28,7 +28,7 @@ struct S9; macro_rules! generate_s10 { ($expr: expr) => { #[cfg(feature = $expr)] - //~^ ERROR expected unsuffixed literal or identifier, found concat!("nonexistent") + //~^ ERROR expected unsuffixed literal or identifier, found `concat!("nonexistent")` struct S10; } } diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index bcf13ead2f4f7..7dab2b2b53f91 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -52,11 +52,11 @@ error[E0565]: literal in `cfg` predicate value must be a string LL | #[cfg(a = b"hi")] //~ ERROR literal in `cfg` predicate value must be a string | ^^^^^ help: consider removing the prefix: `"hi"` -error: expected unsuffixed literal or identifier, found concat!("nonexistent") - --> $DIR/cfg-attr-syntax-validation.rs:30:15 +error: expected unsuffixed literal or identifier, found `concat!("nonexistent")` + --> $DIR/cfg-attr-syntax-validation.rs:30:25 | LL | #[cfg(feature = $expr)] - | ^^^^^^^ + | ^^^^^ ... LL | generate_s10!(concat!("nonexistent")); | -------------------------------------- in this macro invocation diff --git a/src/test/ui/const-generics/invalid-constant-in-args.rs b/src/test/ui/const-generics/invalid-constant-in-args.rs new file mode 100644 index 0000000000000..40df237ee72ed --- /dev/null +++ b/src/test/ui/const-generics/invalid-constant-in-args.rs @@ -0,0 +1,3 @@ +fn main() { + let _: Vec<&str, "a"> = Vec::new(); //~ ERROR wrong number of const arguments +} diff --git a/src/test/ui/const-generics/invalid-constant-in-args.stderr b/src/test/ui/const-generics/invalid-constant-in-args.stderr new file mode 100644 index 0000000000000..1623f645124ab --- /dev/null +++ b/src/test/ui/const-generics/invalid-constant-in-args.stderr @@ -0,0 +1,9 @@ +error[E0107]: wrong number of const arguments: expected 0, found 1 + --> $DIR/invalid-constant-in-args.rs:2:22 + | +LL | let _: Vec<&str, "a"> = Vec::new(); //~ ERROR wrong number of const arguments + | ^^^ unexpected const argument + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index c399650d3258b..3457549a75239 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -1,13 +1,19 @@ error[E0308]: mismatched types --> $DIR/diverging-tuple-parts-39485.rs:8:5 | -LL | fn g() { - | - help: try adding a return type: `-> &_` LL | &panic!() //~ ERROR mismatched types | ^^^^^^^^^ expected (), found reference | = note: expected type `()` found type `&_` +help: try adding a return type + | +LL | fn g() -> &_ { + | ^^^^^ +help: consider removing the borrow + | +LL | panic!() //~ ERROR mismatched types + | ^^^^^^^^ error[E0308]: mismatched types --> $DIR/diverging-tuple-parts-39485.rs:12:5 diff --git a/src/test/ui/issues/issue-50582.rs b/src/test/ui/issues/issue-50582.rs new file mode 100644 index 0000000000000..1358e0bde4c82 --- /dev/null +++ b/src/test/ui/issues/issue-50582.rs @@ -0,0 +1,4 @@ +fn main() { + Vec::<[(); 1 + for x in 0..1 {}]>::new(); + //~^ ERROR cannot add +} diff --git a/src/test/ui/issues/issue-50582.stderr b/src/test/ui/issues/issue-50582.stderr new file mode 100644 index 0000000000000..226f5a3f0fed2 --- /dev/null +++ b/src/test/ui/issues/issue-50582.stderr @@ -0,0 +1,11 @@ +error[E0277]: cannot add `()` to `{integer}` + --> $DIR/issue-50582.rs:2:18 + | +LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); + | ^ no implementation for `{integer} + ()` + | + = help: the trait `std::ops::Add<()>` is not implemented for `{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-58712.rs b/src/test/ui/issues/issue-58712.rs new file mode 100644 index 0000000000000..577709cf2919d --- /dev/null +++ b/src/test/ui/issues/issue-58712.rs @@ -0,0 +1,15 @@ +struct AddrVec { + h: H, + a: A, +} + +impl AddrVec { + //~^ ERROR cannot find type `DeviceId` in this scope + pub fn device(&self) -> DeviceId { + //~^ ERROR cannot find type `DeviceId` in this scope + self.tail() + } +} + +fn main() {} + diff --git a/src/test/ui/issues/issue-58712.stderr b/src/test/ui/issues/issue-58712.stderr new file mode 100644 index 0000000000000..6164ad7ee19b2 --- /dev/null +++ b/src/test/ui/issues/issue-58712.stderr @@ -0,0 +1,15 @@ +error[E0412]: cannot find type `DeviceId` in this scope + --> $DIR/issue-58712.rs:6:20 + | +LL | impl AddrVec { + | ^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `DeviceId` in this scope + --> $DIR/issue-58712.rs:8:29 + | +LL | pub fn device(&self) -> DeviceId { + | ^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/issues/issue-58857.rs b/src/test/ui/issues/issue-58857.rs new file mode 100644 index 0000000000000..392e4ea0c2ecc --- /dev/null +++ b/src/test/ui/issues/issue-58857.rs @@ -0,0 +1,7 @@ +struct Conj {a : A} +trait Valid {} + +impl Conj{} +//~^ ERROR negative trait bounds are not supported + +fn main() {} diff --git a/src/test/ui/issues/issue-58857.stderr b/src/test/ui/issues/issue-58857.stderr new file mode 100644 index 0000000000000..040e9eb8a6567 --- /dev/null +++ b/src/test/ui/issues/issue-58857.stderr @@ -0,0 +1,8 @@ +error: negative trait bounds are not supported + --> $DIR/issue-58857.rs:4:7 + | +LL | impl Conj{} + | ^^^^^^^^ help: remove the trait bound + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/format-borrow.rs b/src/test/ui/suggestions/format-borrow.rs new file mode 100644 index 0000000000000..63930e7f787fd --- /dev/null +++ b/src/test/ui/suggestions/format-borrow.rs @@ -0,0 +1,6 @@ +fn main() { + let a: String = &String::from("a"); + //~^ ERROR mismatched types + let b: String = &format!("b"); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/format-borrow.stderr b/src/test/ui/suggestions/format-borrow.stderr new file mode 100644 index 0000000000000..44bb11faa7f38 --- /dev/null +++ b/src/test/ui/suggestions/format-borrow.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/format-borrow.rs:2:21 + | +LL | let a: String = &String::from("a"); + | ^^^^^^^^^^^^^^^^^^ + | | + | expected struct `std::string::String`, found reference + | help: consider removing the borrow: `String::from("a")` + | + = note: expected type `std::string::String` + found type `&std::string::String` + +error[E0308]: mismatched types + --> $DIR/format-borrow.rs:4:21 + | +LL | let b: String = &format!("b"); + | ^^^^^^^^^^^^^ + | | + | expected struct `std::string::String`, found reference + | help: consider removing the borrow: `format!("b")` + | + = note: expected type `std::string::String` + found type `&std::string::String` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs new file mode 100644 index 0000000000000..e72a2d8ccc629 --- /dev/null +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs @@ -0,0 +1,7 @@ +trait Bar {} +impl Bar for u8 {} +fn foo() -> impl Bar { + 5; //~^ ERROR the trait bound `(): Bar` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr new file mode 100644 index 0000000000000..f26fb141ccf80 --- /dev/null +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `(): Bar` is not satisfied + --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13 + | +LL | fn foo() -> impl Bar { + | ^^^^^^^^ the trait `Bar` is not implemented for `()` +LL | 5; //~^ ERROR the trait bound `(): Bar` is not satisfied + | - consider removing this semicolon + | + = note: the return type of a function must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/unused-closure-argument.rs b/src/test/ui/suggestions/unused-closure-argument.rs new file mode 100644 index 0000000000000..677003ebf225c --- /dev/null +++ b/src/test/ui/suggestions/unused-closure-argument.rs @@ -0,0 +1,20 @@ +#![deny(unused_variables)] + +struct Point { + x: i32, + y: i32, +} + +fn main() { + let points = vec!(Point { x: 1, y: 2 }, Point { x: 3, y: 4 }); + + let _: i32 = points.iter() + .map(|Point { x, y }| y) + //~^ ERROR unused variable + .sum(); + + let _: i32 = points.iter() + .map(|x| 4) + //~^ ERROR unused variable + .sum(); +} diff --git a/src/test/ui/suggestions/unused-closure-argument.stderr b/src/test/ui/suggestions/unused-closure-argument.stderr new file mode 100644 index 0000000000000..5cfdd79659b27 --- /dev/null +++ b/src/test/ui/suggestions/unused-closure-argument.stderr @@ -0,0 +1,20 @@ +error: unused variable: `x` + --> $DIR/unused-closure-argument.rs:12:23 + | +LL | .map(|Point { x, y }| y) + | ^ help: try ignoring the field: `x: _` + | +note: lint level defined here + --> $DIR/unused-closure-argument.rs:1:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +error: unused variable: `x` + --> $DIR/unused-closure-argument.rs:17:15 + | +LL | .map(|x| 4) + | ^ help: consider prefixing with an underscore: `_x` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs new file mode 100644 index 0000000000000..d0167c8c268cf --- /dev/null +++ b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs @@ -0,0 +1,31 @@ +// rust-lang/rust#58158: We have special-case code to deal with case +// when a type is both packed and needs drop glue, (we move the fields +// out of their potentially unaligned locations before dropping them, +// which requires they be Sized; see PR #44884). +// +// So, we need to check if a given type needs drop-glue. That requires +// that we actually know that the concrete type, and we guard against +// the type having unknown parts (i.e. type variables) by ICE'ing in +// that scenario. +// +// But in a case where we have a projection (`Type as Trait::Assoc`) +// where `Type` does not actually implement `Trait`, we of course +// cannot have a concrete type, because there is no impl to look up +// the concrete type for the associated type `Assoc`. +// +// So, this test is just making sure that in such a case that we do +// not immediately ICE, and instead allow the underlying type error to +// surface. + +pub struct Matrix(S); +pub struct DefaultAllocator; + +pub trait Allocator { type Buffer; } + +// impl Allocator for DefaultAllocator { type Buffer = (); } + +#[repr(packed)] +struct Foo(Matrix<::Buffer>); +//~^ ERROR the trait bound `DefaultAllocator: Allocator` is not satisfied + +fn main() { } diff --git a/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr new file mode 100644 index 0000000000000..e460cdcd3f3e5 --- /dev/null +++ b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `DefaultAllocator: Allocator` is not satisfied + --> $DIR/wf-packed-on-proj-of-type-as-unimpl-trait.rs:28:12 + | +LL | struct Foo(Matrix<::Buffer>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `DefaultAllocator` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.