From 3caf0bcdeb9546bd8a3ab58c0e33baabdcaac75a Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 6 Sep 2021 18:12:55 +0200 Subject: [PATCH 01/23] Accept `m!{ .. }.method()` and `m!{ .. }?` statements. --- compiler/rustc_parse/src/parser/stmt.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 068bd36af5524..f1a91c41355ee 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)) } From ebf12529dfa62cf463de4fd5e1355e8ea4fe0559 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 6 Sep 2021 18:17:46 +0200 Subject: [PATCH 02/23] Add test for braced-macro followed by `.` or `?`. --- src/test/ui/parser/macro-braces-dot-question.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/ui/parser/macro-braces-dot-question.rs 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..05de5a845e958 --- /dev/null +++ b/src/test/ui/parser/macro-braces-dot-question.rs @@ -0,0 +1,9 @@ +// check-pass + +use std::io::Write; + +fn main() -> Result<(), std::io::Error> { + vec! { 1, 2, 3 }.len(); + write! { vec![], "" }?; + Ok(()) +} From ce35f8ec56ec7e89d351cd95001f4d819c97e07d Mon Sep 17 00:00:00 2001 From: danakj Date: Thu, 22 Jul 2021 14:52:45 -0400 Subject: [PATCH 03/23] remap-cwd-prefix --- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/config.rs | 15 +++++-- compiler/rustc_session/src/options.rs | 2 + src/doc/rustc/src/command-line-arguments.md | 13 ++++++ .../reproducible-build/Makefile | 42 +++++++++++++++++++ 5 files changed, 70 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index afab919bc3c2c..94166715f74f3 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -753,6 +753,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_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 9a1be40558ccb..293cf1d0ba365 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1236,6 +1236,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/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 7f482f0f2b1a0..f38b4ca744f74 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -345,6 +345,19 @@ replacement is purely textual, with no consideration of the current system's pathname syntax. For example `--remap-path-prefix foo=bar` will match `foo/lib.rs` but not `./foo/lib.rs`. + +## `--remap-cwd-prefix`: remap paths under the cwd in output + +Remap all absolute paths that are rooted under the current working directory to +be under the given value instead. 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 allows the command line to be universally reproducible, such that the +same execution will work on all machines, regardless of build environment. + +This is an unstable option. Use `-Z remap-cwd-prefix=val` to specify a value. + ## `--json`: configure json messages printed by the compiler 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 From 2a687deee872917b09519519290521fa8dd472b7 Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 7 Sep 2021 15:38:29 -0400 Subject: [PATCH 04/23] Move documentation to the unstable book --- src/doc/rustc/src/command-line-arguments.md | 13 ---------- .../src/compiler-flags/remap-cwd-prefix.md | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index f38b4ca744f74..7f482f0f2b1a0 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -345,19 +345,6 @@ replacement is purely textual, with no consideration of the current system's pathname syntax. For example `--remap-path-prefix foo=bar` will match `foo/lib.rs` but not `./foo/lib.rs`. - -## `--remap-cwd-prefix`: remap paths under the cwd in output - -Remap all absolute paths that are rooted under the current working directory to -be under the given value instead. 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 allows the command line to be universally reproducible, such that the -same execution will work on all machines, regardless of build environment. - -This is an unstable option. Use `-Z remap-cwd-prefix=val` to specify a value. - ## `--json`: configure json messages printed by the compiler 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 +``` From 2691a399762149f2c8dd5c3ffc44244b98c37099 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 13:40:32 -0400 Subject: [PATCH 05/23] Revert "Allow formatting `Anonymous{Struct, Union}` declarations" This reverts commit 64acb7d92135ae722dfce89f0ca9d7cf6576de66. --- src/tools/rustfmt/src/items.rs | 11 +++++-- src/tools/rustfmt/src/lib.rs | 7 +--- src/tools/rustfmt/src/types.rs | 59 ++-------------------------------- 3 files changed, 12 insertions(+), 65 deletions(-) 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) } From 2041fb1a2dc06237ffb63eff8fcfaa93abf67952 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:52:43 -0400 Subject: [PATCH 06/23] Revert "Add test for pretty printing anonymous types" This reverts commit d59b1f1ef4be692b67c1ff1b49ec810fd59452cf. --- src/test/pretty/anonymous-types.rs | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/test/pretty/anonymous-types.rs 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() { } From 5560f6d90a6a15fdb52a30f97d28b439b72f6cf3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:52:49 -0400 Subject: [PATCH 07/23] Revert "Fix ast expanded printing for anonymous types" This reverts commit 5b4bc05fa57be19bb5962f4b7c0f165e194e3151. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3cf04be160c64..bb00e20d699c1 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -986,12 +986,12 @@ impl<'a> State<'a> { self.pclose(); } ast::TyKind::AnonymousStruct(ref fields, ..) => { - self.head("struct"); - self.print_record_struct_body(&fields, ty.span); + self.s.word("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); + self.s.word("union"); + self.print_record_struct_body(fields, ty.span); } ast::TyKind::Paren(ref typ) => { self.popen(); @@ -1413,7 +1413,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 +1467,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); } } From f38ec9ca34c501b2a618178a14fe2a3c9979ddc9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 13:41:46 -0400 Subject: [PATCH 08/23] Revert "Add test for restriction of anonymous types on validation" This reverts commit 8a1dd6918bb686a960ad5ced46a16b5b59668464. --- .../ui/unnamed_fields/restrict_anonymous.rs | 52 ------ .../unnamed_fields/restrict_anonymous.stderr | 175 ------------------ 2 files changed, 227 deletions(-) delete mode 100644 src/test/ui/unnamed_fields/restrict_anonymous.rs delete mode 100644 src/test/ui/unnamed_fields/restrict_anonymous.stderr 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`. From b6aa7e3105a76d1dcb0c4d0e475657056a3885c5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 13:48:42 -0400 Subject: [PATCH 09/23] Manually crafted revert of d4ad050ce5778a09566f6f9ec172565815d54604 . --- .../rustc_ast_passes/src/ast_validation.rs | 68 ------------------- 1 file changed, 68 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index aca4503903c06..07f721d2d840a 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 { @@ -1067,7 +1001,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) } @@ -1082,7 +1015,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) } From 91feb76d133952825e3eb32bed399ec6e4bd9219 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:03:40 -0400 Subject: [PATCH 10/23] Revert "Implement Anonymous{Struct, Union} in the AST" This reverts commit 059b68dd677808e14e560802d235ad40beeba71e. Note that this was manually adjusted to retain some of the refactoring introduced by commit 059b68dd677808e14e560802d235ad40beeba71e, so that it could likewise retain the correction introduced in commit 5b4bc05fa57be19bb5962f4b7c0f165e194e3151 --- compiler/rustc_ast/src/ast.rs | 4 - compiler/rustc_ast/src/mut_visit.rs | 3 - compiler/rustc_ast/src/visit.rs | 3 - compiler/rustc_ast_lowering/src/item.rs | 5 +- compiler/rustc_ast_lowering/src/lib.rs | 9 -- compiler/rustc_ast_passes/src/feature_gate.rs | 1 - compiler/rustc_ast_pretty/src/pprust/state.rs | 8 -- compiler/rustc_feature/src/active.rs | 3 - compiler/rustc_parse/src/parser/item.rs | 35 ++---- compiler/rustc_parse/src/parser/ty.rs | 13 -- compiler/rustc_span/src/symbol.rs | 1 - .../feature-gate-unnamed_fields.rs | 27 ----- .../feature-gate-unnamed_fields.stderr | 111 ------------------ 13 files changed, 14 insertions(+), 209 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-unnamed_fields.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr 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 fa14764c42a73..6a387d62c90c4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1289,15 +1289,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/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 bb00e20d699c1..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.s.word("struct"); - self.print_record_struct_body(fields, ty.span); - } - ast::TyKind::AnonymousUnion(ref fields, ..) => { - self.s.word("union"); - self.print_record_struct_body(fields, ty.span); - } ast::TyKind::Paren(ref typ) => { self.popen(); self.print_type(typ); diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index a3807a2bb9fde..d409746584274 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -639,9 +639,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_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 10c73fd64bc19..29e20f2747f1b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1234,7 +1234,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)> { @@ -1468,28 +1468,19 @@ 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) { + let _ = self.parse_fn(&mut Vec::new(), |_| true, lo); + 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/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_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 24023163cc30e..675c5108720bb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1358,7 +1358,6 @@ symbols! { unix, unlikely, unmarked_api, - unnamed_fields, unpin, unreachable, unreachable_code, 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`. From f26f1ed9a7208c0d928f0413cdd5f0966fa2c399 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:48:12 -0400 Subject: [PATCH 11/23] Re-add 71a7f8f1884b2c83eeb4a545eef16df1f2ea6476 post-revert. --- compiler/rustc_parse/src/parser/item.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 29e20f2747f1b..c5b961f12b2ab 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1469,7 +1469,10 @@ impl<'a> Parser<'a> { let (ident, is_raw) = self.ident_or_err()?; if !is_raw && ident.is_reserved() { let err = if self.check_fn_front_matter(false) { - let _ = self.parse_fn(&mut Vec::new(), |_| true, lo); + // 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), From 35370a7ba3d52bfe2a6121a0eaccbc240ed9559d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 9 Sep 2021 09:31:56 -0400 Subject: [PATCH 12/23] regression test for issue #88583. --- src/test/ui/parser/issue-88583-union-as-ident.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/parser/issue-88583-union-as-ident.rs 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(); +} From 5dab3c5cf5383b1866b374d74305196b72a0b593 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 10 Sep 2021 18:16:58 -0700 Subject: [PATCH 13/23] feat(rustc_typeck): suggest removing bad parens in `(recv.method)()` Fixes #88803 --- compiler/rustc_typeck/src/check/expr.rs | 18 +++++++++++++++++- .../ui/typeck/issue-88803-call-expr-method.rs | 7 +++++++ .../typeck/issue-88803-call-expr-method.stderr | 12 ++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/typeck/issue-88803-call-expr-method.rs create mode 100644 src/test/ui/typeck/issue-88803-call-expr-method.stderr diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d578fac4cdb22..8513659344018 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1842,7 +1842,23 @@ 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(parent_expr) = + self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id)) + { + matches!(parent_expr.kind, ExprKind::Call(..)) + } 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(")") { + err.span_suggestion_short( + expr.span, + "remove wrapping parentheses to call the method", + expr_snippet[1..expr_snippet.len() - 1].to_owned(), + 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/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..fba233eec9b00 --- /dev/null +++ b/src/test/ui/typeck/issue-88803-call-expr-method.rs @@ -0,0 +1,7 @@ +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..9383848db941f --- /dev/null +++ b/src/test/ui/typeck/issue-88803-call-expr-method.stderr @@ -0,0 +1,12 @@ +error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>` + --> $DIR/issue-88803-call-expr-method.rs:5:12 + | +LL | (a.unwrap)() + | ---^^^^^^- + | | | + | | method, not a field + | help: remove wrapping parentheses to call the method + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0615`. From e5c2412e52019ef35f9c6b3524cd5caf972e26b7 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 10 Sep 2021 18:34:51 -0700 Subject: [PATCH 14/23] Add the corrections stuff to the 88803 test case --- src/test/ui/typeck/issue-88803-call-expr-method.fixed | 9 +++++++++ src/test/ui/typeck/issue-88803-call-expr-method.rs | 2 ++ src/test/ui/typeck/issue-88803-call-expr-method.stderr | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/typeck/issue-88803-call-expr-method.fixed 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 index fba233eec9b00..a061994663749 100644 --- a/src/test/ui/typeck/issue-88803-call-expr-method.rs +++ b/src/test/ui/typeck/issue-88803-call-expr-method.rs @@ -1,3 +1,5 @@ +// run-rustfix + fn main() { let a = Some(42); println!( diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.stderr b/src/test/ui/typeck/issue-88803-call-expr-method.stderr index 9383848db941f..4b7ea95dee2a7 100644 --- a/src/test/ui/typeck/issue-88803-call-expr-method.stderr +++ b/src/test/ui/typeck/issue-88803-call-expr-method.stderr @@ -1,5 +1,5 @@ error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>` - --> $DIR/issue-88803-call-expr-method.rs:5:12 + --> $DIR/issue-88803-call-expr-method.rs:7:12 | LL | (a.unwrap)() | ---^^^^^^- From d98892b67f9b1f04c8c3c90cd99cd24738fd30ba Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 10 Sep 2021 18:48:25 -0700 Subject: [PATCH 15/23] Make sure the call span parens check only fires on the callee, not args --- compiler/rustc_typeck/src/check/expr.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 8513659344018..61d5b6985f1bf 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1842,13 +1842,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_t ); err.span_label(field.span, "method, not a field"); - let expr_is_call = if let hir::Node::Expr(parent_expr) = - self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id)) - { - matches!(parent_expr.kind, ExprKind::Call(..)) - } else { - false - }; + 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(")") { From 8be729cdd6473859f4fb54aaf74dce56f0775ef1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 12 Sep 2021 19:51:09 -0700 Subject: [PATCH 16/23] chore: convert to a multi-part suggestion --- compiler/rustc_typeck/src/check/expr.rs | 10 +++++++--- .../ui/typeck/issue-88803-call-expr-method.stderr | 11 +++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 61d5b6985f1bf..f4e3c8e0d9f7f 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1853,10 +1853,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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(")") { - err.span_suggestion_short( - expr.span, + 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", - expr_snippet[1..expr_snippet.len() - 1].to_owned(), + 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) { diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.stderr b/src/test/ui/typeck/issue-88803-call-expr-method.stderr index 4b7ea95dee2a7..dd717ed9416d3 100644 --- a/src/test/ui/typeck/issue-88803-call-expr-method.stderr +++ b/src/test/ui/typeck/issue-88803-call-expr-method.stderr @@ -2,10 +2,13 @@ error[E0615]: attempted to take value of method `unwrap` on type `Option<{intege --> $DIR/issue-88803-call-expr-method.rs:7:12 | LL | (a.unwrap)() - | ---^^^^^^- - | | | - | | method, not a field - | help: remove wrapping parentheses to call the method + | ^^^^^^ method, not a field + | +help: remove wrapping parentheses to call the method + | +LL - (a.unwrap)() +LL + a.unwrap() + | error: aborting due to previous error From 6ec7255d7b9c96c4cc0feafec6f26a2a9db3b7aa Mon Sep 17 00:00:00 2001 From: Waffle Date: Mon, 13 Sep 2021 16:36:14 +0300 Subject: [PATCH 17/23] Highlight the const function if error happened because of a bound on the impl block Currently, for the following code, the compiler produces the errors like the following error: ```rust struct Type impl Type { fn const f() {} } ``` ```text error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable --> ./test.rs:3:6 | 3 | impl Type { | ^ | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable ``` This can be confusing (especially to newcomers) since the error mentions "const fn parameters", but highlights only the impl. This commits adds function highlighting, changing the error to the following: ```text error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable --> ./test.rs:3:6 | 3 | impl Type { | ^ 4 | pub const fn f() {} | ---------------- function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable ``` --- .../src/transform/check_consts/ops.rs | 13 ++++++++++-- .../consts/min_const_fn/min_const_fn.stderr | 21 ++++++++++++++++--- .../min_const_fn/min_const_fn_dyn.stderr | 6 +++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 8923d989b2944..2a29675083888 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -599,12 +599,21 @@ pub mod ty { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - feature_err( + let mut builder = feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_trait_bound, span, "trait bounds other than `Sized` on const fn parameters are unstable", - ) + ); + + match ccx.fn_sig() { + Some(fn_sig) if !fn_sig.span.contains(span) => { + builder.span_label(fn_sig.span, "function declared as const here"); + } + _ => {} + } + + builder } } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index fcbf39d38690b..d1c2a04d6a61b 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -214,6 +214,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl | LL | impl Foo { | ^ +LL | +LL | const fn foo(&self) {} + | ------------------- function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable @@ -223,6 +226,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl | LL | impl Foo { | ^ +LL | +LL | const fn foo2(&self) {} + | -------------------- function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable @@ -232,6 +238,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl | LL | impl Foo { | ^ +LL | +LL | const fn foo3(&self) {} + | -------------------- function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable @@ -292,7 +301,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl --> $DIR/min_const_fn.rs:139:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable @@ -301,7 +312,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl --> $DIR/min_const_fn.rs:139:42 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable @@ -310,7 +323,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl --> $DIR/min_const_fn.rs:139:42 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr index ce844a2f07164..2cad8a862be4c 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr @@ -1,6 +1,8 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn_dyn.rs:9:5 | +LL | const fn no_inner_dyn_trait2(x: Hide) { + | ------------------------------------- function declared as const here LL | x.0.field; | ^^^^^^^^^ | @@ -11,7 +13,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl --> $DIR/min_const_fn_dyn.rs:12:66 | LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } - | ^^ + | ----------------------------------------- ^^ + | | + | function declared as const here | = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable From 7d8d7a03412f6db1402f2713ee96a2040cfb24d2 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 13 Sep 2021 17:50:59 +0200 Subject: [PATCH 18/23] Add negative test in macro-braces-dot-question.rs. --- src/test/ui/parser/macro-braces-dot-question.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/parser/macro-braces-dot-question.rs b/src/test/ui/parser/macro-braces-dot-question.rs index 05de5a845e958..016b434a6124a 100644 --- a/src/test/ui/parser/macro-braces-dot-question.rs +++ b/src/test/ui/parser/macro-braces-dot-question.rs @@ -5,5 +5,7 @@ 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(()) } From 1053a5bb0ff9f781cc1fa0385ce699fe49ee2ad2 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Mon, 13 Sep 2021 12:39:45 -0700 Subject: [PATCH 19/23] `Wrapping` has the same layout and ABI as `T` --- library/core/src/num/wrapping.rs | 4 ++++ 1 file changed, 4 insertions(+) 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)] From f9b8191282da80fff41f496d4b2e8e4dcd3502ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 14 Sep 2021 00:00:00 +0000 Subject: [PATCH 20/23] Remove implementation of `min_align_of` intrinsic Since 88839 `min_align_of` is lowered to AlignOf operator. --- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) 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)?; From a3115b3d450d87e4cc9226ab4e7db2ddde640f48 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 14 Sep 2021 17:57:07 -0700 Subject: [PATCH 21/23] Update books --- src/doc/embedded-book | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/embedded-book b/src/doc/embedded-book index c3a51e2385955..4c76da9ddb465 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit c3a51e23859554369e6bbb5128dcef0e4f159fb5 +Subproject commit 4c76da9ddb4650203c129fceffdea95a3466c205 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 04f489c889235..9d4132b56c499 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 04f489c889235fe3b6dfe678ae5410d07deda958 +Subproject commit 9d4132b56c4999cd3ce1aeca5f1b2f2cb0d11c24 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 95f1acf9a39d6..9198465b6ca8b 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 95f1acf9a39d6f402f654e917e2c1dfdb779c5fc +Subproject commit 9198465b6ca8bed669df0cbb67c0e6d0b140803c From 4933be9e2f7bec805980342f882c235c92755a7c Mon Sep 17 00:00:00 2001 From: danakj Date: Wed, 15 Sep 2021 11:49:12 -0400 Subject: [PATCH 22/23] Verify bin crates are not deterministic on Windows This disables the remap_cwd_bin test which is failing on windows, and adds a test for --remap-path-prefix making a bin crate instead, to see if it will fail the same way. --- .github/workflows/ci.yml | 5 ++++ src/ci/github-actions/ci.yml | 5 ++++ .../reproducible-build/Makefile | 24 ++++++++++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff4fa1527e93a..76318ab7cb922 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -534,6 +534,11 @@ jobs: strategy: matrix: include: + - name: x86_64-msvc-1 + env: + RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler" + SCRIPT: make ci-subset-1 + os: windows-latest-xl - name: dist-x86_64-linux os: ubuntu-latest-xl env: {} diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 6417f5a984ad5..e4c402b417e6b 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -668,6 +668,11 @@ jobs: strategy: matrix: include: + - name: x86_64-msvc-1 + env: + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler + SCRIPT: make ci-subset-1 + <<: *job-windows-xl - *dist-x86_64-linux master: diff --git a/src/test/run-make-fulldeps/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile index 762cf5ed2ea71..46885fdb7df84 100644 --- a/src/test/run-make-fulldeps/reproducible-build/Makefile +++ b/src/test/run-make-fulldeps/reproducible-build/Makefile @@ -9,12 +9,18 @@ all: \ opt \ link_paths \ remap_paths \ - different_source_dirs \ - remap_cwd_bin \ + different_source_dirs_bin \ + different_source_dirs_rlib \ remap_cwd_rlib \ remap_cwd_to_empty \ extern_flags +# TODO: Deterministic builds of `bin` crate types are not deterministic with +# debuginfo=2 on Windows. +# See https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533 +# different_source_dirs_bin \ +# remap_cwd_bin \ + smoke: rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) linker.rs -O @@ -55,7 +61,19 @@ remap_paths: $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/b=/c cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 -different_source_dirs: +different_source_dirs_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 --remap-path-prefix=$$PWD=/b + cp $(TMPDIR)/reproducible-build $(TMPDIR)/foo + (cd $(TMPDIR)/test && $(RUSTC) reproducible-build.rs \ + --remap-path-prefix=$(TMPDIR)/test=/b \ + --crate-type bin) + cmp "$(TMPDIR)/reproducible-build" "$(TMPDIR)/foo" || exit 1 + +different_source_dirs_rlib: rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) reproducible-build-aux.rs mkdir $(TMPDIR)/test From c0118289efbd3d0c61ae8912426a211e53abe208 Mon Sep 17 00:00:00 2001 From: danakj Date: Wed, 15 Sep 2021 13:37:22 -0400 Subject: [PATCH 23/23] Disable both reproducible-build tests for crate-type=bin These tests fail on Windows, as the build is not deterministic there for bin targets. Issue https://github.com/rust-lang/rust/issues/88982 is filed for this problem. --- .github/workflows/ci.yml | 5 ----- src/ci/github-actions/ci.yml | 5 ----- src/test/run-make-fulldeps/reproducible-build/Makefile | 9 +++++---- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76318ab7cb922..ff4fa1527e93a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -534,11 +534,6 @@ jobs: strategy: matrix: include: - - name: x86_64-msvc-1 - env: - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler" - SCRIPT: make ci-subset-1 - os: windows-latest-xl - name: dist-x86_64-linux os: ubuntu-latest-xl env: {} diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index e4c402b417e6b..6417f5a984ad5 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -668,11 +668,6 @@ jobs: strategy: matrix: include: - - name: x86_64-msvc-1 - env: - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler - SCRIPT: make ci-subset-1 - <<: *job-windows-xl - *dist-x86_64-linux master: diff --git a/src/test/run-make-fulldeps/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile index 46885fdb7df84..adccc15356848 100644 --- a/src/test/run-make-fulldeps/reproducible-build/Makefile +++ b/src/test/run-make-fulldeps/reproducible-build/Makefile @@ -9,15 +9,16 @@ all: \ opt \ link_paths \ remap_paths \ - different_source_dirs_bin \ different_source_dirs_rlib \ remap_cwd_rlib \ remap_cwd_to_empty \ extern_flags -# TODO: Deterministic builds of `bin` crate types are not deterministic with -# debuginfo=2 on Windows. -# See https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533 +# TODO: Builds of `bin` crate types are not deterministic with debuginfo=2 on +# Windows. +# See: https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533 +# Issue: https://github.com/rust-lang/rust/issues/88982 +# # different_source_dirs_bin \ # remap_cwd_bin \