From 4e76c3820fea97e06f08555d4eeee3de3be4eb5a Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Tue, 27 Jul 2021 23:40:32 +0200 Subject: [PATCH 01/20] Fix ICE in `improper_ctypes_definitions` lint with all-ZST transparent types --- compiler/rustc_lint/src/types.rs | 10 ++++++++-- src/test/ui/repr/repr-transparent-issue-87496.rs | 12 ++++++++++++ .../ui/repr/repr-transparent-issue-87496.stderr | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/repr/repr-transparent-issue-87496.rs create mode 100644 src/test/ui/repr/repr-transparent-issue-87496.stderr diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a3a87a48768dc..639fe5ca2a46a 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -851,12 +851,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { use FfiResult::*; if def.repr.transparent() { - // Can assume that only one field is not a ZST, so only check + // Can assume that at most one field is not a ZST, so only check // that field's type for FFI-safety. if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { self.check_field_type_for_ffi(cache, field, substs) } else { - bug!("malformed transparent type"); + // All fields are ZSTs; this means that the type should behave + // like (), which is FFI-unsafe + FfiUnsafe { + ty, + reason: "this struct contains only zero-sized fields".into(), + help: None, + } } } else { // We can't completely trust repr(C) markings; make sure the fields are diff --git a/src/test/ui/repr/repr-transparent-issue-87496.rs b/src/test/ui/repr/repr-transparent-issue-87496.rs new file mode 100644 index 0000000000000..a4dd45c63f564 --- /dev/null +++ b/src/test/ui/repr/repr-transparent-issue-87496.rs @@ -0,0 +1,12 @@ +// Regression test for the ICE described in #87496. + +// check-pass + +#[repr(transparent)] +struct TransparentCustomZst(()); +extern "C" { + fn good17(p: TransparentCustomZst); + //~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe +} + +fn main() {} diff --git a/src/test/ui/repr/repr-transparent-issue-87496.stderr b/src/test/ui/repr/repr-transparent-issue-87496.stderr new file mode 100644 index 0000000000000..c488755cc242c --- /dev/null +++ b/src/test/ui/repr/repr-transparent-issue-87496.stderr @@ -0,0 +1,16 @@ +warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe + --> $DIR/repr-transparent-issue-87496.rs:8:18 + | +LL | fn good17(p: TransparentCustomZst); + | ^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: `#[warn(improper_ctypes)]` on by default + = note: this struct contains only zero-sized fields +note: the type is defined here + --> $DIR/repr-transparent-issue-87496.rs:6:1 + | +LL | struct TransparentCustomZst(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + From b82ec362ca14a6c369b1999bdd40150b60567c96 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 7 Sep 2021 17:45:16 +0000 Subject: [PATCH 02/20] Recover from `Foo(a: 1, b: 2)` Detect likely `struct` literal using parentheses as delimiters and emit targeted suggestion instead of type ascription parse error. Fix #61326. --- compiler/rustc_parse/src/parser/expr.rs | 84 ++++++++++++++++--- src/test/ui/issues/issue-34255-1.rs | 2 +- src/test/ui/issues/issue-34255-1.stderr | 19 +++-- src/test/ui/parser/issue-44406.rs | 4 +- src/test/ui/parser/issue-44406.stderr | 20 +++-- .../ui/parser/recover-from-bad-variant.rs | 2 +- .../ui/parser/recover-from-bad-variant.stderr | 19 +++-- 7 files changed, 116 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a1d3e9adba013..c802d40fb8595 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -882,6 +882,12 @@ impl<'a> Parser<'a> { } } + fn look_ahead_type_ascription_as_field(&mut self) -> bool { + self.look_ahead(1, |t| t.is_ident()) + && self.look_ahead(2, |t| t == &token::Colon) + && self.look_ahead(3, |t| t.can_begin_expr()) + } + fn parse_dot_suffix_expr(&mut self, lo: Span, base: P) -> PResult<'a, P> { match self.token.uninterpolate().kind { token::Ident(..) => self.parse_dot_suffix(base, lo), @@ -1031,9 +1037,56 @@ impl<'a> Parser<'a> { /// Parse a function call expression, `expr(...)`. fn parse_fn_call_expr(&mut self, lo: Span, fun: P) -> P { - let seq = self.parse_paren_expr_seq().map(|args| { + let snapshot = if self.token.kind == token::OpenDelim(token::Paren) + && self.look_ahead_type_ascription_as_field() + { + Some((self.clone(), fun.kind.clone())) + } else { + None + }; + let open_paren = self.token.span; + + let mut seq = self.parse_paren_expr_seq().map(|args| { self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args), AttrVec::new()) }); + match (seq.as_mut(), snapshot) { + (Err(ref mut err), Some((mut snapshot, ExprKind::Path(None, path)))) => { + let name = pprust::path_to_string(&path); + snapshot.bump(); // `(` + match snapshot.parse_struct_fields(path.clone(), false, token::Paren) { + Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => { + // We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest + // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`. + *self = snapshot; + let close_paren = self.prev_token.span; + let span = lo.to(self.prev_token.span); + err.cancel(); + self.struct_span_err( + span, + "invalid `struct` delimiters or `fn` call arguments", + ) + .multipart_suggestion( + &format!("if `{}` is a struct, use braces as delimiters", name), + vec![(open_paren, " { ".to_string()), (close_paren, " }".to_string())], + Applicability::MaybeIncorrect, + ) + .multipart_suggestion( + &format!("if `{}` is a function, use the arguments directly", name), + fields + .into_iter() + .map(|field| (field.span.until(field.expr.span), String::new())) + .collect(), + Applicability::MaybeIncorrect, + ) + .emit(); + return self.mk_expr_err(span); + } + Ok(_) => {} + Err(mut err) => err.emit(), + } + } + _ => {} + } self.recover_seq_parse_error(token::Paren, lo, seq) } @@ -2332,14 +2385,12 @@ impl<'a> Parser<'a> { .emit(); } - /// Precondition: already parsed the '{'. - pub(super) fn parse_struct_expr( + pub(super) fn parse_struct_fields( &mut self, - qself: Option, pth: ast::Path, - attrs: AttrVec, recover: bool, - ) -> PResult<'a, P> { + close_delim: token::DelimToken, + ) -> PResult<'a, (Vec, ast::StructRest, bool)> { let mut fields = Vec::new(); let mut base = ast::StructRest::None; let mut recover_async = false; @@ -2351,11 +2402,11 @@ impl<'a> Parser<'a> { e.note("for more on editions, read https://doc.rust-lang.org/edition-guide"); }; - while self.token != token::CloseDelim(token::Brace) { + while self.token != token::CloseDelim(close_delim) { if self.eat(&token::DotDot) { let exp_span = self.prev_token.span; // We permit `.. }` on the left-hand side of a destructuring assignment. - if self.check(&token::CloseDelim(token::Brace)) { + if self.check(&token::CloseDelim(close_delim)) { self.sess.gated_spans.gate(sym::destructuring_assignment, self.prev_token.span); base = ast::StructRest::Rest(self.prev_token.span.shrink_to_hi()); break; @@ -2396,7 +2447,7 @@ impl<'a> Parser<'a> { } }; - match self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) { + match self.expect_one_of(&[token::Comma], &[token::CloseDelim(close_delim)]) { Ok(_) => { if let Some(f) = parsed_field.or(recovery_field) { // Only include the field if there's no parse error for the field name. @@ -2427,8 +2478,21 @@ impl<'a> Parser<'a> { } } } + Ok((fields, base, recover_async)) + } - let span = pth.span.to(self.token.span); + /// Precondition: already parsed the '{'. + pub(super) fn parse_struct_expr( + &mut self, + qself: Option, + pth: ast::Path, + attrs: AttrVec, + recover: bool, + ) -> PResult<'a, P> { + let lo = pth.span; + let (fields, base, recover_async) = + self.parse_struct_fields(pth.clone(), recover, token::Brace)?; + let span = lo.to(self.token.span); self.expect(&token::CloseDelim(token::Brace))?; let expr = if recover_async { ExprKind::Err diff --git a/src/test/ui/issues/issue-34255-1.rs b/src/test/ui/issues/issue-34255-1.rs index b1071934bb2f3..c70cd8b5077a9 100644 --- a/src/test/ui/issues/issue-34255-1.rs +++ b/src/test/ui/issues/issue-34255-1.rs @@ -6,5 +6,5 @@ enum Test { fn main() { Test::Drill(field: 42); - //~^ ERROR expected type, found + //~^ ERROR invalid `struct` delimiters or `fn` call arguments } diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr index c8bad3b3bb502..fbff75e37d9f0 100644 --- a/src/test/ui/issues/issue-34255-1.stderr +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -1,13 +1,18 @@ -error: expected type, found `42` - --> $DIR/issue-34255-1.rs:8:24 +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/issue-34255-1.rs:8:5 | LL | Test::Drill(field: 42); - | - ^^ expected type - | | - | tried to parse a type due to this type ascription + | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` - = note: see issue #23416 for more information +help: if `Test::Drill` is a struct, use braces as delimiters + | +LL | Test::Drill { field: 42 }; + | ~ ~ +help: if `Test::Drill` is a function, use the arguments directly + | +LL - Test::Drill(field: 42); +LL + Test::Drill(42); + | error: aborting due to previous error diff --git a/src/test/ui/parser/issue-44406.rs b/src/test/ui/parser/issue-44406.rs index 83bbf884a4ff8..a5b7e83a01622 100644 --- a/src/test/ui/parser/issue-44406.rs +++ b/src/test/ui/parser/issue-44406.rs @@ -1,10 +1,10 @@ macro_rules! foo { ($rest: tt) => { - bar(baz: $rest) + bar(baz: $rest) //~ ERROR invalid `struct` delimiters or `fn` call arguments } } fn main() { - foo!(true); //~ ERROR expected type, found keyword + foo!(true); //~^ ERROR expected identifier, found keyword } diff --git a/src/test/ui/parser/issue-44406.stderr b/src/test/ui/parser/issue-44406.stderr index 372387131e54b..862026408ef7f 100644 --- a/src/test/ui/parser/issue-44406.stderr +++ b/src/test/ui/parser/issue-44406.stderr @@ -9,17 +9,25 @@ help: you can escape reserved keywords to use them as identifiers LL | foo!(r#true); | ~~~~~~ -error: expected type, found keyword `true` - --> $DIR/issue-44406.rs:8:10 +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/issue-44406.rs:3:9 | LL | bar(baz: $rest) - | - help: try using a semicolon: `;` + | ^^^^^^^^^^^^^^^ ... LL | foo!(true); - | ^^^^ expected type + | ----------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: if `bar` is a struct, use braces as delimiters + | +LL | bar { } + | ~ +help: if `bar` is a function, use the arguments directly | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` - = note: see issue #23416 for more information +LL - bar(baz: $rest) +LL + bar(true); + | error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/recover-from-bad-variant.rs b/src/test/ui/parser/recover-from-bad-variant.rs index 1bcef450bb9be..e8887147cbc86 100644 --- a/src/test/ui/parser/recover-from-bad-variant.rs +++ b/src/test/ui/parser/recover-from-bad-variant.rs @@ -5,7 +5,7 @@ enum Enum { fn main() { let x = Enum::Foo(a: 3, b: 4); - //~^ ERROR expected type, found `3` + //~^ ERROR invalid `struct` delimiters or `fn` call arguments match x { Enum::Foo(a, b) => {} //~^ ERROR expected tuple struct or tuple variant, found struct variant `Enum::Foo` diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr index 61ea3695eee0b..8cb71069bdaac 100644 --- a/src/test/ui/parser/recover-from-bad-variant.stderr +++ b/src/test/ui/parser/recover-from-bad-variant.stderr @@ -1,13 +1,18 @@ -error: expected type, found `3` - --> $DIR/recover-from-bad-variant.rs:7:26 +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/recover-from-bad-variant.rs:7:13 | LL | let x = Enum::Foo(a: 3, b: 4); - | - ^ expected type - | | - | tried to parse a type due to this type ascription + | ^^^^^^^^^^^^^^^^^^^^^ | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` - = note: see issue #23416 for more information +help: if `Enum::Foo` is a struct, use braces as delimiters + | +LL | let x = Enum::Foo { a: 3, b: 4 }; + | ~ ~ +help: if `Enum::Foo` is a function, use the arguments directly + | +LL - let x = Enum::Foo(a: 3, b: 4); +LL + let x = Enum::Foo(3, 4); + | error[E0532]: expected tuple struct or tuple variant, found struct variant `Enum::Foo` --> $DIR/recover-from-bad-variant.rs:10:9 From a4a22f07d79b1a2adc6e59811ebfbcd8b2cf21a4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 31 Aug 2021 18:31:29 +0200 Subject: [PATCH 03/20] Doc comments --- compiler/rustc_session/src/filesearch.rs | 12 ++++++------ compiler/rustc_session/src/search_paths.rs | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 6fe6a555f1af8..a9999e1d92197 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -1,3 +1,5 @@ +//! A module for searching for libraries + pub use self::FileMatch::*; use std::env; @@ -14,8 +16,6 @@ pub enum FileMatch { FileDoesntMatch, } -// A module for searching for libraries - #[derive(Clone)] pub struct FileSearch<'a> { sysroot: &'a Path, @@ -83,12 +83,12 @@ impl<'a> FileSearch<'a> { FileSearch { sysroot, triple, search_paths, tlib_path, kind } } - // Returns just the directories within the search paths. + /// Returns just the directories within the search paths. pub fn search_path_dirs(&self) -> Vec { self.search_paths().map(|sp| sp.dir.to_path_buf()).collect() } - // Returns a list of directories where target-specific tool binaries are located. + /// Returns a list of directories where target-specific tool binaries are located. pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple); let p = std::array::IntoIter::new([ @@ -107,8 +107,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { .collect::() } -// This function checks if sysroot is found using env::args().next(), and if it -// is not found, uses env::current_exe() to imply sysroot. +/// This function checks if sysroot is found using env::args().next(), and if it +/// is not found, uses env::current_exe() to imply sysroot. pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. fn canonicalize(path: PathBuf) -> PathBuf { diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 83b737a73b1e8..acb6c735e051e 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -9,17 +9,17 @@ pub struct SearchPath { pub files: Vec, } -// The obvious implementation of `SearchPath::files` is a `Vec`. But -// it is searched repeatedly by `find_library_crate`, and the searches involve -// checking the prefix and suffix of the filename of each `PathBuf`. This is -// doable, but very slow, because it involves calls to `file_name` and -// `extension` that are themselves slow. -// -// This type augments the `PathBuf` with an `Option` containing the -// `PathBuf`'s filename. The prefix and suffix checking is much faster on the -// `Option` than the `PathBuf`. (It's an `Option` because -// `Path::file_name` can fail; if that happens then all subsequent checking -// will also fail, which is fine.) +/// The obvious implementation of `SearchPath::files` is a `Vec`. But +/// it is searched repeatedly by `find_library_crate`, and the searches involve +/// checking the prefix and suffix of the filename of each `PathBuf`. This is +/// doable, but very slow, because it involves calls to `file_name` and +/// `extension` that are themselves slow. +/// +/// This type augments the `PathBuf` with an `Option` containing the +/// `PathBuf`'s filename. The prefix and suffix checking is much faster on the +/// `Option` than the `PathBuf`. (It's an `Option` because +/// `Path::file_name` can fail; if that happens then all subsequent checking +/// will also fail, which is fine.) #[derive(Clone, Debug)] pub struct SearchPathFile { pub path: PathBuf, From 58000ed0e9152e331dc7c7319c7783cc7f028f84 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 31 Aug 2021 18:36:25 +0200 Subject: [PATCH 04/20] Move get_tools_search_paths from FileSearch to Session It only uses fields of FileSearch that are stored in Session too --- compiler/rustc_codegen_ssa/src/back/link.rs | 8 +++----- compiler/rustc_codegen_ssa/src/back/linker.rs | 3 +-- compiler/rustc_session/src/filesearch.rs | 12 ------------ compiler/rustc_session/src/session.rs | 14 +++++++++++++- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4fb51ecc1d347..826c09cd948f6 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -637,7 +637,7 @@ fn link_dwarf_object<'a>(sess: &'a Session, executable_out_filename: &Path) { cmd.arg("-o"); cmd.arg(&dwp_out_filename); - let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let mut new_path = sess.get_tools_search_paths(false); if let Some(path) = env::var_os("PATH") { new_path.extend(env::split_paths(&path)); } @@ -2555,8 +2555,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { match ld_impl { LdImpl::Lld => { if sess.target.lld_flavor == LldFlavor::Ld64 { - let tools_path = - sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let tools_path = sess.get_tools_search_paths(false); let ld64_exe = tools_path .into_iter() .map(|p| p.join("gcc-ld")) @@ -2571,8 +2570,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { arg }); } else { - let tools_path = - sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let tools_path = sess.get_tools_search_paths(false); let lld_path = tools_path .into_iter() .map(|p| p.join("gcc-ld")) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 9e1c6a169f152..e3b0eea0d89c7 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -15,7 +15,6 @@ use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::ty::TyCtxt; use rustc_serialize::{json, Encoder}; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; -use rustc_session::search_paths::PathKind; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor}; @@ -101,7 +100,7 @@ pub fn get_linker<'a>( // The compiler's sysroot often has some bundled tools, so add it to the // PATH for the child. - let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained); + let mut new_path = sess.get_tools_search_paths(self_contained); let mut msvc_changed_path = false; if sess.target.is_like_msvc { if let Some(ref tool) = msvc_tool { diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index a9999e1d92197..9359a55e55a9c 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -87,18 +87,6 @@ impl<'a> FileSearch<'a> { pub fn search_path_dirs(&self) -> Vec { self.search_paths().map(|sp| sp.dir.to_path_buf()).collect() } - - /// Returns a list of directories where target-specific tool binaries are located. - pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { - let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple); - let p = std::array::IntoIter::new([ - Path::new(&self.sysroot), - Path::new(&rustlib_path), - Path::new("bin"), - ]) - .collect::(); - if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } - } } pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c71595ab57e72..648743b7e866d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -36,7 +36,7 @@ use std::fmt; use std::io::Write; use std::num::NonZeroU32; use std::ops::{Div, Mul}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; use std::time::Duration; @@ -799,6 +799,18 @@ impl Session { ) } + /// Returns a list of directories where target-specific tool binaries are located. + pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { + let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, &config::host_triple()); + let p = std::array::IntoIter::new([ + Path::new(&self.sysroot), + Path::new(&rustlib_path), + Path::new("bin"), + ]) + .collect::(); + if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } + } + pub fn init_incr_comp_session( &self, session_dir: PathBuf, From d7ef0b30e89960aede88bf450e4a2172332432e0 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 1 Sep 2021 13:39:48 +0200 Subject: [PATCH 05/20] Use Lrc instead of Option to avoid duplication of a SearchPath --- compiler/rustc_driver/src/lib.rs | 5 +---- compiler/rustc_session/src/session.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 53053327d0dab..4c6a2baaef1e5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -677,10 +677,7 @@ impl RustcDefaultCalls { println!("{}", targets.join("\n")); } Sysroot => println!("{}", sess.sysroot.display()), - TargetLibdir => println!( - "{}", - sess.target_tlib_path.as_ref().unwrap_or(&sess.host_tlib_path).dir.display() - ), + TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()), TargetSpec => println!("{}", sess.target.to_json().pretty()), FileNames | CrateName => { let input = input.unwrap_or_else(|| { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 648743b7e866d..58ea29c080f3b 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -131,9 +131,8 @@ pub struct Session { pub target: Target, pub host: Target, pub opts: config::Options, - pub host_tlib_path: SearchPath, - /// `None` if the host and target are the same. - pub target_tlib_path: Option, + pub host_tlib_path: Lrc, + pub target_tlib_path: Lrc, pub parse_sess: ParseSess, pub sysroot: PathBuf, /// The name of the root source file of the crate, in the local file system. @@ -784,8 +783,7 @@ impl Session { &self.sysroot, self.opts.target_triple.triple(), &self.opts.search_paths, - // `target_tlib_path == None` means it's the same as `host_tlib_path`. - self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path), + &self.target_tlib_path, kind, ) } @@ -1254,11 +1252,13 @@ pub fn build_session( let host_triple = config::host_triple(); let target_triple = sopts.target_triple.triple(); - let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple); + let host_tlib_path = Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple)); let target_tlib_path = if host_triple == target_triple { - None + // Use the same `SearchPath` if host and target triple are identical to avoid unnecessary + // rescanning of the target lib path and an unnecessary allocation. + host_tlib_path.clone() } else { - Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) + Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) }; let file_path_mapping = sopts.file_path_mapping(); From 3feddf71e685f202e6f4f76ae9167daece33e460 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 6 Sep 2021 16:59:24 -0500 Subject: [PATCH 06/20] Add `ConstraintCategory::Usage` for handling aggregate construction In some cases, we emit borrowcheck diagnostics pointing at a particular field expression in a struct expression (e.g. `MyStruct { field: my_expr }`). However, this behavior currently relies on us choosing the `ConstraintCategory::Boring` with the 'correct' span. When adding additional variants to `ConstraintCategory`, (or changing existing usages away from `ConstraintCategory::Boring`), the current behavior can easily get broken, since a non-boring constraint will get chosen over a boring one. To make the diagnostic output less fragile, this commit adds a `ConstraintCategory::Usage` variant. We use this variant for the temporary assignments created for each field of an aggregate we are constructing. Using this new variant, we can emit a message mentioning "this usage", emphasizing the fact that the error message is related to the specific use site (in the struct expression). This is preparation for additional work on improving NLL error messages (see #57374) --- .../src/diagnostics/region_errors.rs | 1 + compiler/rustc_borrowck/src/type_check/mod.rs | 13 ++++++++++ compiler/rustc_middle/src/mir/mod.rs | 3 +++ compiler/rustc_middle/src/mir/query.rs | 8 +++---- .../src/build/expr/as_operand.rs | 17 +++++++++---- .../src/build/expr/as_rvalue.rs | 24 +++++++++++-------- .../rustc_mir_build/src/build/expr/into.rs | 11 +++++++-- src/test/ui/issues/issue-61882-2.stderr | 2 +- src/test/ui/nll/issue-46036.stderr | 2 +- .../user-annotations/adt-brace-enums.stderr | 6 ++--- .../user-annotations/adt-brace-structs.stderr | 6 ++--- .../user-annotations/adt-tuple-enums.stderr | 6 ++--- .../user-annotations/adt-tuple-struct.stderr | 6 ++--- .../ui/nll/where_clauses_in_structs.stderr | 2 +- 14 files changed, 71 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 57d2a3c5ce91b..0761d63c66540 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -40,6 +40,7 @@ impl ConstraintDescription for ConstraintCategory { ConstraintCategory::CopyBound => "copying this value ", ConstraintCategory::OpaqueType => "opaque type ", ConstraintCategory::ClosureUpvar(_) => "closure capture ", + ConstraintCategory::Usage => "this usage ", ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => "", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2c8ff45b00da4..9e8d418a369cc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1386,11 +1386,24 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Return(ReturnConstraint::Normal) } } + Some(l) + if matches!( + body.local_decls[l].local_info, + Some(box LocalInfo::AggregateTemp) + ) => + { + ConstraintCategory::Usage + } Some(l) if !body.local_decls[l].is_user_variable() => { ConstraintCategory::Boring } _ => ConstraintCategory::Assignment, }; + debug!( + "assignment category: {:?} {:?}", + category, + place.as_local().map(|l| &body.local_decls[l]) + ); let place_ty = place.ty(body, tcx).ty; let place_ty = self.normalize(place_ty, location); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 38d4c5b4bd10e..8a72b84bda80f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -993,6 +993,9 @@ pub enum LocalInfo<'tcx> { StaticRef { def_id: DefId, is_thread_local: bool }, /// A temporary created that references the const with the given `DefId` ConstRef { def_id: DefId }, + /// A temporary created during the creation of an aggregate + /// (e.g. a temporary for `foo` in `MyStruct { my_field: foo }`) + AggregateTemp, } impl<'tcx> LocalDecl<'tcx> { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 1bdb6ca012b4a..04beaa1379be5 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -332,17 +332,15 @@ pub enum ConstraintCategory { CopyBound, SizedBound, Assignment, + /// A constraint that came from a usage of a variable (e.g. in an ADT expression + /// like `Foo { field: my_val }`) + Usage, OpaqueType, ClosureUpvar(hir::HirId), /// A "boring" constraint (caused by the given location) is one that /// the user probably doesn't want to see described in diagnostics, /// because it is kind of an artifact of the type system setup. - /// Example: `x = Foo { field: y }` technically creates - /// intermediate regions representing the "type of `Foo { field: y - /// }`", and data flows from `y` into those variables, but they - /// are not very interesting. The assignment into `x` on the other - /// hand might be. Boring, // Boring and applicable everywhere. BoringNoLocation, diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index bbb2f89fda939..b627b0763a286 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -20,7 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { let local_scope = self.local_scope(); - self.as_operand(block, Some(local_scope), expr) + self.as_operand(block, Some(local_scope), expr, None) } /// Returns an operand suitable for use until the end of the current scope expression and @@ -85,6 +85,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// temporary `tmp = x`, so that we capture the value of `x` at /// this time. /// + /// If we end up needing to create a temporary, then we will use + /// `local_info` as its `LocalInfo`, unless `as_temporary` + /// has already assigned it a non-`None` `LocalInfo`. + /// Normally, you should use `None` for `local_info` + /// /// The operand is known to be live until the end of `scope`. /// /// Like `as_local_call_operand`, except that the argument will @@ -94,15 +99,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mut block: BasicBlock, scope: Option, expr: &Expr<'tcx>, + local_info: Option>>, ) -> BlockAnd> { - debug!("as_operand(block={:?}, expr={:?})", block, expr); + debug!("as_operand(block={:?}, expr={:?} local_info={:?})", block, expr, local_info); let this = self; if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { let source_info = this.source_info(expr.span); let region_scope = (region_scope, source_info); return this.in_scope(region_scope, lint_level, |this| { - this.as_operand(block, scope, &this.thir[value]) + this.as_operand(block, scope, &this.thir[value], local_info) }); } @@ -115,6 +121,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Category::Place | Category::Rvalue(..) => { let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut)); + if this.local_decls[operand].local_info.is_none() { + this.local_decls[operand].local_info = local_info; + } block.and(Operand::Move(Place::from(operand))) } } @@ -167,6 +176,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - this.as_operand(block, scope, expr) + this.as_operand(block, scope, expr, None) } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 68de1af613d9f..de532baab2fb2 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -52,16 +52,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Repeat { value, count } => { let value_operand = - unpack!(block = this.as_operand(block, scope, &this.thir[value])); + unpack!(block = this.as_operand(block, scope, &this.thir[value], None)); block.and(Rvalue::Repeat(value_operand, count)) } ExprKind::Binary { op, lhs, rhs } => { - let lhs = unpack!(block = this.as_operand(block, scope, &this.thir[lhs])); - let rhs = unpack!(block = this.as_operand(block, scope, &this.thir[rhs])); + let lhs = unpack!(block = this.as_operand(block, scope, &this.thir[lhs], None)); + let rhs = unpack!(block = this.as_operand(block, scope, &this.thir[rhs], None)); this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs) } ExprKind::Unary { op, arg } => { - let arg = unpack!(block = this.as_operand(block, scope, &this.thir[arg])); + let arg = unpack!(block = this.as_operand(block, scope, &this.thir[arg], None)); // Check for -MIN on signed integers if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() { let bool_ty = this.tcx.types.bool; @@ -116,11 +116,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(Rvalue::Use(Operand::Move(Place::from(result)))) } ExprKind::Cast { source } => { - let source = unpack!(block = this.as_operand(block, scope, &this.thir[source])); + let source = + unpack!(block = this.as_operand(block, scope, &this.thir[source], None)); block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty)) } ExprKind::Pointer { cast, source } => { - let source = unpack!(block = this.as_operand(block, scope, &this.thir[source])); + let source = + unpack!(block = this.as_operand(block, scope, &this.thir[source], None)); block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty)) } ExprKind::Array { ref fields } => { @@ -155,7 +157,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fields: Vec<_> = fields .into_iter() .copied() - .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f]))) + .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f], None))) .collect(); block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(el_ty)), fields)) @@ -166,7 +168,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fields: Vec<_> = fields .into_iter() .copied() - .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f]))) + .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f], None))) .collect(); block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields)) @@ -242,7 +244,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &this.thir[arg], ) ), - _ => unpack!(block = this.as_operand(block, scope, upvar)), + _ => { + unpack!(block = this.as_operand(block, scope, upvar, None)) + } } } } @@ -304,7 +308,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Category::of(&expr.kind), Some(Category::Rvalue(RvalueFunc::AsRvalue)) )); - let operand = unpack!(block = this.as_operand(block, scope, expr)); + let operand = unpack!(block = this.as_operand(block, scope, expr, None)); block.and(Rvalue::Use(operand)) } } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index e30e758e63779..1803a18441ce2 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -326,10 +326,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fields_map: FxHashMap<_, _> = fields .into_iter() .map(|f| { + let local_info = Box::new(LocalInfo::AggregateTemp); ( f.name, unpack!( - block = this.as_operand(block, Some(scope), &this.thir[f.expr]) + block = this.as_operand( + block, + Some(scope), + &this.thir[f.expr], + Some(local_info) + ) ), ) }) @@ -508,7 +514,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Yield { value } => { let scope = this.local_scope(); - let value = unpack!(block = this.as_operand(block, Some(scope), &this.thir[value])); + let value = + unpack!(block = this.as_operand(block, Some(scope), &this.thir[value], None)); let resume = this.cfg.start_new_block(); this.cfg.terminate( block, diff --git a/src/test/ui/issues/issue-61882-2.stderr b/src/test/ui/issues/issue-61882-2.stderr index 03a65540ced04..0b8e134c9662e 100644 --- a/src/test/ui/issues/issue-61882-2.stderr +++ b/src/test/ui/issues/issue-61882-2.stderr @@ -5,7 +5,7 @@ LL | Self(&x); | ^^ | | | borrowed value does not live long enough - | requires that `x` is borrowed for `'static` + | this usage requires that `x` is borrowed for `'static` LL | LL | } | - `x` dropped here while still borrowed diff --git a/src/test/ui/nll/issue-46036.stderr b/src/test/ui/nll/issue-46036.stderr index 49dd0e267b8ea..e6e95ee613647 100644 --- a/src/test/ui/nll/issue-46036.stderr +++ b/src/test/ui/nll/issue-46036.stderr @@ -5,7 +5,7 @@ LL | let foo = Foo { x: &a }; | ^^ | | | borrowed value does not live long enough - | requires that `a` is borrowed for `'static` + | this usage requires that `a` is borrowed for `'static` LL | loop { } LL | } | - `a` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr index e38b77fdcea01..253e382511045 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr @@ -5,7 +5,7 @@ LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-brace-structs.stderr b/src/test/ui/nll/user-annotations/adt-brace-structs.stderr index 3c3003477c2d6..8b9d1705df6ad 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-structs.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-structs.stderr @@ -5,7 +5,7 @@ LL | SomeStruct::<&'static u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeStruct::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeStruct::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr b/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr index 810912bf88618..2fa7042631d21 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr @@ -5,7 +5,7 @@ LL | SomeEnum::SomeVariant::<&'static u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeEnum::SomeVariant::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeEnum::SomeVariant::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr b/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr index 4d2140eca1b02..76b5252258c7b 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr +++ b/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr @@ -5,7 +5,7 @@ LL | SomeStruct::<&'static u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeStruct::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeStruct::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/where_clauses_in_structs.stderr b/src/test/ui/nll/where_clauses_in_structs.stderr index 2e990131e61de..8499b00f6f556 100644 --- a/src/test/ui/nll/where_clauses_in_structs.stderr +++ b/src/test/ui/nll/where_clauses_in_structs.stderr @@ -6,7 +6,7 @@ LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { | | | lifetime `'a` defined here LL | Foo { x, y }; - | ^ requires that `'a` must outlive `'b` + | ^ this usage requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` From 6b7f916008f48b9a8635d461dc33f7c5621611a2 Mon Sep 17 00:00:00 2001 From: Dan Zwell Date: Tue, 14 Sep 2021 14:22:49 +0800 Subject: [PATCH 07/20] Document the closure arguments for `reduce`. Fixes issue #88927. --- library/core/src/iter/traits/iterator.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 330d3714247c5..b0a9d9f5ef5c9 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2172,8 +2172,9 @@ pub trait Iterator { /// If the iterator is empty, returns [`None`]; otherwise, returns the /// result of the reduction. /// + /// The reducing function is a closure with two arguments: an 'accumulator', and an element. /// For iterators with at least one element, this is the same as [`fold()`] - /// with the first element of the iterator as the initial value, folding + /// with the first element of the iterator as the initial accumulator value, folding /// every subsequent element into it. /// /// [`fold()`]: Iterator::fold @@ -2187,8 +2188,8 @@ pub trait Iterator { /// where I: Iterator, /// I::Item: Ord, /// { - /// iter.reduce(|a, b| { - /// if a >= b { a } else { b } + /// iter.reduce(|accum, item| { + /// if accum >= item { accum } else { item } /// }) /// } /// let a = [10, 20, 5, -23, 0]; From ffc623ab93340f0c13fea3d518a00f6e0e49a7ec Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 14 Sep 2021 18:16:33 +0000 Subject: [PATCH 08/20] review comment: move recovery code to its own function --- compiler/rustc_parse/src/parser/expr.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c802d40fb8595..cfd3fe93d32eb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1049,6 +1049,23 @@ impl<'a> Parser<'a> { let mut seq = self.parse_paren_expr_seq().map(|args| { self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args), AttrVec::new()) }); + if let Some(expr) = + self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot) + { + return expr; + } + self.recover_seq_parse_error(token::Paren, lo, seq) + } + + /// If we encounter a parser state that looks like the user has written a `struct` literal with + /// parentheses instead of braces, recover the parser state and provide suggestions. + fn maybe_recover_struct_lit_bad_delims( + &mut self, + lo: Span, + open_paren: Span, + seq: &mut PResult<'a, P>, + snapshot: Option<(Self, ExprKind)>, + ) -> Option> { match (seq.as_mut(), snapshot) { (Err(ref mut err), Some((mut snapshot, ExprKind::Path(None, path)))) => { let name = pprust::path_to_string(&path); @@ -1079,7 +1096,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ) .emit(); - return self.mk_expr_err(span); + return Some(self.mk_expr_err(span)); } Ok(_) => {} Err(mut err) => err.emit(), @@ -1087,7 +1104,7 @@ impl<'a> Parser<'a> { } _ => {} } - self.recover_seq_parse_error(token::Paren, lo, seq) + None } /// Parse an indexing expression `expr[...]`. From 4840f67fcbe02fe6428a0a29bcf329401242b739 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 14 Sep 2021 18:29:38 -0700 Subject: [PATCH 09/20] Add chown functions to std::os::unix::fs to change the owner and group of files This is a straightforward wrapper that uses the existing helpers for C string handling and errno handling. Having this available is convenient for UNIX utility programs written in Rust, and avoids having to call unsafe functions like `libc::chown` directly and handle errors manually, in a program that may otherwise be entirely safe code. In addition, these functions provide a more Rustic interface by accepting appropriate traits and using `None` rather than `-1`. --- library/std/src/os/unix/fs.rs | 70 ++++++++++++++++++++++++++++++++++ library/std/src/sys/unix/fs.rs | 17 +++++++++ 2 files changed, 87 insertions(+) diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 6cf37f23c574d..c26f6a182b74f 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -5,6 +5,7 @@ use super::platform::fs::MetadataExt as _; use crate::fs::{self, OpenOptions, Permissions}; use crate::io; +use crate::os::unix::io::{AsFd, AsRawFd}; use crate::path::Path; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner}; @@ -924,6 +925,75 @@ impl DirBuilderExt for fs::DirBuilder { } } +/// Change the owner and group of the specified path. +/// +/// Specifying either the uid or gid as `None` will leave it unchanged. +/// +/// Changing the owner typically requires privileges, such as root or a specific capability. +/// Changing the group typically requires either being the owner and a member of the group, or +/// having privileges. +/// +/// If called on a symbolic link, this will change the owner and group of the link target. To +/// change the owner and group of the link itself, see [`lchown`]. +/// +/// # Examples +/// +/// ```no_run +/// #![feature(unix_chown)] +/// use std::os::unix::fs; +/// +/// fn main() -> std::io::Result<()> { +/// fs::chown("/sandbox", Some(0), Some(0))?; +/// Ok(()) +/// } +/// ``` +#[unstable(feature = "unix_chown", issue = "none")] +pub fn chown>(dir: P, uid: Option, gid: Option) -> io::Result<()> { + sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) +} + +/// Change the owner and group of the file referenced by the specified open file descriptor. +/// +/// For semantics and required privileges, see [`chown`]. +/// +/// # Examples +/// +/// ```no_run +/// #![feature(unix_chown)] +/// use std::os::unix::fs; +/// +/// fn main() -> std::io::Result<()> { +/// let f = std::fs::File::open("/file")?; +/// fs::fchown(f, Some(0), Some(0))?; +/// Ok(()) +/// } +/// ``` +#[unstable(feature = "unix_chown", issue = "none")] +pub fn fchown(fd: F, uid: Option, gid: Option) -> io::Result<()> { + sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) +} + +/// Change the owner and group of the specified path, without dereferencing symbolic links. +/// +/// Identical to [`chown`], except that if called on a symbolic link, this will change the owner +/// and group of the link itself rather than the owner and group of the link target. +/// +/// # Examples +/// +/// ```no_run +/// #![feature(unix_chown)] +/// use std::os::unix::fs; +/// +/// fn main() -> std::io::Result<()> { +/// fs::lchown("/symlink", Some(0), Some(0))?; +/// Ok(()) +/// } +/// ``` +#[unstable(feature = "unix_chown", issue = "none")] +pub fn lchown>(dir: P, uid: Option, gid: Option) -> io::Result<()> { + sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) +} + /// Change the root directory of the current process to the specified path. /// /// This typically requires privileges, such as root or a specific capability. diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 6d7524a733afd..a4fff9b2e6473 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1416,6 +1416,23 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { Ok(bytes_copied as u64) } +pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { + let path = cstr(path)?; + cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?; + Ok(()) +} + +pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> { + cvt(unsafe { libc::fchown(fd, uid as libc::uid_t, gid as libc::gid_t) })?; + Ok(()) +} + +pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { + let path = cstr(path)?; + cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?; + Ok(()) +} + #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))] pub fn chroot(dir: &Path) -> io::Result<()> { let dir = cstr(dir)?; From 870a132eaf1ca062e438cdc6bb76559dc5683292 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Mon, 5 Apr 2021 17:17:23 +0000 Subject: [PATCH 10/20] [aarch64] add target feature outline-atomics Enable outline-atomics by default as enabled in clang by the following commit https://reviews.llvm.org/rGc5e7e649d537067dec7111f3de1430d0fc8a4d11 Performance improves by several orders of magnitude when using the LSE instructions instead of the ARMv8.0 compatible load/store exclusive instructions. Tested on Graviton2 aarch64-linux with x.py build && x.py install && x.py test --- .../src/spec/aarch64_unknown_linux_gnu.rs | 1 + .../src/spec/aarch64_unknown_linux_musl.rs | 1 + src/test/assembly/asm/aarch64-outline-atomics.rs | 16 ++++++++++++++++ src/test/ui/abi/unsupported.aarch64.stderr | 1 + 4 files changed, 19 insertions(+) create mode 100644 src/test/assembly/asm/aarch64-outline-atomics.rs diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs index 3e92ecbae054c..6e5b48c881feb 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs @@ -9,6 +9,7 @@ pub fn target() -> Target { options: TargetOptions { mcount: "\u{1}_mcount".to_string(), max_atomic_width: Some(128), + features: "+outline-atomics".to_string(), supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs index 6a16b4ce41964..9aaa76649a35a 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs @@ -3,6 +3,7 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.max_atomic_width = Some(128); + base.features = "+outline-atomics".to_string(); Target { llvm_target: "aarch64-unknown-linux-musl".to_string(), diff --git a/src/test/assembly/asm/aarch64-outline-atomics.rs b/src/test/assembly/asm/aarch64-outline-atomics.rs new file mode 100644 index 0000000000000..93dda712e1b9b --- /dev/null +++ b/src/test/assembly/asm/aarch64-outline-atomics.rs @@ -0,0 +1,16 @@ +// min-llvm-version: 12.0 +// assembly-output: emit-asm +// compile-flags: -O +// compile-flags: --target aarch64-unknown-linux-gnu +// needs-llvm-components: aarch64 +// only-aarch64 + +#![crate_type = "rlib"] + +use std::sync::atomic::{AtomicI32, Ordering::*}; + +pub fn compare_exchange(a: &AtomicI32) { + // On AArch64 LLVM should outline atomic operations. + // CHECK: __aarch64_cas4_relax + let _ = a.compare_exchange(0, 10, Relaxed, Relaxed); +} diff --git a/src/test/ui/abi/unsupported.aarch64.stderr b/src/test/ui/abi/unsupported.aarch64.stderr index 225d49e05a3fa..ceee61a700d4c 100644 --- a/src/test/ui/abi/unsupported.aarch64.stderr +++ b/src/test/ui/abi/unsupported.aarch64.stderr @@ -1,3 +1,4 @@ +'+outline-atomics' is not a recognized feature for this target (ignoring feature) error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target --> $DIR/unsupported.rs:26:1 | From 97621162996c0746a528edaddb43c984e15a3d51 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Sun, 12 Sep 2021 18:49:56 +0000 Subject: [PATCH 11/20] Move object safety suggestions to the end of the error --- .../rustc_infer/src/traits/error_reporting/mod.rs | 12 ++++++++---- compiler/rustc_middle/src/traits/mod.rs | 4 ++-- .../associated-const-in-trait.stderr | 2 +- src/test/ui/associated-item/issue-48027.stderr | 2 +- ...coherence-impl-trait-for-trait-object-safe.stderr | 2 +- .../generic_const_exprs/object-safety-err-ret.stderr | 2 +- src/test/ui/error-codes/E0038.stderr | 2 +- .../feature-gate-object_safe_for_dispatch.stderr | 4 ++-- .../gat-in-trait-path.stderr | 2 +- .../generic-associated-types/issue-67510-pass.stderr | 2 +- .../ui/generic-associated-types/issue-76535.stderr | 4 ++-- .../ui/generic-associated-types/issue-78671.stderr | 2 +- .../ui/generic-associated-types/issue-79422.stderr | 4 ++-- .../ui/generic-associated-types/trait-objects.stderr | 2 +- src/test/ui/issues/issue-18959.stderr | 2 +- src/test/ui/issues/issue-19538.stderr | 4 ++-- .../object-safety-associated-consts.curr.stderr | 2 +- ...associated-consts.object_safe_for_dispatch.stderr | 2 +- .../object-safety/object-safety-generics.curr.stderr | 4 ++-- ...t-safety-generics.object_safe_for_dispatch.stderr | 4 ++-- .../object-safety-mentions-Self.curr.stderr | 4 ++-- ...ety-mentions-Self.object_safe_for_dispatch.stderr | 4 ++-- .../object-unsafe-trait-references-self.stderr | 4 ++-- src/test/ui/traits/item-privacy.stderr | 6 +++--- src/test/ui/traits/test-2.stderr | 8 ++++---- ...-parameter-defaults-referencing-Self-ppaux.stderr | 2 +- src/test/ui/wf/issue-87495.stderr | 2 +- src/test/ui/wf/wf-object-safe.stderr | 2 +- 28 files changed, 50 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index d0bd508bc257f..9dbfa3a850ba8 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -83,10 +83,6 @@ pub fn report_object_safety_error( messages.push(msg.clone()); } } - if trait_span.is_some() { - // Only provide the help if its a local trait, otherwise it's not actionable. - violation.solution(&mut err); - } } } let has_multi_span = !multi_span.is_empty(); @@ -104,5 +100,13 @@ pub fn report_object_safety_error( to be resolvable dynamically; for more information visit \ ", ); + if trait_span.is_some() { + let mut reported_violations: Vec<_> = reported_violations.into_iter().collect(); + reported_violations.sort(); + for violation in reported_violations { + // Only provide the help if its a local trait, otherwise it's not actionable. + violation.solution(&mut err); + } + } err } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 07c2ffac8c78c..fc88b95bc67cd 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -730,7 +730,7 @@ pub struct ImplSourceTraitAliasData<'tcx, N> { pub nested: Vec, } -#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. SizedSelf(SmallVec<[Span; 1]>), @@ -879,7 +879,7 @@ impl ObjectSafetyViolation { } /// Reasons a method might not be object-safe. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] pub enum MethodViolationCode { /// e.g., `fn foo()` StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */), diff --git a/src/test/ui/associated-consts/associated-const-in-trait.stderr b/src/test/ui/associated-consts/associated-const-in-trait.stderr index 7b4594108246b..fc949f2494857 100644 --- a/src/test/ui/associated-consts/associated-const-in-trait.stderr +++ b/src/test/ui/associated-consts/associated-const-in-trait.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | impl dyn Trait { | ^^^^^^^^^ `Trait` cannot be made into an object | - = help: consider moving `N` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/associated-const-in-trait.rs:6:11 | @@ -12,6 +11,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | const N: usize; | ^ ...because it contains this associated `const` + = help: consider moving `N` to another trait error: aborting due to previous error diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index 77915a80a79b0..7b158f1d75474 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -21,7 +21,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | impl dyn Bar {} | ^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `X` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-48027.rs:2:11 | @@ -29,6 +28,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr index a2b779e29540b..e9090c1b6bcfb 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object LL | impl NotObjectSafe for dyn NotObjectSafe { } | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object | - = help: consider moving `eq` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:6:43 | @@ -12,6 +11,7 @@ LL | trait NotObjectSafe { fn eq(&self, other: Self); } | ------------- ^^^^ ...because method `eq` references the `Self` type in this parameter | | | this trait cannot be made into an object... + = help: consider moving `eq` to another trait error: aborting due to previous error diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr index 319e6c2c032a0..4e1d71f154558 100644 --- a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | fn use_dyn(v: &dyn Foo) { | ^^^^^^^ `Foo` cannot be made into an object | - = help: consider moving `test` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-err-ret.rs:8:23 | @@ -12,6 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn test(&self) -> [u8; bar::()]; | ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type + = help: consider moving `test` to another trait error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index cead9776e4abb..3773d6f5234b0 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | fn call_foo(x: Box) { | ^^^^^^^^^ `Trait` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/E0038.rs:2:22 | @@ -12,6 +11,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn foo(&self) -> Self; | ^^^^ ...because method `foo` references the `Self` type in its return type + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index a3bd65e518e4c..72cb4cc843cc4 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -40,7 +40,6 @@ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object LL | fn takes_non_object_safe_box(obj: Box) { | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/feature-gate-object_safe_for_dispatch.rs:11:8 | @@ -48,6 +47,7 @@ LL | trait NonObjectSafe3 { | -------------- this trait cannot be made into an object... LL | fn foo(&self); | ^^^ ...because method `foo` has generic type parameters + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe4` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 @@ -55,7 +55,6 @@ error[E0038]: the trait `NonObjectSafe4` cannot be made into an object LL | fn return_non_object_safe_rc() -> std::rc::Rc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/feature-gate-object_safe_for_dispatch.rs:15:22 | @@ -63,6 +62,7 @@ LL | trait NonObjectSafe4 { | -------------- this trait cannot be made into an object... LL | fn foo(&self, s: &Self); | ^^^^^ ...because method `foo` references the `Self` type in this parameter + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16 diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr index 8651789688eaa..a55642490f975 100644 --- a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | fn f(_arg : Box Foo = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object | - = help: consider moving `A` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/gat-in-trait-path.rs:5:10 | @@ -12,6 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | type A<'a> where Self: 'a; | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.stderr index b4b89ab047363..7dd1bdf891eb5 100644 --- a/src/test/ui/generic-associated-types/issue-67510-pass.stderr +++ b/src/test/ui/generic-associated-types/issue-67510-pass.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `X` cannot be made into an object LL | fn _func1<'a>(_x: Box=&'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object | - = help: consider moving `Y` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-67510-pass.rs:4:10 | @@ -12,6 +11,7 @@ LL | trait X { | - this trait cannot be made into an object... LL | type Y<'a>; | ^ ...because it contains the generic associated type `Y` + = help: consider moving `Y` to another trait error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.stderr index 246454f0612db..0a7eb5dde6009 100644 --- a/src/test/ui/generic-associated-types/issue-76535.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.stderr @@ -20,7 +20,6 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object LL | let sub: Box> = Box::new(SuperStruct::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object | - = help: consider moving `SubType` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-76535.rs:6:10 | @@ -28,6 +27,7 @@ LL | pub trait SuperTrait { | ---------- this trait cannot be made into an object... LL | type SubType<'a>: SubTrait; | ^^^^^^^ ...because it contains the generic associated type `SubType` + = help: consider moving `SubType` to another trait error[E0038]: the trait `SuperTrait` cannot be made into an object --> $DIR/issue-76535.rs:36:57 @@ -35,7 +35,6 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object LL | let sub: Box> = Box::new(SuperStruct::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object | - = help: consider moving `SubType` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-76535.rs:6:10 | @@ -43,6 +42,7 @@ LL | pub trait SuperTrait { | ---------- this trait cannot be made into an object... LL | type SubType<'a>: SubTrait; | ^^^^^^^ ...because it contains the generic associated type `SubType` + = help: consider moving `SubType` to another trait = note: required because of the requirements on the impl of `CoerceUnsized>>>` for `Box` = note: required by cast to type `Box>>` diff --git a/src/test/ui/generic-associated-types/issue-78671.stderr b/src/test/ui/generic-associated-types/issue-78671.stderr index b92730839568d..17dd0ff4a0c94 100644 --- a/src/test/ui/generic-associated-types/issue-78671.stderr +++ b/src/test/ui/generic-associated-types/issue-78671.stderr @@ -20,7 +20,6 @@ error[E0038]: the trait `CollectionFamily` cannot be made into an object LL | Box::new(Family) as &dyn CollectionFamily | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object | - = help: consider moving `Member` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-78671.rs:4:10 | @@ -28,6 +27,7 @@ LL | trait CollectionFamily { | ---------------- this trait cannot be made into an object... LL | type Member; | ^^^^^^ ...because it contains the generic associated type `Member` + = help: consider moving `Member` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.stderr index 8d8ef6bf83685..b6f856a97e725 100644 --- a/src/test/ui/generic-associated-types/issue-79422.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.stderr @@ -20,7 +20,6 @@ error[E0038]: the trait `MapLike` cannot be made into an object LL | as Box>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object | - = help: consider moving `VRefCont` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-79422.rs:20:10 | @@ -28,6 +27,7 @@ LL | trait MapLike { | ------- this trait cannot be made into an object... LL | type VRefCont<'a>: RefCont<'a, V>; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + = help: consider moving `VRefCont` to another trait error[E0038]: the trait `MapLike` cannot be made into an object --> $DIR/issue-79422.rs:41:13 @@ -35,7 +35,6 @@ error[E0038]: the trait `MapLike` cannot be made into an object LL | let m = Box::new(std::collections::BTreeMap::::new()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object | - = help: consider moving `VRefCont` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-79422.rs:20:10 | @@ -43,6 +42,7 @@ LL | trait MapLike { | ------- this trait cannot be made into an object... LL | type VRefCont<'a>: RefCont<'a, V>; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + = help: consider moving `VRefCont` to another trait = note: required because of the requirements on the impl of `CoerceUnsized + 'static)>>>` for `Box>` = note: required by cast to type `Box + 'static)>>` diff --git a/src/test/ui/generic-associated-types/trait-objects.stderr b/src/test/ui/generic-associated-types/trait-objects.stderr index 6429bb8159e1f..5ab37910207ca 100644 --- a/src/test/ui/generic-associated-types/trait-objects.stderr +++ b/src/test/ui/generic-associated-types/trait-objects.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `StreamingIterator` cannot be made into an object LL | fn min_size(x: &mut dyn for<'a> StreamingIterator = &'a i32>) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object | - = help: consider moving `Item` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/trait-objects.rs:4:10 | @@ -12,6 +11,7 @@ LL | trait StreamingIterator { | ----------------- this trait cannot be made into an object... LL | type Item<'a> where Self: 'a; | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index 2a5416ce85ba6..b9e27873636c3 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn foo(b: &dyn Bar) { | ^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-18959.rs:1:20 | @@ -12,6 +11,7 @@ LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | ^^^ ...because method `foo` has generic type parameters LL | pub trait Bar: Foo { } | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index 555d0ff0dc787..7b37e1f95dcc6 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-19538.rs:2:8 | @@ -13,6 +12,7 @@ LL | fn foo(&self, val: T); ... LL | trait Bar: Foo { } | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:30 @@ -20,7 +20,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-19538.rs:2:8 | @@ -29,6 +28,7 @@ LL | fn foo(&self, val: T); ... LL | trait Bar: Foo { } | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing` = note: required by cast to type `&mut dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index 35ec586892c05..9dd144fee24a6 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `X` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-associated-consts.rs:9:11 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index d51734ed2316b..9ba3b251e6603 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t | ^ `Bar` cannot be made into an object | - = help: consider moving `X` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-associated-consts.rs:9:11 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 8d6094c514429..345950f1ae670 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:24:39 @@ -19,7 +19,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar_explicit(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -27,6 +26,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index 3d2b2bb228cb5..86355627c796f 100644 --- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t | ^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` @@ -21,7 +21,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t as &dyn Bar | ^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -29,6 +28,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 336929702e6cd..f91c9b9856055 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:11:22 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:28:30 @@ -19,7 +19,6 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^ `Baz` cannot be made into an object | - = help: consider moving `baz` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:15:22 | @@ -27,6 +26,7 @@ LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 6e7896e309cc6..f48628c9d1111 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t | ^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:11:22 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` @@ -21,7 +21,6 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | t | ^ `Baz` cannot be made into an object | - = help: consider moving `baz` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:15:22 | @@ -29,6 +28,7 @@ LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T` = note: required by cast to type `&dyn Baz` diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr index f332b7213d8bc..54f19fe9da445 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -4,8 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | fn bar(x: &dyn Trait) {} | ^^^^^^^^^ `Trait` cannot be made into an object | - = help: consider moving `baz` to another trait - = help: consider moving `bat` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-unsafe-trait-references-self.rs:2:22 | @@ -15,6 +13,8 @@ LL | fn baz(&self, _: Self) {} | ^^^^ ...because method `baz` references the `Self` type in this parameter LL | fn bat(&self) -> Self {} | ^^^^ ...because method `bat` references the `Self` type in its return type + = help: consider moving `baz` to another trait + = help: consider moving `bat` to another trait error[E0038]: the trait `Other` cannot be made into an object --> $DIR/object-unsafe-trait-references-self.rs:10:12 diff --git a/src/test/ui/traits/item-privacy.stderr b/src/test/ui/traits/item-privacy.stderr index 2260dcfc70ea3..ef5d5cdff8f4b 100644 --- a/src/test/ui/traits/item-privacy.stderr +++ b/src/test/ui/traits/item-privacy.stderr @@ -127,9 +127,6 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object LL | ::A; | ^^^^^ `assoc_const::C` cannot be made into an object | - = help: consider moving `C` to another trait - = help: consider moving `B` to another trait - = help: consider moving `A` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/item-privacy.rs:25:15 | @@ -143,6 +140,9 @@ LL | pub trait C: A + B { | - this trait cannot be made into an object... LL | const C: u8 = 0; | ^ ...because it contains this associated `const` + = help: consider moving `C` to another trait + = help: consider moving `A` to another trait + = help: consider moving `B` to another trait error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:115:12 diff --git a/src/test/ui/traits/test-2.stderr b/src/test/ui/traits/test-2.stderr index 0289424510f97..d943b48fd0082 100644 --- a/src/test/ui/traits/test-2.stderr +++ b/src/test/ui/traits/test-2.stderr @@ -32,8 +32,6 @@ error[E0038]: the trait `bar` cannot be made into an object LL | (box 10 as Box).dup(); | ^^^^^^^^^^^^ `bar` cannot be made into an object | - = help: consider moving `dup` to another trait - = help: consider moving `blah` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/test-2.rs:4:30 | @@ -42,6 +40,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | | | | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait error[E0038]: the trait `bar` cannot be made into an object --> $DIR/test-2.rs:13:6 @@ -49,8 +49,6 @@ error[E0038]: the trait `bar` cannot be made into an object LL | (box 10 as Box).dup(); | ^^^^^^ `bar` cannot be made into an object | - = help: consider moving `dup` to another trait - = help: consider moving `blah` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/test-2.rs:4:30 | @@ -59,6 +57,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | | | | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box<{integer}>` = note: required by cast to type `Box` diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index 2de5f6eb0f03a..8a296dc7ee6e1 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -16,7 +16,6 @@ error[E0038]: the trait `MyAdd` cannot be made into an object LL | let y = x as dyn MyAdd; | ^^^^^^^^^^^^^^ `MyAdd` cannot be made into an object | - = help: consider moving `add` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55 | @@ -24,6 +23,7 @@ LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } | ----- ^^^^ ...because method `add` references the `Self` type in its return type | | | this trait cannot be made into an object... + = help: consider moving `add` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/issue-87495.stderr b/src/test/ui/wf/issue-87495.stderr index 010200b5ded1f..c924cd87997e1 100644 --- a/src/test/ui/wf/issue-87495.stderr +++ b/src/test/ui/wf/issue-87495.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `T` cannot be made into an object LL | const CONST: (bool, dyn T); | ^^^^^ `T` cannot be made into an object | - = help: consider moving `CONST` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-87495.rs:4:11 | @@ -12,6 +11,7 @@ LL | trait T { | - this trait cannot be made into an object... LL | const CONST: (bool, dyn T); | ^^^^^ ...because it contains this associated `const` + = help: consider moving `CONST` to another trait error: aborting due to previous error diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 9b749f88fb810..64969fbe3203e 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `A` cannot be made into an object LL | let _x: &dyn A; | ^^^^^^ `A` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/wf-object-safe.rs:5:23 | @@ -12,6 +11,7 @@ LL | trait A { | - this trait cannot be made into an object... LL | fn foo(&self, _x: &Self); | ^^^^^ ...because method `foo` references the `Self` type in this parameter + = help: consider moving `foo` to another trait error: aborting due to previous error From ef44452a83a21742d67187c0f23d96ce5a05aaff Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 15 Sep 2021 09:13:18 -0700 Subject: [PATCH 12/20] chore(rustc_expand): fix typo in comment --- compiler/rustc_expand/src/mbe/quoted.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index fb7479eafc86f..363cc72b52c3e 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -72,7 +72,7 @@ pub(super) fn parse( // this with just `span.edition()`. A // `SyntaxContext::root()` from the current crate will // have the edition of the current crate, and a - // `SyntaxxContext::root()` from a foreign crate will + // `SyntaxContext::root()` from a foreign crate will // have the edition of that crate (which we manually // retrieve via the `edition` parameter). if span.ctxt() == SyntaxContext::root() { From cc7929b1bd2c50c5b07442195fc6b0a13fa61d35 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 15 Sep 2021 09:14:20 -0700 Subject: [PATCH 13/20] docs(std): add docs for cof_from_cstr impls CC #51430 --- library/std/src/ffi/c_str.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index de05c37785295..3b9175503080c 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -915,6 +915,7 @@ impl From for Box { #[stable(feature = "cow_from_cstr", since = "1.28.0")] impl<'a> From for Cow<'a, CStr> { + /// Converts a [`CString`] into an owned [`Cow`] without copying or allocating. #[inline] fn from(s: CString) -> Cow<'a, CStr> { Cow::Owned(s) @@ -923,6 +924,7 @@ impl<'a> From for Cow<'a, CStr> { #[stable(feature = "cow_from_cstr", since = "1.28.0")] impl<'a> From<&'a CStr> for Cow<'a, CStr> { + /// Converts a [`CStr`] into a borrowed [`Cow`] without copying or allocating. #[inline] fn from(s: &'a CStr) -> Cow<'a, CStr> { Cow::Borrowed(s) @@ -931,6 +933,7 @@ impl<'a> From<&'a CStr> for Cow<'a, CStr> { #[stable(feature = "cow_from_cstr", since = "1.28.0")] impl<'a> From<&'a CString> for Cow<'a, CStr> { + /// Converts a `&`[`CString`] into a borrowed [`Cow`] without copying or allocating. #[inline] fn from(s: &'a CString) -> Cow<'a, CStr> { Cow::Borrowed(s.as_c_str()) From c39d7599a3a346a571056d3d02081cccc8e62d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 15 Sep 2021 00:00:00 +0000 Subject: [PATCH 14/20] Disable RemoveZsts in generators to avoid query cycles Querying layout of a generator requires its optimized MIR. Thus computing layout during MIR optimization of a generator might create a query cycle. Disable RemoveZsts in generators to avoid the issue (similar approach is used in ConstProp transform already). --- compiler/rustc_mir_transform/src/remove_zsts.rs | 4 ++++ src/test/ui/mir/remove-zsts-query-cycle.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/test/ui/mir/remove-zsts-query-cycle.rs diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 25e3c52132cca..d93ffa38c6906 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -9,6 +9,10 @@ pub struct RemoveZsts; impl<'tcx> MirPass<'tcx> for RemoveZsts { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + // Avoid query cycles (generators require optimized MIR for layout). + if tcx.type_of(body.source.def_id()).is_generator() { + return; + } let param_env = tcx.param_env(body.source.def_id()); let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); for block in basic_blocks.iter_mut() { diff --git a/src/test/ui/mir/remove-zsts-query-cycle.rs b/src/test/ui/mir/remove-zsts-query-cycle.rs new file mode 100644 index 0000000000000..8f93c6cadff5a --- /dev/null +++ b/src/test/ui/mir/remove-zsts-query-cycle.rs @@ -0,0 +1,16 @@ +// Regression test for #88972. Used to cause a query cycle: +// optimized mir -> remove zsts -> layout of a generator -> optimized mir. +// +// edition:2018 +// compile-flags: --crate-type=lib +// build-pass + +pub async fn listen() -> Result<(), std::io::Error> { + let f = do_async(); + std::mem::forget(f); + Ok(()) +} + +pub async fn do_async() { + listen().await.unwrap() +} From 1b0186e9ecdaa6fd00f1beea7d877b5a4fbd762d Mon Sep 17 00:00:00 2001 From: Caio Date: Wed, 15 Sep 2021 14:03:27 -0300 Subject: [PATCH 15/20] Move some tests to more reasonable directories --- .../issue-19883.rs | 0 .../issue-19883.stderr | 0 .../issue-21363.rs | 0 .../auxiliary/issue-72470-lib.rs | 0 .../issue-72470-llvm-dominate.rs | 0 .../ui/{issues => closures}/issue-78720.rs | 0 .../{issues => closures}/issue-78720.stderr | 0 src/test/ui/{issues => consts}/issue-23833.rs | 0 src/test/ui/{issues => consts}/issue-34784.rs | 0 .../ui/{issues => deriving}/issue-3935.rs | 0 .../ui/{ => generics}/mid-path-type-params.rs | 0 .../type-arg-mismatch-due-to-impl-trait.rs | 0 ...type-arg-mismatch-due-to-impl-trait.stderr | 0 src/test/ui/issues/issue-5791.rs | 14 ------------- src/test/ui/issues/issue-5791.stderr | 21 ------------------- .../{ => lint}/enable-unstable-lib-feature.rs | 0 .../enable-unstable-lib-feature.stderr | 0 src/test/ui/{issues => lint}/issue-57410.rs | 0 src/test/ui/{issues => lint}/issue-79744.rs | 0 .../ui/{issues => lint}/issue-79744.stderr | 0 .../ui/{issues => llvm-asm}/issue-37433.rs | 0 .../{issues => llvm-asm}/issue-37433.stderr | 0 .../ui/{ => macros}/auxiliary/define-macro.rs | 0 .../ui/{ => macros}/out-of-order-shadowing.rs | 0 .../out-of-order-shadowing.stderr | 0 src/test/ui/{ => match}/guards.rs | 0 src/test/ui/{issues => match}/issue-33498.rs | 0 src/test/ui/{issues => match}/issue-41255.rs | 0 .../ui/{issues => match}/issue-41255.stderr | 0 src/test/ui/{issues => match}/issue-56685.rs | 0 .../ui/{issues => match}/issue-56685.stderr | 0 .../ui/{ => never_type}/expr-empty-ret.rs | 0 .../issue-74614.rs | 0 .../ui/{issues => privacy}/issue-79593.rs | 0 .../ui/{issues => privacy}/issue-79593.stderr | 0 .../ui/{issues => resolve}/issue-42944.rs | 0 .../ui/{issues => resolve}/issue-42944.stderr | 0 .../ui/{ => resolve}/use-self-in-inner-fn.rs | 0 .../{ => resolve}/use-self-in-inner-fn.stderr | 0 .../{issues => specialization}/issue-35376.rs | 0 .../issue-35376.stderr | 0 src/test/ui/{issues => static}/issue-34194.rs | 0 .../{issues => structs-enums}/issue-38002.rs | 0 .../{issues => symbol-names}/issue-53912.rs | 0 .../ui/{issues => test-attrs}/issue-36768.rs | 0 src/test/ui/{ => thread-local}/tls.rs | 0 src/test/ui/{ => traits}/bug-7183-generics.rs | 0 src/test/ui/{issues => traits}/issue-20692.rs | 0 .../ui/{issues => traits}/issue-20692.stderr | 0 src/test/ui/{issues => traits}/issue-23825.rs | 0 ...7-unnecessary-unsafe-in-closure.mir.stderr | 0 ...sue-45107-unnecessary-unsafe-in-closure.rs | 0 ...-unnecessary-unsafe-in-closure.thir.stderr | 0 src/tools/tidy/src/ui_tests.rs | 4 ++-- 54 files changed, 2 insertions(+), 37 deletions(-) rename src/test/ui/{issues => associated-types}/issue-19883.rs (100%) rename src/test/ui/{issues => associated-types}/issue-19883.stderr (100%) rename src/test/ui/{issues => associated-types}/issue-21363.rs (100%) rename src/test/ui/{ => async-await}/auxiliary/issue-72470-lib.rs (100%) rename src/test/ui/{ => async-await}/issue-72470-llvm-dominate.rs (100%) rename src/test/ui/{issues => closures}/issue-78720.rs (100%) rename src/test/ui/{issues => closures}/issue-78720.stderr (100%) rename src/test/ui/{issues => consts}/issue-23833.rs (100%) rename src/test/ui/{issues => consts}/issue-34784.rs (100%) rename src/test/ui/{issues => deriving}/issue-3935.rs (100%) rename src/test/ui/{ => generics}/mid-path-type-params.rs (100%) rename src/test/ui/{issues => impl-trait}/type-arg-mismatch-due-to-impl-trait.rs (100%) rename src/test/ui/{issues => impl-trait}/type-arg-mismatch-due-to-impl-trait.stderr (100%) delete mode 100644 src/test/ui/issues/issue-5791.rs delete mode 100644 src/test/ui/issues/issue-5791.stderr rename src/test/ui/{ => lint}/enable-unstable-lib-feature.rs (100%) rename src/test/ui/{ => lint}/enable-unstable-lib-feature.stderr (100%) rename src/test/ui/{issues => lint}/issue-57410.rs (100%) rename src/test/ui/{issues => lint}/issue-79744.rs (100%) rename src/test/ui/{issues => lint}/issue-79744.stderr (100%) rename src/test/ui/{issues => llvm-asm}/issue-37433.rs (100%) rename src/test/ui/{issues => llvm-asm}/issue-37433.stderr (100%) rename src/test/ui/{ => macros}/auxiliary/define-macro.rs (100%) rename src/test/ui/{ => macros}/out-of-order-shadowing.rs (100%) rename src/test/ui/{ => macros}/out-of-order-shadowing.stderr (100%) rename src/test/ui/{ => match}/guards.rs (100%) rename src/test/ui/{issues => match}/issue-33498.rs (100%) rename src/test/ui/{issues => match}/issue-41255.rs (100%) rename src/test/ui/{issues => match}/issue-41255.stderr (100%) rename src/test/ui/{issues => match}/issue-56685.rs (100%) rename src/test/ui/{issues => match}/issue-56685.stderr (100%) rename src/test/ui/{ => never_type}/expr-empty-ret.rs (100%) rename src/test/ui/{issues => polymorphization}/issue-74614.rs (100%) rename src/test/ui/{issues => privacy}/issue-79593.rs (100%) rename src/test/ui/{issues => privacy}/issue-79593.stderr (100%) rename src/test/ui/{issues => resolve}/issue-42944.rs (100%) rename src/test/ui/{issues => resolve}/issue-42944.stderr (100%) rename src/test/ui/{ => resolve}/use-self-in-inner-fn.rs (100%) rename src/test/ui/{ => resolve}/use-self-in-inner-fn.stderr (100%) rename src/test/ui/{issues => specialization}/issue-35376.rs (100%) rename src/test/ui/{issues => specialization}/issue-35376.stderr (100%) rename src/test/ui/{issues => static}/issue-34194.rs (100%) rename src/test/ui/{issues => structs-enums}/issue-38002.rs (100%) rename src/test/ui/{issues => symbol-names}/issue-53912.rs (100%) rename src/test/ui/{issues => test-attrs}/issue-36768.rs (100%) rename src/test/ui/{ => thread-local}/tls.rs (100%) rename src/test/ui/{ => traits}/bug-7183-generics.rs (100%) rename src/test/ui/{issues => traits}/issue-20692.rs (100%) rename src/test/ui/{issues => traits}/issue-20692.stderr (100%) rename src/test/ui/{issues => traits}/issue-23825.rs (100%) rename src/test/ui/{issues => unsafe}/issue-45107-unnecessary-unsafe-in-closure.mir.stderr (100%) rename src/test/ui/{issues => unsafe}/issue-45107-unnecessary-unsafe-in-closure.rs (100%) rename src/test/ui/{issues => unsafe}/issue-45107-unnecessary-unsafe-in-closure.thir.stderr (100%) diff --git a/src/test/ui/issues/issue-19883.rs b/src/test/ui/associated-types/issue-19883.rs similarity index 100% rename from src/test/ui/issues/issue-19883.rs rename to src/test/ui/associated-types/issue-19883.rs diff --git a/src/test/ui/issues/issue-19883.stderr b/src/test/ui/associated-types/issue-19883.stderr similarity index 100% rename from src/test/ui/issues/issue-19883.stderr rename to src/test/ui/associated-types/issue-19883.stderr diff --git a/src/test/ui/issues/issue-21363.rs b/src/test/ui/associated-types/issue-21363.rs similarity index 100% rename from src/test/ui/issues/issue-21363.rs rename to src/test/ui/associated-types/issue-21363.rs diff --git a/src/test/ui/auxiliary/issue-72470-lib.rs b/src/test/ui/async-await/auxiliary/issue-72470-lib.rs similarity index 100% rename from src/test/ui/auxiliary/issue-72470-lib.rs rename to src/test/ui/async-await/auxiliary/issue-72470-lib.rs diff --git a/src/test/ui/issue-72470-llvm-dominate.rs b/src/test/ui/async-await/issue-72470-llvm-dominate.rs similarity index 100% rename from src/test/ui/issue-72470-llvm-dominate.rs rename to src/test/ui/async-await/issue-72470-llvm-dominate.rs diff --git a/src/test/ui/issues/issue-78720.rs b/src/test/ui/closures/issue-78720.rs similarity index 100% rename from src/test/ui/issues/issue-78720.rs rename to src/test/ui/closures/issue-78720.rs diff --git a/src/test/ui/issues/issue-78720.stderr b/src/test/ui/closures/issue-78720.stderr similarity index 100% rename from src/test/ui/issues/issue-78720.stderr rename to src/test/ui/closures/issue-78720.stderr diff --git a/src/test/ui/issues/issue-23833.rs b/src/test/ui/consts/issue-23833.rs similarity index 100% rename from src/test/ui/issues/issue-23833.rs rename to src/test/ui/consts/issue-23833.rs diff --git a/src/test/ui/issues/issue-34784.rs b/src/test/ui/consts/issue-34784.rs similarity index 100% rename from src/test/ui/issues/issue-34784.rs rename to src/test/ui/consts/issue-34784.rs diff --git a/src/test/ui/issues/issue-3935.rs b/src/test/ui/deriving/issue-3935.rs similarity index 100% rename from src/test/ui/issues/issue-3935.rs rename to src/test/ui/deriving/issue-3935.rs diff --git a/src/test/ui/mid-path-type-params.rs b/src/test/ui/generics/mid-path-type-params.rs similarity index 100% rename from src/test/ui/mid-path-type-params.rs rename to src/test/ui/generics/mid-path-type-params.rs diff --git a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs b/src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.rs similarity index 100% rename from src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs rename to src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.rs diff --git a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr b/src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.stderr similarity index 100% rename from src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr rename to src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.stderr diff --git a/src/test/ui/issues/issue-5791.rs b/src/test/ui/issues/issue-5791.rs deleted file mode 100644 index 3544160f094e5..0000000000000 --- a/src/test/ui/issues/issue-5791.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![warn(clashing_extern_declarations)] -// pretty-expanded FIXME #23616 - -extern "C" { - #[link_name = "malloc"] - fn malloc1(len: i32) -> *const u8; - #[link_name = "malloc"] - //~^ WARN `malloc2` redeclares `malloc` with a different signature - fn malloc2(len: i32, foo: i32) -> *const u8; -} - -pub fn main() {} diff --git a/src/test/ui/issues/issue-5791.stderr b/src/test/ui/issues/issue-5791.stderr deleted file mode 100644 index cf60e609deb31..0000000000000 --- a/src/test/ui/issues/issue-5791.stderr +++ /dev/null @@ -1,21 +0,0 @@ -warning: `malloc2` redeclares `malloc` with a different signature - --> $DIR/issue-5791.rs:9:5 - | -LL | / #[link_name = "malloc"] -LL | | fn malloc1(len: i32) -> *const u8; - | |______________________________________- `malloc` previously declared here -LL | / #[link_name = "malloc"] -LL | | -LL | | fn malloc2(len: i32, foo: i32) -> *const u8; - | |________________________________________________^ this signature doesn't match the previous declaration - | -note: the lint level is defined here - --> $DIR/issue-5791.rs:3:9 - | -LL | #![warn(clashing_extern_declarations)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `unsafe extern "C" fn(i32) -> *const u8` - found `unsafe extern "C" fn(i32, i32) -> *const u8` - -warning: 1 warning emitted - diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/lint/enable-unstable-lib-feature.rs similarity index 100% rename from src/test/ui/enable-unstable-lib-feature.rs rename to src/test/ui/lint/enable-unstable-lib-feature.rs diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/lint/enable-unstable-lib-feature.stderr similarity index 100% rename from src/test/ui/enable-unstable-lib-feature.stderr rename to src/test/ui/lint/enable-unstable-lib-feature.stderr diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/lint/issue-57410.rs similarity index 100% rename from src/test/ui/issues/issue-57410.rs rename to src/test/ui/lint/issue-57410.rs diff --git a/src/test/ui/issues/issue-79744.rs b/src/test/ui/lint/issue-79744.rs similarity index 100% rename from src/test/ui/issues/issue-79744.rs rename to src/test/ui/lint/issue-79744.rs diff --git a/src/test/ui/issues/issue-79744.stderr b/src/test/ui/lint/issue-79744.stderr similarity index 100% rename from src/test/ui/issues/issue-79744.stderr rename to src/test/ui/lint/issue-79744.stderr diff --git a/src/test/ui/issues/issue-37433.rs b/src/test/ui/llvm-asm/issue-37433.rs similarity index 100% rename from src/test/ui/issues/issue-37433.rs rename to src/test/ui/llvm-asm/issue-37433.rs diff --git a/src/test/ui/issues/issue-37433.stderr b/src/test/ui/llvm-asm/issue-37433.stderr similarity index 100% rename from src/test/ui/issues/issue-37433.stderr rename to src/test/ui/llvm-asm/issue-37433.stderr diff --git a/src/test/ui/auxiliary/define-macro.rs b/src/test/ui/macros/auxiliary/define-macro.rs similarity index 100% rename from src/test/ui/auxiliary/define-macro.rs rename to src/test/ui/macros/auxiliary/define-macro.rs diff --git a/src/test/ui/out-of-order-shadowing.rs b/src/test/ui/macros/out-of-order-shadowing.rs similarity index 100% rename from src/test/ui/out-of-order-shadowing.rs rename to src/test/ui/macros/out-of-order-shadowing.rs diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/macros/out-of-order-shadowing.stderr similarity index 100% rename from src/test/ui/out-of-order-shadowing.stderr rename to src/test/ui/macros/out-of-order-shadowing.stderr diff --git a/src/test/ui/guards.rs b/src/test/ui/match/guards.rs similarity index 100% rename from src/test/ui/guards.rs rename to src/test/ui/match/guards.rs diff --git a/src/test/ui/issues/issue-33498.rs b/src/test/ui/match/issue-33498.rs similarity index 100% rename from src/test/ui/issues/issue-33498.rs rename to src/test/ui/match/issue-33498.rs diff --git a/src/test/ui/issues/issue-41255.rs b/src/test/ui/match/issue-41255.rs similarity index 100% rename from src/test/ui/issues/issue-41255.rs rename to src/test/ui/match/issue-41255.rs diff --git a/src/test/ui/issues/issue-41255.stderr b/src/test/ui/match/issue-41255.stderr similarity index 100% rename from src/test/ui/issues/issue-41255.stderr rename to src/test/ui/match/issue-41255.stderr diff --git a/src/test/ui/issues/issue-56685.rs b/src/test/ui/match/issue-56685.rs similarity index 100% rename from src/test/ui/issues/issue-56685.rs rename to src/test/ui/match/issue-56685.rs diff --git a/src/test/ui/issues/issue-56685.stderr b/src/test/ui/match/issue-56685.stderr similarity index 100% rename from src/test/ui/issues/issue-56685.stderr rename to src/test/ui/match/issue-56685.stderr diff --git a/src/test/ui/expr-empty-ret.rs b/src/test/ui/never_type/expr-empty-ret.rs similarity index 100% rename from src/test/ui/expr-empty-ret.rs rename to src/test/ui/never_type/expr-empty-ret.rs diff --git a/src/test/ui/issues/issue-74614.rs b/src/test/ui/polymorphization/issue-74614.rs similarity index 100% rename from src/test/ui/issues/issue-74614.rs rename to src/test/ui/polymorphization/issue-74614.rs diff --git a/src/test/ui/issues/issue-79593.rs b/src/test/ui/privacy/issue-79593.rs similarity index 100% rename from src/test/ui/issues/issue-79593.rs rename to src/test/ui/privacy/issue-79593.rs diff --git a/src/test/ui/issues/issue-79593.stderr b/src/test/ui/privacy/issue-79593.stderr similarity index 100% rename from src/test/ui/issues/issue-79593.stderr rename to src/test/ui/privacy/issue-79593.stderr diff --git a/src/test/ui/issues/issue-42944.rs b/src/test/ui/resolve/issue-42944.rs similarity index 100% rename from src/test/ui/issues/issue-42944.rs rename to src/test/ui/resolve/issue-42944.rs diff --git a/src/test/ui/issues/issue-42944.stderr b/src/test/ui/resolve/issue-42944.stderr similarity index 100% rename from src/test/ui/issues/issue-42944.stderr rename to src/test/ui/resolve/issue-42944.stderr diff --git a/src/test/ui/use-self-in-inner-fn.rs b/src/test/ui/resolve/use-self-in-inner-fn.rs similarity index 100% rename from src/test/ui/use-self-in-inner-fn.rs rename to src/test/ui/resolve/use-self-in-inner-fn.rs diff --git a/src/test/ui/use-self-in-inner-fn.stderr b/src/test/ui/resolve/use-self-in-inner-fn.stderr similarity index 100% rename from src/test/ui/use-self-in-inner-fn.stderr rename to src/test/ui/resolve/use-self-in-inner-fn.stderr diff --git a/src/test/ui/issues/issue-35376.rs b/src/test/ui/specialization/issue-35376.rs similarity index 100% rename from src/test/ui/issues/issue-35376.rs rename to src/test/ui/specialization/issue-35376.rs diff --git a/src/test/ui/issues/issue-35376.stderr b/src/test/ui/specialization/issue-35376.stderr similarity index 100% rename from src/test/ui/issues/issue-35376.stderr rename to src/test/ui/specialization/issue-35376.stderr diff --git a/src/test/ui/issues/issue-34194.rs b/src/test/ui/static/issue-34194.rs similarity index 100% rename from src/test/ui/issues/issue-34194.rs rename to src/test/ui/static/issue-34194.rs diff --git a/src/test/ui/issues/issue-38002.rs b/src/test/ui/structs-enums/issue-38002.rs similarity index 100% rename from src/test/ui/issues/issue-38002.rs rename to src/test/ui/structs-enums/issue-38002.rs diff --git a/src/test/ui/issues/issue-53912.rs b/src/test/ui/symbol-names/issue-53912.rs similarity index 100% rename from src/test/ui/issues/issue-53912.rs rename to src/test/ui/symbol-names/issue-53912.rs diff --git a/src/test/ui/issues/issue-36768.rs b/src/test/ui/test-attrs/issue-36768.rs similarity index 100% rename from src/test/ui/issues/issue-36768.rs rename to src/test/ui/test-attrs/issue-36768.rs diff --git a/src/test/ui/tls.rs b/src/test/ui/thread-local/tls.rs similarity index 100% rename from src/test/ui/tls.rs rename to src/test/ui/thread-local/tls.rs diff --git a/src/test/ui/bug-7183-generics.rs b/src/test/ui/traits/bug-7183-generics.rs similarity index 100% rename from src/test/ui/bug-7183-generics.rs rename to src/test/ui/traits/bug-7183-generics.rs diff --git a/src/test/ui/issues/issue-20692.rs b/src/test/ui/traits/issue-20692.rs similarity index 100% rename from src/test/ui/issues/issue-20692.rs rename to src/test/ui/traits/issue-20692.rs diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/traits/issue-20692.stderr similarity index 100% rename from src/test/ui/issues/issue-20692.stderr rename to src/test/ui/traits/issue-20692.stderr diff --git a/src/test/ui/issues/issue-23825.rs b/src/test/ui/traits/issue-23825.rs similarity index 100% rename from src/test/ui/issues/issue-23825.rs rename to src/test/ui/traits/issue-23825.rs diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.mir.stderr b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr similarity index 100% rename from src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.mir.stderr rename to src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs similarity index 100% rename from src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs rename to src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.thir.stderr b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr similarity index 100% rename from src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.thir.stderr rename to src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 46b5b877b4c26..a341527c84cf0 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,8 +7,8 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 1345; -const ISSUES_ENTRY_LIMIT: usize = 2525; +const ROOT_ENTRY_LIMIT: usize = 1330; +const ISSUES_ENTRY_LIMIT: usize = 2488; fn check_entries(path: &Path, bad: &mut bool) { let dirs = walkdir::WalkDir::new(&path.join("test/ui")) From 09745a63fe03ab58178ca579f39304a869c142ed Mon Sep 17 00:00:00 2001 From: Commeownist Date: Wed, 15 Sep 2021 21:31:59 +0300 Subject: [PATCH 16/20] Update clobber_abi list to include k[1-7] regs --- src/doc/unstable-book/src/library-features/asm.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 444b1cbf3cc45..ccaf6e8733e0c 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -804,9 +804,9 @@ The following ABIs can be used with `clobber_abi`: | Architecture | ABI name | Clobbered registers | | ------------ | -------- | ------------------- | -| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `st([0-7])` | +| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | +| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | +| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | | AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x30`, `v[0-31]`, `p[0-15]`, `ffr` | | ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` | | RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`, `x[28-31]`, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` | From 4e61d11a160bd43da0451e493d9e076848b8413a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Wed, 15 Sep 2021 20:32:35 +0200 Subject: [PATCH 17/20] Update the backtrace crate https://github.com/rust-lang/backtrace-rs/pull/437 fixed backtraces in OpenBSD -> update it here as well so OpenBSD Rust code can produce proper backtraces. --- library/backtrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/backtrace b/library/backtrace index 4f925f8d81dfa..cc89bb66f91b2 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 4f925f8d81dfa57067537217e501e1dff7433491 +Subproject commit cc89bb66f91b2b4a640b0b525ca5d753e3346d7e From 4fd39dd8a6f20bb919b30a56022c16e235cf7d5a Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Wed, 15 Sep 2021 11:41:37 -0700 Subject: [PATCH 18/20] Make rustc_mir_dataflow::framework::graphviz and rustc_mir_transform::MirPass public --- compiler/rustc_mir_dataflow/src/lib.rs | 4 ++-- compiler/rustc_mir_transform/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index bfae09b7760a0..72c4e27cbeabf 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -28,8 +28,8 @@ pub use self::drop_flag_effects::{ on_lookup_result_bits, }; pub use self::framework::{ - fmt, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine, Forward, - GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor, ResultsRefCursor, + fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine, + Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor, ResultsRefCursor, ResultsVisitable, ResultsVisitor, }; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 90d7cbee976d0..bfd0de85438d1 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -76,7 +76,7 @@ mod unreachable_prop; use rustc_const_eval::transform::check_consts; use rustc_const_eval::transform::promote_consts; use rustc_const_eval::transform::validate; -use rustc_const_eval::transform::MirPass; +pub use rustc_const_eval::transform::MirPass; use rustc_mir_dataflow::rustc_peek; pub fn provide(providers: &mut Providers) { From 47104a34a67444a086fd38c82e005f316f7f567a Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Wed, 15 Sep 2021 11:45:31 -0700 Subject: [PATCH 19/20] Allow call to get_body_with_borrowck_facts without -Z polonius --- compiler/rustc_borrowck/src/consumers.rs | 6 +++--- compiler/rustc_borrowck/src/lib.rs | 8 +++----- compiler/rustc_borrowck/src/nll.rs | 6 ++++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index f6e4e3888418f..4333038a6f936 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -14,7 +14,9 @@ pub use super::{ }; /// This function computes Polonius facts for the given body. It makes a copy of -/// the body because it needs to regenerate the region identifiers. +/// the body because it needs to regenerate the region identifiers. This function +/// should never be invoked during a typical compilation session due to performance +/// issues with Polonius. /// /// Note: /// * This function will panic if the required body was already stolen. This @@ -22,8 +24,6 @@ pub use super::{ /// because they are evaluated during typechecking. The panic can be avoided /// by overriding the `mir_borrowck` query. You can find a complete example /// that shows how to do this at `src/test/run-make/obtain-borrowck/`. -/// * This function will also panic if computation of Polonius facts -/// (`-Zpolonius` flag) is not enabled. /// /// * Polonius is highly unstable, so expect regular changes in its signature or other details. pub fn get_body_with_borrowck_facts<'tcx>( diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4e4b8a953cd12..b3b7d7e02ccef 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -154,11 +154,6 @@ fn do_mir_borrowck<'a, 'tcx>( debug!("do_mir_borrowck(def = {:?})", def); - assert!( - !return_body_with_facts || infcx.tcx.sess.opts.debugging_opts.polonius, - "borrowck facts can be requested only when Polonius is enabled" - ); - let tcx = infcx.tcx; let param_env = tcx.param_env(def.did); let id = tcx.hir().local_def_id_to_hir_id(def.did); @@ -235,6 +230,8 @@ fn do_mir_borrowck<'a, 'tcx>( let borrow_set = Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); + let use_polonius = return_body_with_facts || infcx.tcx.sess.opts.debugging_opts.polonius; + // Compute non-lexical lifetimes. let nll::NllOutput { regioncx, @@ -254,6 +251,7 @@ fn do_mir_borrowck<'a, 'tcx>( &mdpe.move_data, &borrow_set, &upvars, + use_polonius, ); // Dump MIR results into a file, if that is enabled. This let us diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 8b2c0362261ca..477b049b07596 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -164,8 +164,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>( move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, upvars: &[Upvar<'tcx>], + use_polonius: bool, ) -> NllOutput<'tcx> { - let mut all_facts = AllFacts::enabled(infcx.tcx).then_some(AllFacts::default()); + let mut all_facts = + (use_polonius || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default()); let universal_regions = Rc::new(universal_regions); @@ -281,7 +283,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( all_facts.write_to_dir(dir_path, location_table).unwrap(); } - if infcx.tcx.sess.opts.debugging_opts.polonius { + if use_polonius { let algorithm = env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Hybrid")); let algorithm = Algorithm::from_str(&algorithm).unwrap(); From 862d89e3b5ba092d95586fc2a33b23d1c8672087 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 15 Sep 2021 13:09:54 -0700 Subject: [PATCH 20/20] Add tracking issue for unix_chown --- library/std/src/os/unix/fs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index c26f6a182b74f..30eead9b05901 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -947,7 +947,7 @@ impl DirBuilderExt for fs::DirBuilder { /// Ok(()) /// } /// ``` -#[unstable(feature = "unix_chown", issue = "none")] +#[unstable(feature = "unix_chown", issue = "88989")] pub fn chown>(dir: P, uid: Option, gid: Option) -> io::Result<()> { sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) } @@ -968,7 +968,7 @@ pub fn chown>(dir: P, uid: Option, gid: Option) -> io:: /// Ok(()) /// } /// ``` -#[unstable(feature = "unix_chown", issue = "none")] +#[unstable(feature = "unix_chown", issue = "88989")] pub fn fchown(fd: F, uid: Option, gid: Option) -> io::Result<()> { sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) } @@ -989,7 +989,7 @@ pub fn fchown(fd: F, uid: Option, gid: Option) -> io::Result< /// Ok(()) /// } /// ``` -#[unstable(feature = "unix_chown", issue = "none")] +#[unstable(feature = "unix_chown", issue = "88989")] pub fn lchown>(dir: P, uid: Option, gid: Option) -> io::Result<()> { sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) }