diff --git a/Cargo.lock b/Cargo.lock
index cde73166babb7..a6fd8a4938c28 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3980,6 +3980,7 @@ name = "rustc_lexer"
version = "0.1.0"
dependencies = [
"expect-test",
+ "unic-emoji-char",
"unicode-xid",
]
@@ -5443,6 +5444,47 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+[[package]]
+name = "unic-char-property"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
+dependencies = [
+ "unic-char-range",
+]
+
+[[package]]
+name = "unic-char-range"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
+
+[[package]]
+name = "unic-common"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
+
+[[package]]
+name = "unic-emoji-char"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d"
+dependencies = [
+ "unic-char-property",
+ "unic-char-range",
+ "unic-ucd-version",
+]
+
+[[package]]
+name = "unic-ucd-version"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
+dependencies = [
+ "unic-common",
+]
+
[[package]]
name = "unicase"
version = "2.6.0"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index b92c5fa072786..c27ab810a4c60 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1902,10 +1902,6 @@ pub enum TyKind {
Never,
/// A tuple (`(A, B, C, D,...)`).
Tup(Vec
>),
- /// An anonymous struct type i.e. `struct { foo: Type }`
- AnonymousStruct(Vec, bool),
- /// An anonymous union type i.e. `union { bar: Type }`
- AnonymousUnion(Vec, bool),
/// A path (`module::module::...::Type`), optionally
/// "qualified", e.g., ` as SomeTrait>::SomeType`.
///
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 2ec941cbb2466..ba86036577ac5 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -484,9 +484,6 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) {
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
}
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
- TyKind::AnonymousStruct(fields, ..) | TyKind::AnonymousUnion(fields, ..) => {
- fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
- }
}
vis.visit_span(span);
visit_lazy_tts(tokens, vis);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index c30f711b39707..b38031042e0f0 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -407,9 +407,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
- TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => {
- walk_list!(visitor, visit_field_def, fields)
- }
TyKind::Never | TyKind::CVarArgs => {}
}
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index b7497c713f3df..a77e3e1997fd6 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -748,10 +748,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
- pub(super) fn lower_field_def(
- &mut self,
- (index, f): (usize, &FieldDef),
- ) -> hir::FieldDef<'hir> {
+ fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
let t = self.lower_path_ty(
&f.ty,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 8d731d7a57895..4cf54b07dbef8 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1301,15 +1301,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let kind = match t.kind {
TyKind::Infer => hir::TyKind::Infer,
TyKind::Err => hir::TyKind::Err,
- // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
- TyKind::AnonymousStruct(ref _fields, _recovered) => {
- self.sess.struct_span_err(t.span, "anonymous structs are unimplemented").emit();
- hir::TyKind::Err
- }
- TyKind::AnonymousUnion(ref _fields, _recovered) => {
- self.sess.struct_span_err(t.span, "anonymous unions are unimplemented").emit();
- hir::TyKind::Err
- }
TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
TyKind::Rptr(ref region, ref mt) => {
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index e9dce953c7388..6723cffc8e684 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -193,11 +193,6 @@ impl<'a> AstValidator<'a> {
}
}
}
- TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => {
- self.with_banned_assoc_ty_bound(|this| {
- walk_list!(this, visit_struct_field_def, fields)
- });
- }
_ => visit::walk_ty(self, t),
}
}
@@ -205,7 +200,6 @@ impl<'a> AstValidator<'a> {
fn visit_struct_field_def(&mut self, field: &'a FieldDef) {
if let Some(ident) = field.ident {
if ident.name == kw::Underscore {
- self.check_anonymous_field(field);
self.visit_vis(&field.vis);
self.visit_ident(ident);
self.visit_ty_common(&field.ty);
@@ -251,66 +245,6 @@ impl<'a> AstValidator<'a> {
err.emit();
}
- fn check_anonymous_field(&self, field: &FieldDef) {
- let FieldDef { ty, .. } = field;
- match &ty.kind {
- TyKind::AnonymousStruct(..) | TyKind::AnonymousUnion(..) => {
- // We already checked for `kw::Underscore` before calling this function,
- // so skip the check
- }
- TyKind::Path(..) => {
- // If the anonymous field contains a Path as type, we can't determine
- // if the path is a valid struct or union, so skip the check
- }
- _ => {
- let msg = "unnamed fields can only have struct or union types";
- let label = "not a struct or union";
- self.err_handler()
- .struct_span_err(field.span, msg)
- .span_label(ty.span, label)
- .emit();
- }
- }
- }
-
- fn deny_anonymous_struct(&self, ty: &Ty) {
- match &ty.kind {
- TyKind::AnonymousStruct(..) => {
- self.err_handler()
- .struct_span_err(
- ty.span,
- "anonymous structs are not allowed outside of unnamed struct or union fields",
- )
- .span_label(ty.span, "anonymous struct declared here")
- .emit();
- }
- TyKind::AnonymousUnion(..) => {
- self.err_handler()
- .struct_span_err(
- ty.span,
- "anonymous unions are not allowed outside of unnamed struct or union fields",
- )
- .span_label(ty.span, "anonymous union declared here")
- .emit();
- }
- _ => {}
- }
- }
-
- fn deny_anonymous_field(&self, field: &FieldDef) {
- if let Some(ident) = field.ident {
- if ident.name == kw::Underscore {
- self.err_handler()
- .struct_span_err(
- field.span,
- "anonymous fields are not allowed outside of structs or unions",
- )
- .span_label(ident.span, "anonymous field declared here")
- .emit()
- }
- }
- }
-
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) {
for Param { pat, .. } in &decl.inputs {
match pat.kind {
@@ -1081,7 +1015,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_ty(&mut self, ty: &'a Ty) {
self.visit_ty_common(ty);
- self.deny_anonymous_struct(ty);
self.walk_ty(ty)
}
@@ -1096,7 +1029,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
fn visit_field_def(&mut self, s: &'a FieldDef) {
- self.deny_anonymous_field(s);
visit::walk_field_def(self, s)
}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 1defb65ed8793..30bc4edd7e69c 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -668,7 +668,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
// involved, so we only emit errors where there are no other parsing errors.
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
}
- gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
// All uses of `gate_all!` below this point were added in #65742,
// and subsequently disabled (with the non-early gating readded).
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 3cf04be160c64..c24882086e12d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -985,14 +985,6 @@ impl<'a> State<'a> {
}
self.pclose();
}
- ast::TyKind::AnonymousStruct(ref fields, ..) => {
- self.head("struct");
- self.print_record_struct_body(&fields, ty.span);
- }
- ast::TyKind::AnonymousUnion(ref fields, ..) => {
- self.head("union");
- self.print_record_struct_body(&fields, ty.span);
- }
ast::TyKind::Paren(ref typ) => {
self.popen();
self.print_type(typ);
@@ -1413,7 +1405,12 @@ impl<'a> State<'a> {
}
}
- crate fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) {
+ crate fn print_record_struct_body(
+ &mut self,
+ fields: &Vec,
+ span: rustc_span::Span,
+ ) {
+ self.nbsp();
self.bopen();
self.hardbreak_if_not_bol();
@@ -1462,7 +1459,6 @@ impl<'a> State<'a> {
}
ast::VariantData::Struct(ref fields, ..) => {
self.print_where_clause(&generics.where_clause);
- self.nbsp();
self.print_record_struct_body(fields, span);
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index b032ee96ce7b0..698742fe98ceb 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -62,15 +62,10 @@ crate fn eval_nullary_intrinsic<'tcx>(
ensure_monomorphic_enough(tcx, tp_ty)?;
ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
}
- sym::min_align_of | sym::pref_align_of => {
+ sym::pref_align_of => {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
- let n = match name {
- sym::pref_align_of => layout.align.pref.bytes(),
- sym::min_align_of => layout.align.abi.bytes(),
- _ => bug!(),
- };
- ConstValue::from_machine_usize(n, &tcx)
+ ConstValue::from_machine_usize(layout.align.pref.bytes(), &tcx)
}
sym::type_id => {
ensure_monomorphic_enough(tcx, tp_ty)?;
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 29f352ae58559..47d240b389d64 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -721,7 +721,7 @@ impl EmitterWriter {
}
let source_string = match file.get_line(line.line_index - 1) {
- Some(s) => replace_tabs(&*s),
+ Some(s) => normalize_whitespace(&*s),
None => return Vec::new(),
};
@@ -1272,7 +1272,7 @@ impl EmitterWriter {
buffer.append(0, ": ", header_style);
}
for &(ref text, _) in msg.iter() {
- buffer.append(0, &replace_tabs(text), header_style);
+ buffer.append(0, &normalize_whitespace(text), header_style);
}
}
@@ -1526,7 +1526,7 @@ impl EmitterWriter {
self.draw_line(
&mut buffer,
- &replace_tabs(&unannotated_line),
+ &normalize_whitespace(&unannotated_line),
annotated_file.lines[line_idx + 1].line_index - 1,
last_buffer_line_num,
width_offset,
@@ -1648,7 +1648,7 @@ impl EmitterWriter {
buffer.puts(
row_num - 1,
max_line_num_len + 3,
- &replace_tabs(
+ &normalize_whitespace(
&*file_lines
.file
.get_line(file_lines.lines[line_pos].line_index)
@@ -1674,7 +1674,7 @@ impl EmitterWriter {
}
// print the suggestion
- buffer.append(row_num, &replace_tabs(line), Style::NoStyle);
+ buffer.append(row_num, &normalize_whitespace(line), Style::NoStyle);
// Colorize addition/replacements with green.
for &SubstitutionHighlight { start, end } in highlight_parts {
@@ -2054,8 +2054,17 @@ fn num_decimal_digits(num: usize) -> usize {
MAX_DIGITS
}
-fn replace_tabs(str: &str) -> String {
- str.replace('\t', " ")
+const REPLACEMENTS: &[(char, &str)] = &[
+ ('\t', " "),
+ ('\u{200D}', ""), // Replace ZWJ with nothing for consistent terminal output of grapheme clusters.
+];
+
+fn normalize_whitespace(str: &str) -> String {
+ let mut output = str.to_string();
+ for (c, replacement) in REPLACEMENTS {
+ output = output.replace(*c, replacement);
+ }
+ output
}
fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 366ed715434ed..efa93c186363a 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -638,9 +638,6 @@ declare_features! (
/// Allows specifying the as-needed link modifier
(active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
- /// Allows unnamed fields of struct and union type
- (incomplete, unnamed_fields, "1.53.0", Some(49804), None),
-
/// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
(active, more_qualified_paths, "1.54.0", Some(86935), None),
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index d0bd508bc257f..0679519c68fd6 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,11 @@ pub fn report_object_safety_error(
to be resolvable dynamically; for more information visit \
",
);
+ if trait_span.is_some() {
+ 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_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 1f3d6f70ff837..7071a98b77d15 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -35,7 +35,7 @@ use rustc_session::output::{filename_for_input, filename_for_metadata};
use rustc_session::search_paths::PathKind;
use rustc_session::Session;
use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::FileName;
+use rustc_span::{FileName, MultiSpan};
use rustc_trait_selection::traits;
use rustc_typeck as typeck;
use tempfile::Builder as TempFileBuilder;
@@ -445,6 +445,19 @@ pub fn configure_and_expand(
}
});
+ // Gate identifiers containing invalid Unicode codepoints that were recovered during lexing.
+ sess.parse_sess.bad_unicode_identifiers.with_lock(|identifiers| {
+ let mut identifiers: Vec<_> = identifiers.drain().collect();
+ identifiers.sort_by_key(|&(key, _)| key);
+ for (ident, mut spans) in identifiers.into_iter() {
+ spans.sort();
+ sess.diagnostic().span_err(
+ MultiSpan::from(spans),
+ &format!("identifiers cannot contain emoji: `{}`", ident),
+ );
+ }
+ });
+
Ok(krate)
}
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 81433e571021e..cfe13b1fd4e1f 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -754,6 +754,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(profiler_runtime, "abc".to_string());
tracked!(relax_elf_relocations, Some(true));
tracked!(relro_level, Some(RelroLevel::Full));
+ tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc")));
tracked!(report_delayed_bugs, true);
tracked!(sanitizer, SanitizerSet::ADDRESS);
diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml
index 7e05fe545cabe..a43333339543e 100644
--- a/compiler/rustc_lexer/Cargo.toml
+++ b/compiler/rustc_lexer/Cargo.toml
@@ -17,6 +17,7 @@ doctest = false
# Note that this crate purposefully does not depend on other rustc crates
[dependencies]
unicode-xid = "0.2.0"
+unic-emoji-char = "0.9.0"
[dev-dependencies]
expect-test = "1.0"
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index b64a891cb2526..44b002fa93f42 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -64,6 +64,8 @@ pub enum TokenKind {
/// "ident" or "continue"
/// At this step keywords are also considered identifiers.
Ident,
+ /// Like the above, but containing invalid unicode codepoints.
+ InvalidIdent,
/// "r#ident"
RawIdent,
/// An unknown prefix like `foo#`, `foo'`, `foo"`. Note that only the
@@ -411,6 +413,10 @@ impl Cursor<'_> {
let kind = Str { terminated };
Literal { kind, suffix_start }
}
+ // Identifier starting with an emoji. Only lexed for graceful error recovery.
+ c if !c.is_ascii() && unic_emoji_char::is_emoji(c) => {
+ self.fake_ident_or_unknown_prefix()
+ }
_ => Unknown,
};
Token::new(token_kind, self.len_consumed())
@@ -492,10 +498,28 @@ impl Cursor<'_> {
// we see a prefix here, it is definitely an unknown prefix.
match self.first() {
'#' | '"' | '\'' => UnknownPrefix,
+ c if !c.is_ascii() && unic_emoji_char::is_emoji(c) => {
+ self.fake_ident_or_unknown_prefix()
+ }
_ => Ident,
}
}
+ fn fake_ident_or_unknown_prefix(&mut self) -> TokenKind {
+ // Start is already eaten, eat the rest of identifier.
+ self.eat_while(|c| {
+ unicode_xid::UnicodeXID::is_xid_continue(c)
+ || (!c.is_ascii() && unic_emoji_char::is_emoji(c))
+ || c == '\u{200d}'
+ });
+ // Known prefixes must have been handled earlier. So if
+ // we see a prefix here, it is definitely an unknown prefix.
+ match self.first() {
+ '#' | '"' | '\'' => UnknownPrefix,
+ _ => InvalidIdent,
+ }
+ }
+
fn number(&mut self, first_digit: char) -> LiteralKind {
debug_assert!('0' <= self.prev() && self.prev() <= '9');
let mut base = Base::Decimal;
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 1e65cc27154a8..b0552dda1177d 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -1,3 +1,4 @@
+use crate::lexer::unicode_chars::UNICODE_ARRAY;
use rustc_ast::ast::{self, AttrStyle};
use rustc_ast::token::{self, CommentKind, Token, TokenKind};
use rustc_ast::tokenstream::{Spacing, TokenStream};
@@ -191,6 +192,22 @@ impl<'a> StringReader<'a> {
}
token::Ident(sym, is_raw_ident)
}
+ rustc_lexer::TokenKind::InvalidIdent
+ // Do not recover an identifier with emoji if the codepoint is a confusable
+ // with a recoverable substitution token, like `โ`.
+ if UNICODE_ARRAY
+ .iter()
+ .find(|&&(c, _, _)| {
+ let sym = self.str_from(start);
+ sym.chars().count() == 1 && c == sym.chars().next().unwrap()
+ })
+ .is_none() =>
+ {
+ let sym = nfc_normalize(self.str_from(start));
+ let span = self.mk_sp(start, self.pos);
+ self.sess.bad_unicode_identifiers.borrow_mut().entry(sym).or_default().push(span);
+ token::Ident(sym, false)
+ }
rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
let suffix_start = start + BytePos(suffix_start as u32);
let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
@@ -262,7 +279,7 @@ impl<'a> StringReader<'a> {
rustc_lexer::TokenKind::Caret => token::BinOp(token::Caret),
rustc_lexer::TokenKind::Percent => token::BinOp(token::Percent),
- rustc_lexer::TokenKind::Unknown => {
+ rustc_lexer::TokenKind::Unknown | rustc_lexer::TokenKind::InvalidIdent => {
let c = self.str_from(start).chars().next().unwrap();
let mut err =
self.struct_fatal_span_char(start, self.pos, "unknown start of token", c);
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index 3eebc088f3fb7..ccd11f06bc582 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -7,7 +7,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_span::{symbol::kw, BytePos, Pos, Span};
#[rustfmt::skip] // for line breaks
-const UNICODE_ARRAY: &[(char, &str, char)] = &[
+pub(crate) const UNICODE_ARRAY: &[(char, &str, char)] = &[
('โจ', "Line Separator", ' '),
('โฉ', "Paragraph Separator", ' '),
('แ', "Ogham Space mark", ' '),
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 04a7948e8c96e..0e2222bf84093 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1247,7 +1247,7 @@ impl<'a> Parser<'a> {
Ok((class_name, ItemKind::Union(vdata, generics)))
}
- pub(super) fn parse_record_struct_body(
+ fn parse_record_struct_body(
&mut self,
adt_ty: &str,
) -> PResult<'a, (Vec, /* recovered */ bool)> {
@@ -1481,28 +1481,22 @@ impl<'a> Parser<'a> {
fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
let (ident, is_raw) = self.ident_or_err()?;
if !is_raw && ident.is_reserved() {
- if ident.name == kw::Underscore {
- self.sess.gated_spans.gate(sym::unnamed_fields, lo);
+ let err = if self.check_fn_front_matter(false) {
+ // We use `parse_fn` to get a span for the function
+ if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) {
+ db.delay_as_bug();
+ }
+ let mut err = self.struct_span_err(
+ lo.to(self.prev_token.span),
+ &format!("functions are not allowed in {} definitions", adt_ty),
+ );
+ err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
+ err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
+ err
} else {
- let err = if self.check_fn_front_matter(false) {
- // We use `parse_fn` to get a span for the function
- if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) {
- db.delay_as_bug();
- }
- let mut err = self.struct_span_err(
- lo.to(self.prev_token.span),
- &format!("functions are not allowed in {} definitions", adt_ty),
- );
- err.help(
- "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
- );
- err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
- err
- } else {
- self.expected_ident_found()
- };
- return Err(err);
- }
+ self.expected_ident_found()
+ };
+ return Err(err);
}
self.bump();
Ok(ident)
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 25dcb4a112de1..9ec6effeb4e03 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -155,17 +155,20 @@ impl<'a> Parser<'a> {
let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription };
- let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof
- {
- StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
- } else {
- // Since none of the above applied, this is an expression statement macro.
- let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
- let e = self.maybe_recover_from_bad_qpath(e, true)?;
- let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
- let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
- StmtKind::Expr(e)
- };
+ let kind =
+ if (delim == token::Brace && self.token != token::Dot && self.token != token::Question)
+ || self.token == token::Semi
+ || self.token == token::Eof
+ {
+ StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
+ } else {
+ // Since none of the above applied, this is an expression statement macro.
+ let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
+ let e = self.maybe_recover_from_bad_qpath(e, true)?;
+ let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
+ let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
+ StmtKind::Expr(e)
+ };
Ok(self.mk_stmt(lo.to(hi), kind))
}
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 299fc916ac97f..98400372c36a6 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -226,19 +226,6 @@ impl<'a> Parser<'a> {
}
} else if self.eat_keyword(kw::Impl) {
self.parse_impl_ty(&mut impl_dyn_multi)?
- } else if self.token.is_keyword(kw::Union)
- && self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
- {
- self.bump();
- let (fields, recovered) = self.parse_record_struct_body("union")?;
- let span = lo.to(self.prev_token.span);
- self.sess.gated_spans.gate(sym::unnamed_fields, span);
- TyKind::AnonymousUnion(fields, recovered)
- } else if self.eat_keyword(kw::Struct) {
- let (fields, recovered) = self.parse_record_struct_body("struct")?;
- let span = lo.to(self.prev_token.span);
- self.sess.gated_spans.gate(sym::unnamed_fields, span);
- TyKind::AnonymousStruct(fields, recovered)
} else if self.is_explicit_dyn_type() {
self.parse_dyn_ty(&mut impl_dyn_multi)?
} else if self.eat_lt() {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index fdedb7e6a4afe..32aa035e1cdec 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1920,9 +1920,10 @@ fn parse_extern_dep_specs(
fn parse_remap_path_prefix(
matches: &getopts::Matches,
+ debugging_opts: &DebuggingOptions,
error_format: ErrorOutputType,
) -> Vec<(PathBuf, PathBuf)> {
- matches
+ let mut mapping: Vec<(PathBuf, PathBuf)> = matches
.opt_strs("remap-path-prefix")
.into_iter()
.map(|remap| match remap.rsplit_once('=') {
@@ -1932,7 +1933,15 @@ fn parse_remap_path_prefix(
),
Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
})
- .collect()
+ .collect();
+ match &debugging_opts.remap_cwd_prefix {
+ Some(to) => match std::env::current_dir() {
+ Ok(cwd) => mapping.push((cwd, to.clone())),
+ Err(_) => (),
+ },
+ None => (),
+ };
+ mapping
}
pub fn build_session_options(matches: &getopts::Matches) -> Options {
@@ -2077,7 +2086,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let crate_name = matches.opt_str("crate-name");
- let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
+ let remap_path_prefix = parse_remap_path_prefix(matches, &debugging_opts, error_format);
let pretty = parse_pretty(&debugging_opts, error_format);
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index bb29a87035e80..8110afe75fa92 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1250,6 +1250,8 @@ options! {
"whether ELF relocations can be relaxed"),
relro_level: Option = (None, parse_relro_level, [TRACKED],
"choose which RELRO level to use"),
+ remap_cwd_prefix: Option = (None, parse_opt_pathbuf, [TRACKED],
+ "remap paths under the current working directory to this path prefix"),
simulate_remapped_rust_src_base: Option = (None, parse_opt_pathbuf, [TRACKED],
"simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
to rust's source base directory. only meant for testing purposes"),
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index a007b53030271..24e0cd1862ff3 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -119,8 +119,13 @@ pub struct ParseSess {
pub config: CrateConfig,
pub edition: Edition,
pub missing_fragment_specifiers: Lock>,
- /// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
+ /// Places where raw identifiers were used. This is used to avoid complaining about idents
+ /// clashing with keywords in new editions.
pub raw_identifier_spans: Lock>,
+ /// Places where identifiers that contain invalid Unicode codepoints but that look like they
+ /// should be. Useful to avoid bad tokenization when encountering emoji. We group them to
+ /// provide a single error per unique incorrect identifier.
+ pub bad_unicode_identifiers: Lock>>,
source_map: Lrc,
pub buffered_lints: Lock>,
/// Contains the spans of block expressions that could have been incomplete based on the
@@ -160,6 +165,7 @@ impl ParseSess {
edition: ExpnId::root().expn_data().edition,
missing_fragment_specifiers: Default::default(),
raw_identifier_spans: Lock::new(Vec::new()),
+ bad_unicode_identifiers: Lock::new(Default::default()),
source_map,
buffered_lints: Lock::new(vec![]),
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c816d06045681..b1aea3c9ba00a 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1359,7 +1359,6 @@ symbols! {
unix,
unlikely,
unmarked_api,
- unnamed_fields,
unpin,
unreachable,
unreachable_code,
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index d578fac4cdb22..f4e3c8e0d9f7f 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1842,7 +1842,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr_t
);
err.span_label(field.span, "method, not a field");
- if !self.expr_in_place(expr.hir_id) {
+ let expr_is_call =
+ if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) =
+ self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id))
+ {
+ expr.hir_id == callee.hir_id
+ } else {
+ false
+ };
+ let expr_snippet =
+ self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new());
+ if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") {
+ let after_open = expr.span.lo() + rustc_span::BytePos(1);
+ let before_close = expr.span.hi() - rustc_span::BytePos(1);
+ err.multipart_suggestion(
+ "remove wrapping parentheses to call the method",
+ vec![
+ (expr.span.with_hi(after_open), String::new()),
+ (expr.span.with_lo(before_close), String::new()),
+ ],
+ Applicability::MachineApplicable,
+ );
+ } else if !self.expr_in_place(expr.hir_id) {
self.suggest_method_call(
&mut err,
"use parentheses to call the method",
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index be6d70320d407..b078cdf5479d7 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -32,6 +32,10 @@ use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
///
/// assert_eq!(u32::MAX, (zero - one).0);
/// ```
+///
+/// # Layout
+///
+/// `Wrapping` is guaranteed to have the same layout and ABI as `T`.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
#[repr(transparent)]
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 79e6967300767..069a5376a441c 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -10,29 +10,20 @@ pub mod raw;
// of a macro that is not vendored by Rust and included in the toolchain.
// See https://github.com/rust-analyzer/rust-analyzer/issues/6038.
+// On certain platforms right now the "main modules" modules that are
+// documented don't compile (missing things in `libc` which is empty),
+// so just omit them with an empty module and add the "unstable" attribute.
+
+// Unix, linux, wasi and windows are handled a bit differently.
#[cfg(all(
doc,
- not(any(
+ any(
all(target_arch = "wasm32", not(target_os = "wasi")),
all(target_vendor = "fortanix", target_env = "sgx")
- ))
+ )
))]
-#[path = "."]
-mod doc {
- // When documenting std we want to show the `unix`, `windows`, `linux` and `wasi`
- // modules as these are the "main modules" that are used across platforms,
- // so these modules are enabled when `cfg(doc)` is set.
- // This should help show platform-specific functionality in a hopefully cross-platform
- // way in the documentation.
-
- pub mod unix;
-
- pub mod linux;
-
- pub mod wasi;
-
- pub mod windows;
-}
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod unix {}
#[cfg(all(
doc,
any(
@@ -40,87 +31,115 @@ mod doc {
all(target_vendor = "fortanix", target_env = "sgx")
)
))]
-mod doc {
- // On certain platforms right now the "main modules" modules that are
- // documented don't compile (missing things in `libc` which is empty),
- // so just omit them with an empty module.
-
- #[unstable(issue = "none", feature = "std_internals")]
- pub mod unix {}
-
- #[unstable(issue = "none", feature = "std_internals")]
- pub mod linux {}
-
- #[unstable(issue = "none", feature = "std_internals")]
- pub mod wasi {}
-
- #[unstable(issue = "none", feature = "std_internals")]
- pub mod windows {}
-}
-#[cfg(doc)]
-#[stable(feature = "os", since = "1.0.0")]
-pub use doc::*;
-
-#[cfg(not(doc))]
-#[path = "."]
-mod imp {
- // If we're not documenting std then we only expose modules appropriate for the
- // current platform.
-
- #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
- pub mod fortanix_sgx;
-
- #[cfg(target_os = "hermit")]
- #[path = "hermit/mod.rs"]
- pub mod unix;
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod linux {}
+#[cfg(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+))]
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod wasi {}
+#[cfg(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+))]
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod windows {}
- #[cfg(target_os = "android")]
- pub mod android;
- #[cfg(target_os = "dragonfly")]
- pub mod dragonfly;
- #[cfg(target_os = "emscripten")]
- pub mod emscripten;
- #[cfg(target_os = "espidf")]
- pub mod espidf;
- #[cfg(target_os = "freebsd")]
- pub mod freebsd;
- #[cfg(target_os = "fuchsia")]
- pub mod fuchsia;
- #[cfg(target_os = "haiku")]
- pub mod haiku;
- #[cfg(target_os = "illumos")]
- pub mod illumos;
- #[cfg(target_os = "ios")]
- pub mod ios;
- #[cfg(target_os = "l4re")]
- pub mod linux;
- #[cfg(target_os = "linux")]
- pub mod linux;
- #[cfg(target_os = "macos")]
- pub mod macos;
- #[cfg(target_os = "netbsd")]
- pub mod netbsd;
- #[cfg(target_os = "openbsd")]
- pub mod openbsd;
- #[cfg(target_os = "redox")]
- pub mod redox;
- #[cfg(target_os = "solaris")]
- pub mod solaris;
- #[cfg(unix)]
- pub mod unix;
+// unix
+#[cfg(not(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+)))]
+#[cfg(target_os = "hermit")]
+#[path = "hermit/mod.rs"]
+pub mod unix;
+#[cfg(not(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+)))]
+#[cfg(all(not(target_os = "hermit"), any(unix, doc)))]
+pub mod unix;
- #[cfg(target_os = "vxworks")]
- pub mod vxworks;
+// linux
+#[cfg(not(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+)))]
+#[cfg(any(target_os = "linux", target_os = "l4re", doc))]
+pub mod linux;
- #[cfg(target_os = "wasi")]
- pub mod wasi;
+// wasi
+#[cfg(not(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+)))]
+#[cfg(any(target_os = "wasi", doc))]
+pub mod wasi;
- #[cfg(windows)]
- pub mod windows;
-}
-#[cfg(not(doc))]
-#[stable(feature = "os", since = "1.0.0")]
-pub use imp::*;
+// windows
+#[cfg(not(all(
+ doc,
+ any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ all(target_vendor = "fortanix", target_env = "sgx")
+ )
+)))]
+#[cfg(any(windows, doc))]
+pub mod windows;
+
+// Others.
+#[cfg(target_os = "android")]
+pub mod android;
+#[cfg(target_os = "dragonfly")]
+pub mod dragonfly;
+#[cfg(target_os = "emscripten")]
+pub mod emscripten;
+#[cfg(target_os = "espidf")]
+pub mod espidf;
+#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
+pub mod fortanix_sgx;
+#[cfg(target_os = "freebsd")]
+pub mod freebsd;
+#[cfg(target_os = "fuchsia")]
+pub mod fuchsia;
+#[cfg(target_os = "haiku")]
+pub mod haiku;
+#[cfg(target_os = "illumos")]
+pub mod illumos;
+#[cfg(target_os = "ios")]
+pub mod ios;
+#[cfg(target_os = "macos")]
+pub mod macos;
+#[cfg(target_os = "netbsd")]
+pub mod netbsd;
+#[cfg(target_os = "openbsd")]
+pub mod openbsd;
+#[cfg(target_os = "redox")]
+pub mod redox;
+#[cfg(target_os = "solaris")]
+pub mod solaris;
+
+#[cfg(target_os = "vxworks")]
+pub mod vxworks;
#[cfg(any(unix, target_os = "wasi", doc))]
mod fd;
diff --git a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md
new file mode 100644
index 0000000000000..977d258529f8c
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md
@@ -0,0 +1,24 @@
+# `remap-cwd-prefix`
+
+The tracking issue for this feature is: [#87325](https://github.com/rust-lang/rust/issues/87325).
+
+------------------------
+
+This flag will rewrite absolute paths under the current working directory,
+replacing the current working directory prefix with a specified value.
+
+The given value may be absolute or relative, or empty. This switch takes
+precidence over `--remap-path-prefix` in case they would both match a given
+path.
+
+This flag helps to produce deterministic output, by removing the current working
+directory from build output, while allowing the command line to be universally
+reproducible, such that the same execution will work on all machines, regardless
+of build environment.
+
+## Example
+```sh
+# This would produce an absolute path to main.rs in build outputs of
+# "./main.rs".
+rustc -Z remap-cwd-prefix=. main.rs
+```
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index ece3ee640e2a6..3128d97922515 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -489,7 +489,7 @@ impl<'a> Classifier<'a> {
},
Some(c) => c,
},
- TokenKind::RawIdent | TokenKind::UnknownPrefix => {
+ TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => {
Class::Ident(self.new_span(before, text))
}
TokenKind::Lifetime { .. } => Class::Lifetime,
diff --git a/src/test/pretty/anonymous-types.rs b/src/test/pretty/anonymous-types.rs
deleted file mode 100644
index 5ff452e8e43c4..0000000000000
--- a/src/test/pretty/anonymous-types.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Test for issue 85480
-// Pretty print anonymous struct and union types
-
-// pp-exact
-// pretty-compare-only
-
-struct Foo {
- _: union {
- _: struct {
- a: u8,
- b: u16,
- },
- c: u32,
- },
- d: u64,
- e: f32,
-}
-
-type A =
- struct {
- field: u8,
- };
-
-fn main() { }
diff --git a/src/test/run-make-fulldeps/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile
index a17ec212cfd58..762cf5ed2ea71 100644
--- a/src/test/run-make-fulldeps/reproducible-build/Makefile
+++ b/src/test/run-make-fulldeps/reproducible-build/Makefile
@@ -10,6 +10,9 @@ all: \
link_paths \
remap_paths \
different_source_dirs \
+ remap_cwd_bin \
+ remap_cwd_rlib \
+ remap_cwd_to_empty \
extern_flags
smoke:
@@ -64,6 +67,45 @@ different_source_dirs:
--crate-type rlib)
cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
+remap_cwd_bin:
+ rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+ $(RUSTC) reproducible-build-aux.rs
+ mkdir $(TMPDIR)/test
+ cp reproducible-build.rs $(TMPDIR)/test
+ $(RUSTC) reproducible-build.rs --crate-type bin -C debuginfo=2 \
+ -Z remap-cwd-prefix=.
+ cp $(TMPDIR)/reproducible-build $(TMPDIR)/first
+ (cd $(TMPDIR)/test && \
+ $(RUSTC) reproducible-build.rs --crate-type bin -C debuginfo=2 \
+ -Z remap-cwd-prefix=.)
+ cmp "$(TMPDIR)/first" "$(TMPDIR)/reproducible-build" || exit 1
+
+remap_cwd_rlib:
+ rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+ $(RUSTC) reproducible-build-aux.rs
+ mkdir $(TMPDIR)/test
+ cp reproducible-build.rs $(TMPDIR)/test
+ $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+ -Z remap-cwd-prefix=.
+ cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfirst.rlib
+ (cd $(TMPDIR)/test && \
+ $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+ -Z remap-cwd-prefix=.)
+ cmp "$(TMPDIR)/libfirst.rlib" "$(TMPDIR)/libreproducible_build.rlib" || exit 1
+
+remap_cwd_to_empty:
+ rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+ $(RUSTC) reproducible-build-aux.rs
+ mkdir $(TMPDIR)/test
+ cp reproducible-build.rs $(TMPDIR)/test
+ $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+ -Z remap-cwd-prefix=
+ cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfirst.rlib
+ (cd $(TMPDIR)/test && \
+ $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+ -Z remap-cwd-prefix=)
+ cmp "$(TMPDIR)/libfirst.rlib" "$(TMPDIR)/libreproducible_build.rlib" || exit 1
+
extern_flags:
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
$(RUSTC) reproducible-build-aux.rs
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/feature-gates/feature-gate-unnamed_fields.rs b/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs
deleted file mode 100644
index bd815dbcc9242..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-struct Foo {
- foo: u8,
- _: union { //~ ERROR unnamed fields are not yet fully implemented [E0658]
- //~^ ERROR unnamed fields are not yet fully implemented [E0658]
- //~| ERROR anonymous unions are unimplemented
- bar: u8,
- baz: u16
- }
-}
-
-union Bar {
- foobar: u8,
- _: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658]
- //~^ ERROR unnamed fields are not yet fully implemented [E0658]
- //~| ERROR anonymous structs are unimplemented
- //~| ERROR unions may not contain fields that need dropping [E0740]
- foobaz: u8,
- barbaz: u16
- }
-}
-
-struct S;
-struct Baz {
- _: S //~ ERROR unnamed fields are not yet fully implemented [E0658]
-}
-
-fn main(){}
diff --git a/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr b/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr
deleted file mode 100644
index 4f3ab85c98792..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr
+++ /dev/null
@@ -1,111 +0,0 @@
-error[E0658]: unnamed fields are not yet fully implemented
- --> $DIR/feature-gate-unnamed_fields.rs:3:5
- |
-LL | _: union {
- | ^
- |
- = note: see issue #49804 for more information
- = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
- --> $DIR/feature-gate-unnamed_fields.rs:3:8
- |
-LL | _: union {
- | ________^
-LL | |
-LL | |
-LL | | bar: u8,
-LL | | baz: u16
-LL | | }
- | |_____^
- |
- = note: see issue #49804 for more information
- = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
- --> $DIR/feature-gate-unnamed_fields.rs:13:5
- |
-LL | _: struct {
- | ^
- |
- = note: see issue #49804 for more information
- = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
- --> $DIR/feature-gate-unnamed_fields.rs:13:8
- |
-LL | _: struct {
- | ________^
-LL | |
-LL | |
-LL | |
-LL | | foobaz: u8,
-LL | | barbaz: u16
-LL | | }
- | |_____^
- |
- = note: see issue #49804 for more information
- = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
- --> $DIR/feature-gate-unnamed_fields.rs:24:5
- |
-LL | _: S
- | ^
- |
- = note: see issue #49804 for more information
- = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error: anonymous unions are unimplemented
- --> $DIR/feature-gate-unnamed_fields.rs:3:8
- |
-LL | _: union {
- | ________^
-LL | |
-LL | |
-LL | | bar: u8,
-LL | | baz: u16
-LL | | }
- | |_____^
-
-error: anonymous structs are unimplemented
- --> $DIR/feature-gate-unnamed_fields.rs:13:8
- |
-LL | _: struct {
- | ________^
-LL | |
-LL | |
-LL | |
-LL | | foobaz: u8,
-LL | | barbaz: u16
-LL | | }
- | |_____^
-
-error[E0740]: unions may not contain fields that need dropping
- --> $DIR/feature-gate-unnamed_fields.rs:13:5
- |
-LL | / _: struct {
-LL | |
-LL | |
-LL | |
-LL | | foobaz: u8,
-LL | | barbaz: u16
-LL | | }
- | |_____^
- |
-note: `std::mem::ManuallyDrop` can be used to wrap the type
- --> $DIR/feature-gate-unnamed_fields.rs:13:5
- |
-LL | / _: struct {
-LL | |
-LL | |
-LL | |
-LL | | foobaz: u8,
-LL | | barbaz: u16
-LL | | }
- | |_____^
-
-error: aborting due to 8 previous errors
-
-Some errors have detailed explanations: E0658, E0740.
-For more information about an error, try `rustc --explain E0658`.
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/parser/emoji-identifiers.rs b/src/test/ui/parser/emoji-identifiers.rs
new file mode 100644
index 0000000000000..ef18939bbb80c
--- /dev/null
+++ b/src/test/ui/parser/emoji-identifiers.rs
@@ -0,0 +1,16 @@
+struct ABig๐ฉโ๐ฉโ๐งโ๐งFamily; //~ ERROR identifiers cannot contain emoji
+struct ๐; //~ ERROR identifiers cannot contain emoji
+impl ๐ {
+ fn full_of_โจ() -> ๐ { //~ ERROR identifiers cannot contain emoji
+ ๐
+ }
+}
+fn i_like_to_๐
_a_lot() -> ๐ { //~ ERROR identifiers cannot contain emoji
+ ๐::full_ofโจ() //~ ERROR no function or associated item named `full_ofโจ` found for struct `๐`
+ //~^ ERROR identifiers cannot contain emoji
+}
+fn main() {
+ let _ = i_like_to_๐_a_lot() โ 4; //~ ERROR cannot find function `i_like_to_๐_a_lot` in this scope
+ //~^ ERROR identifiers cannot contain emoji
+ //~| ERROR unknown start of token: \u{2796}
+}
diff --git a/src/test/ui/parser/emoji-identifiers.stderr b/src/test/ui/parser/emoji-identifiers.stderr
new file mode 100644
index 0000000000000..5f9263c4c13e7
--- /dev/null
+++ b/src/test/ui/parser/emoji-identifiers.stderr
@@ -0,0 +1,83 @@
+error: unknown start of token: \u{2796}
+ --> $DIR/emoji-identifiers.rs:13:33
+ |
+LL | let _ = i_like_to_๐_a_lot() โ 4;
+ | ^^
+ |
+help: Unicode character 'โ' (Heavy Minus Sign) looks like '-' (Minus/Hyphen), but it is not
+ |
+LL | let _ = i_like_to_๐_a_lot() - 4;
+ | ~
+
+error[E0425]: cannot find function `i_like_to_๐_a_lot` in this scope
+ --> $DIR/emoji-identifiers.rs:13:13
+ |
+LL | fn i_like_to_๐
_a_lot() -> ๐ {
+ | ----------------------------- similarly named function `i_like_to_๐
_a_lot` defined here
+...
+LL | let _ = i_like_to_๐_a_lot() โ 4;
+ | ^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `i_like_to_๐
_a_lot`
+
+error: identifiers cannot contain emoji: `ABig๐ฉ๐ฉ๐ง๐งFamily`
+ --> $DIR/emoji-identifiers.rs:1:8
+ |
+LL | struct ABig๐ฉ๐ฉ๐ง๐งFamily;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: identifiers cannot contain emoji: `๐`
+ --> $DIR/emoji-identifiers.rs:2:8
+ |
+LL | struct ๐;
+ | ^^
+LL | impl ๐ {
+ | ^^
+LL | fn full_of_โจ() -> ๐ {
+ | ^^
+LL | ๐
+ | ^^
+...
+LL | fn i_like_to_๐
_a_lot() -> ๐ {
+ | ^^
+LL | ๐::full_ofโจ()
+ | ^^
+
+error: identifiers cannot contain emoji: `full_of_โจ`
+ --> $DIR/emoji-identifiers.rs:4:8
+ |
+LL | fn full_of_โจ() -> ๐ {
+ | ^^^^^^^^^^
+
+error: identifiers cannot contain emoji: `i_like_to_๐
_a_lot`
+ --> $DIR/emoji-identifiers.rs:8:4
+ |
+LL | fn i_like_to_๐
_a_lot() -> ๐ {
+ | ^^^^^^^^^^^^^^^^^^
+
+error: identifiers cannot contain emoji: `full_ofโจ`
+ --> $DIR/emoji-identifiers.rs:9:8
+ |
+LL | ๐::full_ofโจ()
+ | ^^^^^^^^^
+
+error: identifiers cannot contain emoji: `i_like_to_๐_a_lot`
+ --> $DIR/emoji-identifiers.rs:13:13
+ |
+LL | let _ = i_like_to_๐_a_lot() โ 4;
+ | ^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no function or associated item named `full_ofโจ` found for struct `๐` in the current scope
+ --> $DIR/emoji-identifiers.rs:9:8
+ |
+LL | struct ๐;
+ | ---------- function or associated item `full_ofโจ` not found for this
+...
+LL | ๐::full_ofโจ()
+ | ^^^^^^^^^
+ | |
+ | function or associated item not found in `๐`
+ | help: there is an associated function with a similar name: `full_of_โจ`
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0425, E0599.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/issue-88583-union-as-ident.rs b/src/test/ui/parser/issue-88583-union-as-ident.rs
new file mode 100644
index 0000000000000..b3d66d46b1d4b
--- /dev/null
+++ b/src/test/ui/parser/issue-88583-union-as-ident.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![allow(non_camel_case_types)]
+
+struct union;
+
+impl union {
+ pub fn new() -> Self {
+ union { }
+ }
+}
+
+fn main() {
+ let _u = union::new();
+}
diff --git a/src/test/ui/parser/macro-braces-dot-question.rs b/src/test/ui/parser/macro-braces-dot-question.rs
new file mode 100644
index 0000000000000..016b434a6124a
--- /dev/null
+++ b/src/test/ui/parser/macro-braces-dot-question.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+use std::io::Write;
+
+fn main() -> Result<(), std::io::Error> {
+ vec! { 1, 2, 3 }.len();
+ write! { vec![], "" }?;
+ println!{""}
+ [0]; // separate statement, not indexing into the result of println.
+ Ok(())
+}
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/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
index 74237e6e6c638..03381415e7dc2 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
@@ -22,6 +22,10 @@ LL | fn foo() where Self: Other, { }
| ^^^ ...because associated function `foo` has no `self` parameter
LL | fn bar(self: ()) {}
| ^^ ...because method `bar`'s `self` parameter cannot be dispatched on
+help: consider changing method `bar`'s `self` parameter to be `&self`
+ |
+LL | fn bar(self: &Self) {}
+ | ~~~~~
help: consider turning `foo` into a method by giving it a `&self` argument
|
LL | fn foo(&self) where Self: Other, { }
@@ -30,10 +34,6 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
|
LL | fn foo() where Self: Other, Self: Sized, { }
| +++++++++++++
-help: consider changing method `bar`'s `self` parameter to be `&self`
- |
-LL | fn bar(self: &Self) {}
- | ~~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/item-privacy.stderr b/src/test/ui/traits/item-privacy.stderr
index 2260dcfc70ea3..81982363b2b85 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 `B` to another trait
+ = help: consider moving `A` to another trait
+ = help: consider moving `C` 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/typeck/issue-88803-call-expr-method.fixed b/src/test/ui/typeck/issue-88803-call-expr-method.fixed
new file mode 100644
index 0000000000000..19b96ecf3fc3a
--- /dev/null
+++ b/src/test/ui/typeck/issue-88803-call-expr-method.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+ let a = Some(42);
+ println!(
+ "The value is {}.",
+ a.unwrap() //~ERROR [E0615]
+ );
+}
diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.rs b/src/test/ui/typeck/issue-88803-call-expr-method.rs
new file mode 100644
index 0000000000000..a061994663749
--- /dev/null
+++ b/src/test/ui/typeck/issue-88803-call-expr-method.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+ let a = Some(42);
+ println!(
+ "The value is {}.",
+ (a.unwrap)() //~ERROR [E0615]
+ );
+}
diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.stderr b/src/test/ui/typeck/issue-88803-call-expr-method.stderr
new file mode 100644
index 0000000000000..dd717ed9416d3
--- /dev/null
+++ b/src/test/ui/typeck/issue-88803-call-expr-method.stderr
@@ -0,0 +1,15 @@
+error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>`
+ --> $DIR/issue-88803-call-expr-method.rs:7:12
+ |
+LL | (a.unwrap)()
+ | ^^^^^^ method, not a field
+ |
+help: remove wrapping parentheses to call the method
+ |
+LL - (a.unwrap)()
+LL + a.unwrap()
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0615`.
diff --git a/src/test/ui/unnamed_fields/restrict_anonymous.rs b/src/test/ui/unnamed_fields/restrict_anonymous.rs
deleted file mode 100644
index 99637d1105301..0000000000000
--- a/src/test/ui/unnamed_fields/restrict_anonymous.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(unnamed_fields)]
-
-fn f() -> struct { field: u8 } {} //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous structs are unimplemented
-
-fn f2(a: struct { field: u8 } ) {} //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous structs are unimplemented
-
-union G {
- field: struct { field: u8 } //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous structs are unimplemented
-}
-//~| ERROR unions may not contain fields that need dropping [E0740]
-
-struct H { _: u8 } // Should error after hir checks
-
-struct I(struct { field: u8 }, u8); //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous structs are unimplemented
-
-enum J {
- K(struct { field: u8 }), //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous structs are unimplemented
- L {
- _ : struct { field: u8 } //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous fields are not allowed outside of structs or unions
- //~| ERROR anonymous structs are unimplemented
- },
- M {
- _ : u8 //~ ERROR anonymous fields are not allowed outside of structs or unions
- }
-}
-
-static M: union { field: u8 } = 0; //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous unions are unimplemented
-
-type N = union { field: u8 }; //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous unions are unimplemented
-
-fn main() {
- const O: struct { field: u8 } = 0; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous structs are unimplemented
-
- let p: [struct { field: u8 }; 1]; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous structs are unimplemented
-
- let q: (struct { field: u8 }, u8); //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous structs are unimplemented
-
- let cl = || -> struct { field: u8 } {}; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
- //~^ ERROR anonymous structs are unimplemented
-}
diff --git a/src/test/ui/unnamed_fields/restrict_anonymous.stderr b/src/test/ui/unnamed_fields/restrict_anonymous.stderr
deleted file mode 100644
index efcf544fde4dc..0000000000000
--- a/src/test/ui/unnamed_fields/restrict_anonymous.stderr
+++ /dev/null
@@ -1,175 +0,0 @@
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:4:11
- |
-LL | fn f() -> struct { field: u8 } {}
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:7:10
- |
-LL | fn f2(a: struct { field: u8 } ) {}
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:11:12
- |
-LL | field: struct { field: u8 }
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:18:10
- |
-LL | struct I(struct { field: u8 }, u8);
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:22:7
- |
-LL | K(struct { field: u8 }),
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous fields are not allowed outside of structs or unions
- --> $DIR/restrict_anonymous.rs:25:9
- |
-LL | _ : struct { field: u8 }
- | -^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | anonymous field declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:25:13
- |
-LL | _ : struct { field: u8 }
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous fields are not allowed outside of structs or unions
- --> $DIR/restrict_anonymous.rs:30:9
- |
-LL | _ : u8
- | -^^^^^
- | |
- | anonymous field declared here
-
-error: anonymous unions are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:34:11
- |
-LL | static M: union { field: u8 } = 0;
- | ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
-
-error: anonymous unions are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:37:10
- |
-LL | type N = union { field: u8 };
- | ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:41:14
- |
-LL | const O: struct { field: u8 } = 0;
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:44:13
- |
-LL | let p: [struct { field: u8 }; 1];
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:47:13
- |
-LL | let q: (struct { field: u8 }, u8);
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
- --> $DIR/restrict_anonymous.rs:50:20
- |
-LL | let cl = || -> struct { field: u8 } {};
- | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:4:11
- |
-LL | fn f() -> struct { field: u8 } {}
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:7:10
- |
-LL | fn f2(a: struct { field: u8 } ) {}
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:11:12
- |
-LL | field: struct { field: u8 }
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:18:10
- |
-LL | struct I(struct { field: u8 }, u8);
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:22:7
- |
-LL | K(struct { field: u8 }),
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:25:13
- |
-LL | _ : struct { field: u8 }
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous unions are unimplemented
- --> $DIR/restrict_anonymous.rs:34:11
- |
-LL | static M: union { field: u8 } = 0;
- | ^^^^^^^^^^^^^^^^^^^
-
-error: anonymous unions are unimplemented
- --> $DIR/restrict_anonymous.rs:37:10
- |
-LL | type N = union { field: u8 };
- | ^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:44:13
- |
-LL | let p: [struct { field: u8 }; 1];
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:47:13
- |
-LL | let q: (struct { field: u8 }, u8);
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:50:20
- |
-LL | let cl = || -> struct { field: u8 } {};
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
- --> $DIR/restrict_anonymous.rs:41:14
- |
-LL | const O: struct { field: u8 } = 0;
- | ^^^^^^^^^^^^^^^^^^^^
-
-error[E0740]: unions may not contain fields that need dropping
- --> $DIR/restrict_anonymous.rs:11:5
- |
-LL | field: struct { field: u8 }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: `std::mem::ManuallyDrop` can be used to wrap the type
- --> $DIR/restrict_anonymous.rs:11:5
- |
-LL | field: struct { field: u8 }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 27 previous errors
-
-For more information about this error, try `rustc --explain E0740`.
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
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index d7e46c2d3eb9d..80be4350c3c1a 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -104,7 +104,7 @@ pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWri
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];
-pub const PERMISSIONS_FROM_MODE: [&str; 7] = ["std", "os", "imp", "unix", "fs", "PermissionsExt", "from_mode"];
+pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 2483d0570d9ea..14041539b9dfd 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -6,7 +6,7 @@ use std::cmp::{max, min, Ordering};
use regex::Regex;
use rustc_ast::visit;
use rustc_ast::{ast, ptr};
-use rustc_span::{symbol, BytePos, Span};
+use rustc_span::{symbol, BytePos, Span, DUMMY_SP};
use crate::attr::filter_inline_attrs;
use crate::comment::{
@@ -31,7 +31,12 @@ use crate::stmt::Stmt;
use crate::utils::*;
use crate::vertical::rewrite_with_alignment;
use crate::visitor::FmtVisitor;
-use crate::DEFAULT_VISIBILITY;
+
+const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility {
+ kind: ast::VisibilityKind::Inherited,
+ span: DUMMY_SP,
+ tokens: None,
+};
fn type_annotation_separator(config: &Config) -> &str {
colon_spaces(config)
@@ -972,7 +977,7 @@ impl<'a> StructParts<'a> {
format_header(context, self.prefix, self.ident, self.vis, offset)
}
- pub(crate) fn from_variant(variant: &'a ast::Variant) -> Self {
+ fn from_variant(variant: &'a ast::Variant) -> Self {
StructParts {
prefix: "",
ident: variant.ident,
diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs
index 206d2f782909c..47a7b9d4dbe3c 100644
--- a/src/tools/rustfmt/src/lib.rs
+++ b/src/tools/rustfmt/src/lib.rs
@@ -32,7 +32,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use rustc_ast::ast;
-use rustc_span::{symbol, DUMMY_SP};
+use rustc_span::symbol;
use thiserror::Error;
use crate::comment::LineClasses;
@@ -96,11 +96,6 @@ mod types;
mod vertical;
pub(crate) mod visitor;
-const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility {
- kind: ast::VisibilityKind::Inherited,
- span: DUMMY_SP,
- tokens: None,
-};
/// The various errors that can occur during formatting. Note that not all of
/// these can currently be propagated to clients.
#[derive(Error, Debug)]
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 640d127e86098..76bf58e875b1f 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -1,15 +1,15 @@
use std::iter::ExactSizeIterator;
use std::ops::Deref;
-use rustc_ast::ast::{self, AttrVec, FnRetTy, Mutability};
-use rustc_span::{symbol::kw, symbol::Ident, BytePos, Pos, Span};
+use rustc_ast::ast::{self, FnRetTy, Mutability};
+use rustc_span::{symbol::kw, BytePos, Pos, Span};
+use crate::comment::{combine_strs_with_missing_comments, contains_comment};
use crate::config::lists::*;
use crate::config::{IndentStyle, TypeDensity, Version};
use crate::expr::{
format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, rewrite_unary_prefix, ExprType,
};
-use crate::items::StructParts;
use crate::lists::{
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
};
@@ -24,11 +24,6 @@ use crate::utils::{
colon_spaces, extra_offset, first_line_width, format_extern, format_mutability,
last_line_extendable, last_line_width, mk_sp, rewrite_ident,
};
-use crate::DEFAULT_VISIBILITY;
-use crate::{
- comment::{combine_strs_with_missing_comments, contains_comment},
- items::format_struct_struct,
-};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum PathContext {
@@ -769,54 +764,6 @@ impl Rewrite for ast::Ty {
ast::TyKind::Tup(ref items) => {
rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
}
- ast::TyKind::AnonymousStruct(ref fields, recovered) => {
- let ident = Ident::new(
- kw::Struct,
- mk_sp(self.span.lo(), self.span.lo() + BytePos(6)),
- );
- let data = ast::VariantData::Struct(fields.clone(), recovered);
- let variant = ast::Variant {
- attrs: AttrVec::new(),
- id: self.id,
- span: self.span,
- vis: DEFAULT_VISIBILITY,
- ident,
- data,
- disr_expr: None,
- is_placeholder: false,
- };
- format_struct_struct(
- &context,
- &StructParts::from_variant(&variant),
- fields,
- shape.indent,
- None,
- )
- }
- ast::TyKind::AnonymousUnion(ref fields, recovered) => {
- let ident = Ident::new(
- kw::Union,
- mk_sp(self.span.lo(), self.span.lo() + BytePos(5)),
- );
- let data = ast::VariantData::Struct(fields.clone(), recovered);
- let variant = ast::Variant {
- attrs: AttrVec::new(),
- id: self.id,
- span: self.span,
- vis: DEFAULT_VISIBILITY,
- ident,
- data,
- disr_expr: None,
- is_placeholder: false,
- };
- format_struct_struct(
- &context,
- &StructParts::from_variant(&variant),
- fields,
- shape.indent,
- None,
- )
- }
ast::TyKind::Path(ref q_self, ref path) => {
rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape)
}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 5f1267fc3d250..30438ccc9385e 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -82,8 +82,8 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"bitflags",
"block-buffer",
"block-padding",
- "byteorder",
"byte-tools",
+ "byteorder",
"cc",
"cfg-if",
"chalk-derive",
@@ -140,9 +140,9 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"memmap2",
"memoffset",
"miniz_oxide",
- "num_cpus",
"num-integer",
"num-traits",
+ "num_cpus",
"object",
"once_cell",
"opaque-debug",
@@ -188,8 +188,8 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"serde_json",
"sha-1",
"sha2",
- "smallvec",
"sharded-slab",
+ "smallvec",
"snap",
"stable_deref_trait",
"stacker",
@@ -209,6 +209,11 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"tracing-subscriber",
"tracing-tree",
"typenum",
+ "unic-char-property",
+ "unic-char-range",
+ "unic-common",
+ "unic-emoji-char",
+ "unic-ucd-version",
"unicode-normalization",
"unicode-script",
"unicode-security",