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_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index c139f915e6cbb..c710fcc2c1dcb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -3,9 +3,11 @@ use rustc_index::vec::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir;
use rustc_middle::ty;
+use rustc_middle::ty::layout::LayoutOf;
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
+use rustc_target::abi::Abi;
use rustc_target::abi::Size;
use super::operand::{OperandRef, OperandValue};
@@ -368,21 +370,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
{
let arg_index = place.local.index() - 1;
if target_is_msvc {
- // Rust compiler decomposes every &str or slice argument into two components:
- // a pointer to the memory address where the data is stored and a usize representing
- // the length of the str (or slice). These components will later be used to reconstruct
- // the original argument inside the body of the function that owns it (see the
- // definition of debug_introduce_local for more details).
- //
- // Since the original argument is declared inside a function rather than being passed
- // in as an argument, it must be marked as a LocalVariable for MSVC debuggers to visualize
- // its data correctly. (See issue #81894 for an in-depth description of the problem).
- match *var_ty.kind() {
- ty::Ref(_, inner_type, _) => match *inner_type.kind() {
- ty::Slice(_) | ty::Str => VariableKind::LocalVariable,
- _ => VariableKind::ArgumentVariable(arg_index + 1),
- },
- _ => VariableKind::ArgumentVariable(arg_index + 1),
+ // ScalarPair parameters are spilled to the stack so they need to
+ // be marked as a `LocalVariable` for MSVC debuggers to visualize
+ // their data correctly. (See #81894 & #88625)
+ let var_ty_layout = self.cx.layout_of(var_ty);
+ if let Abi::ScalarPair(_, _) = var_ty_layout.abi {
+ VariableKind::LocalVariable
+ } else {
+ VariableKind::ArgumentVariable(arg_index + 1)
}
} else {
// FIXME(eddyb) shouldn't `ArgumentVariable` indices be
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index e2edd44826717..0877345938a92 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -129,6 +129,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
///////////////////////////////////////////////////////////////////////////
+#[instrument(level = "debug", skip(cx))]
pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
instance: Instance<'tcx>,
diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
index 09b91083a6347..a9db3497b2390 100644
--- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
@@ -83,8 +83,58 @@ impl DepthFirstSearch<'graph, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
{
- pub fn new(graph: &'graph G, start_node: G::Node) -> Self {
- Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) }
+ pub fn new(graph: &'graph G) -> Self {
+ Self { graph, stack: vec![], visited: BitSet::new_empty(graph.num_nodes()) }
+ }
+
+ /// Version of `push_start_node` that is convenient for chained
+ /// use.
+ pub fn with_start_node(mut self, start_node: G::Node) -> Self {
+ self.push_start_node(start_node);
+ self
+ }
+
+ /// Pushes another start node onto the stack. If the node
+ /// has not already been visited, then you will be able to
+ /// walk its successors (and so forth) after the current
+ /// contents of the stack are drained. If multiple start nodes
+ /// are added into the walk, then their mutual successors
+ /// will all be walked. You can use this method once the
+ /// iterator has been completely drained to add additional
+ /// start nodes.
+ pub fn push_start_node(&mut self, start_node: G::Node) {
+ if self.visited.insert(start_node) {
+ self.stack.push(start_node);
+ }
+ }
+
+ /// Searches all nodes reachable from the current start nodes.
+ /// This is equivalent to just invoke `next` repeatedly until
+ /// you get a `None` result.
+ pub fn complete_search(&mut self) {
+ while let Some(_) = self.next() {}
+ }
+
+ /// Returns true if node has been visited thus far.
+ /// A node is considered "visited" once it is pushed
+ /// onto the internal stack; it may not yet have been yielded
+ /// from the iterator. This method is best used after
+ /// the iterator is completely drained.
+ pub fn visited(&self, node: G::Node) -> bool {
+ self.visited.contains(node)
+ }
+}
+
+impl std::fmt::Debug for DepthFirstSearch<'_, G>
+where
+ G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let mut f = fmt.debug_set();
+ for n in self.visited.iter() {
+ f.entry(&n);
+ }
+ f.finish()
}
}
diff --git a/compiler/rustc_data_structures/src/graph/iterate/tests.rs b/compiler/rustc_data_structures/src/graph/iterate/tests.rs
index 0e038e88b221d..c498c289337f1 100644
--- a/compiler/rustc_data_structures/src/graph/iterate/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/iterate/tests.rs
@@ -20,3 +20,19 @@ fn is_cyclic() {
assert!(!is_cyclic(&diamond_acyclic));
assert!(is_cyclic(&diamond_cyclic));
}
+
+#[test]
+fn dfs() {
+ let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]);
+
+ let result: Vec = DepthFirstSearch::new(&graph).with_start_node(0).collect();
+ assert_eq!(result, vec![0, 2, 3, 1]);
+}
+
+#[test]
+fn dfs_debug() {
+ let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]);
+ let mut dfs = DepthFirstSearch::new(&graph).with_start_node(0);
+ dfs.complete_search();
+ assert_eq!(format!("{{0, 1, 2, 3}}"), format!("{:?}", dfs));
+}
diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index dff22855629a8..3560df6e5e204 100644
--- a/compiler/rustc_data_structures/src/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
@@ -32,7 +32,7 @@ where
where
Self: WithNumNodes,
{
- iterate::DepthFirstSearch::new(self, from)
+ iterate::DepthFirstSearch::new(self).with_start_node(from)
}
}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index d128a688e751f..dd6a17b92aef3 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -21,6 +21,7 @@
#![feature(iter_map_while)]
#![feature(maybe_uninit_uninit_array)]
#![feature(min_specialization)]
+#![feature(never_type)]
#![feature(type_alias_impl_trait)]
#![feature(new_uninit)]
#![feature(nll)]
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index 18b352cf3b0b9..354f9dd93cc4d 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -209,6 +209,12 @@ impl_stable_hash_via_hash!(i128);
impl_stable_hash_via_hash!(char);
impl_stable_hash_via_hash!(());
+impl HashStable for ! {
+ fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
+ unreachable!()
+ }
+}
+
impl HashStable for ::std::num::NonZeroU32 {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.get().hash_stable(ctx, hasher)
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_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 853415c4173b5..cb668eb35e093 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -598,6 +598,11 @@ impl Res {
}
}
+ #[track_caller]
+ pub fn expect_non_local(self) -> Res {
+ self.map_id(|_| panic!("unexpected `Res::Local`"))
+ }
+
pub fn macro_kind(self) -> Option {
match self {
Res::Def(DefKind::Macro(kind), _) => Some(kind),
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 5f01cfa6a7da2..cc4b7d08f45d8 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1020,10 +1020,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
/// Iterates over each child of the given item.
- fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session)
- where
- F: FnMut(Export),
- {
+ fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
if let Some(data) = &self.root.proc_macro_data {
/* If we are loading as a proc macro, we want to return the view of this crate
* as a proc macro crate.
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 41839c58021ab..80341b16e1412 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -5,7 +5,6 @@ use crate::rmeta::encoder;
use rustc_ast as ast;
use rustc_data_structures::stable_map::FxHashMap;
-use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@@ -326,28 +325,27 @@ pub fn provide(providers: &mut Providers) {
// (restrict scope of mutable-borrow of `visible_parent_map`)
{
let visible_parent_map = &mut visible_parent_map;
- let mut add_child =
- |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
- if child.vis != ty::Visibility::Public {
- return;
- }
+ let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
+ if child.vis != ty::Visibility::Public {
+ return;
+ }
- if let Some(child) = child.res.opt_def_id() {
- match visible_parent_map.entry(child) {
- Entry::Occupied(mut entry) => {
- // If `child` is defined in crate `cnum`, ensure
- // that it is mapped to a parent in `cnum`.
- if child.is_local() && entry.get().is_local() {
- entry.insert(parent);
- }
- }
- Entry::Vacant(entry) => {
+ if let Some(child) = child.res.opt_def_id() {
+ match visible_parent_map.entry(child) {
+ Entry::Occupied(mut entry) => {
+ // If `child` is defined in crate `cnum`, ensure
+ // that it is mapped to a parent in `cnum`.
+ if child.is_local() && entry.get().is_local() {
entry.insert(parent);
- bfs_queue.push_back(child);
}
}
+ Entry::Vacant(entry) => {
+ entry.insert(parent);
+ bfs_queue.push_back(child);
+ }
}
- };
+ }
+ };
while let Some(def) = bfs_queue.pop_front() {
for child in tcx.item_children(def).iter() {
@@ -393,11 +391,7 @@ impl CStore {
self.get_crate_data(def.krate).get_visibility(def.index)
}
- pub fn item_children_untracked(
- &self,
- def_id: DefId,
- sess: &Session,
- ) -> Vec> {
+ pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec {
let mut result = vec![];
self.get_crate_data(def_id.krate).each_child_of_item(
def_id.index,
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index d8b9a4799760e..52c6193940dbc 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1065,14 +1065,7 @@ impl EncodeContext<'a, 'tcx> {
// items - we encode information about proc-macros later on.
let reexports = if !self.is_proc_macro {
match tcx.module_exports(local_def_id) {
- Some(exports) => {
- let hir = self.tcx.hir();
- self.lazy(
- exports
- .iter()
- .map(|export| export.map_id(|id| hir.local_def_id_to_hir_id(id))),
- )
- }
+ Some(exports) => self.lazy(exports),
_ => Lazy::empty(),
}
} else {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index a487753f4628a..fe0bf5b64ba09 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -359,7 +359,7 @@ struct RenderedConst(String);
#[derive(MetadataEncodable, MetadataDecodable)]
struct ModData {
- reexports: Lazy<[Export]>,
+ reexports: Lazy<[Export]>,
expansion: ExpnId,
}
diff --git a/compiler/rustc_middle/src/hir/exports.rs b/compiler/rustc_middle/src/hir/exports.rs
index be9e38aca65d1..f37b976fba68d 100644
--- a/compiler/rustc_middle/src/hir/exports.rs
+++ b/compiler/rustc_middle/src/hir/exports.rs
@@ -11,23 +11,18 @@ use std::fmt::Debug;
/// This is the replacement export map. It maps a module to all of the exports
/// within.
-pub type ExportMap = FxHashMap>>;
+pub type ExportMap = FxHashMap>;
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
-pub struct Export {
+pub struct Export {
/// The name of the target.
pub ident: Ident,
/// The resolution of the target.
- pub res: Res,
+ /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
+ pub res: Res,
/// The span of the target.
pub span: Span,
/// The visibility of the export.
/// We include non-`pub` exports for hygienic macros that get used from extern crates.
pub vis: ty::Visibility,
}
-
-impl Export {
- pub fn map_id(self, map: impl FnMut(Id) -> R) -> Export {
- Export { ident: self.ident, res: self.res.map_id(map), span: self.span, vis: self.vis }
- }
-}
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d6f3b6f3248a1..7402a77939418 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1189,7 +1189,7 @@ rustc_queries! {
desc { "traits in scope at a block" }
}
- query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> {
+ query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> {
desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
}
@@ -1401,7 +1401,7 @@ rustc_queries! {
eval_always
desc { "fetching what a crate is named" }
}
- query item_children(def_id: DefId) -> &'tcx [Export] {
+ query item_children(def_id: DefId) -> &'tcx [Export] {
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
}
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index fddfd6e435c05..cd1e38445ae8c 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -127,7 +127,7 @@ pub struct ResolverOutputs {
pub extern_crate_map: FxHashMap,
pub maybe_unused_trait_imports: FxHashSet,
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
- pub export_map: ExportMap,
+ pub export_map: ExportMap,
pub glob_map: FxHashMap>,
/// Extern prelude entries. The value is `true` if the entry was introduced
/// via `extern crate` item and not `--extern` option or compiler built-in.
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 10c73fd64bc19..c5b961f12b2ab 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,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/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_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 2ee483d850e7b..55f2b04c4f1c1 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -228,7 +228,6 @@ impl<'a> Resolver<'a> {
crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
let def_id = module.def_id().expect("unpopulated module without a def-id");
for child in self.cstore().item_children_untracked(def_id, self.session) {
- let child = child.map_id(|_| panic!("unexpected id"));
let parent_scope = ParentScope::module(module, self);
BuildReducedGraphVisitor { r: self, parent_scope }
.build_reduced_graph_for_external_crate_res(child);
@@ -946,9 +945,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
/// Builds the reduced graph for a single item in an external crate.
- fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) {
+ fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) {
let parent = self.parent_scope.module;
let Export { ident, res, vis, span } = child;
+ let res = res.expect_non_local();
let expansion = self.parent_scope.expansion;
// Record primary definitions.
match res {
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index dfb6d89a0d126..d4782edbc1346 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -11,7 +11,6 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin
use rustc_ast::unwrap_or;
use rustc_ast::NodeId;
-use rustc_ast_lowering::ResolverAstLowering;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::ptr_key::PtrKey;
use rustc_errors::{pluralize, struct_span_err, Applicability};
@@ -1387,13 +1386,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
let mut reexports = Vec::new();
- module.for_each_child(self.r, |this, ident, _, binding| {
+ module.for_each_child(self.r, |_, ident, _, binding| {
// Filter away ambiguous imports and anything that has def-site hygiene.
// FIXME: Implement actual cross-crate hygiene.
let is_good_import =
binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion();
if is_good_import || binding.is_macro_def() {
- let res = binding.res().map_id(|id| this.local_def_id(id));
+ let res = binding.res().expect_non_local();
if res != def::Res::Err {
reexports.push(Export { ident, res, span: binding.span, vis: binding.vis });
}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 7fb1e92440bfb..d76ba80e42eab 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -14,6 +14,7 @@
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]
#![feature(iter_zip)]
+#![feature(never_type)]
#![feature(nll)]
#![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)]
@@ -911,7 +912,7 @@ pub struct Resolver<'a> {
/// `CrateNum` resolutions of `extern crate` items.
extern_crate_map: FxHashMap,
- export_map: ExportMap,
+ export_map: ExportMap,
trait_map: Option>>,
/// A map from nodes to anonymous modules.
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index ecc8dae04800a..e32e4493726db 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -366,6 +366,18 @@ direct_serialize_impls! {
char emit_char read_char
}
+impl Encodable for ! {
+ fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
+ unreachable!()
+ }
+}
+
+impl Decodable for ! {
+ fn decode(_d: &mut D) -> Result {
+ unreachable!()
+ }
+}
+
impl Encodable for ::std::num::NonZeroU32 {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_u32(self.get())
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/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index a746ad7ad4bc7..9744f4f6483c7 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -1655,7 +1655,7 @@ fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] {
tcx: TyCtxt<'_>,
traits: &mut Vec,
external_mods: &mut FxHashSet,
- res: Res,
+ res: Res,
) {
match res {
Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index c871411793073..fbc7f19cb731c 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -590,10 +590,18 @@ impl Step for Rustc {
cargo.rustdocflag("-Znormalize-docs");
cargo.rustdocflag("--show-type-layout");
compile::rustc_cargo(builder, &mut cargo, target);
+ cargo.arg("-Zunstable-options");
cargo.arg("-Zskip-rustdoc-fingerprint");
// Only include compiler crates, no dependencies of those, such as `libc`.
+ // Do link to dependencies on `docs.rs` however using `rustdoc-map`.
cargo.arg("--no-deps");
+ cargo.arg("-Zrustdoc-map");
+
+ // FIXME: `-Zrustdoc-map` does not yet correctly work for transitive dependencies,
+ // once this is no longer an issue the special case for `ena` can be removed.
+ cargo.rustdocflag("--extern-html-root-url");
+ cargo.rustdocflag("ena=https://docs.rs/ena/latest/");
// Find dependencies for top level crates.
let mut compiler_crates = HashSet::new();
diff --git a/src/ci/scripts/verify-backported-commits.sh b/src/ci/scripts/verify-backported-commits.sh
index 1023e4b0e2837..d3da6d1ac915a 100755
--- a/src/ci/scripts/verify-backported-commits.sh
+++ b/src/ci/scripts/verify-backported-commits.sh
@@ -18,14 +18,6 @@ verify_backported_commits_main() {
exit 0
fi
- echo 'git: unshallowing the repository so we can check commits'
- git fetch \
- --no-tags \
- --no-recurse-submodules \
- --progress \
- --prune \
- --unshallow
-
if [[ $ci_base_branch == "beta" ]]; then
verify_cherries master "$BETA_LIMIT" \
|| exit 1
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 40b0175bb1595..29834c82b3de3 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -482,12 +482,13 @@ fn build_module(
// visit each node at most once.
for &item in cx.tcx.item_children(did).iter() {
if item.vis == ty::Visibility::Public {
- if let Some(def_id) = item.res.mod_def_id() {
+ let res = item.res.expect_non_local();
+ if let Some(def_id) = res.mod_def_id() {
if did == def_id || !visited.insert(def_id) {
continue;
}
}
- if let Res::PrimTy(p) = item.res {
+ if let Res::PrimTy(p) = res {
// Primitive types can't be inlined so generate an import instead.
let prim_ty = clean::PrimitiveType::from(p);
items.push(clean::Item {
@@ -500,7 +501,7 @@ fn build_module(
clean::ImportSource {
path: clean::Path {
global: false,
- res: item.res,
+ res,
segments: vec![clean::PathSegment {
name: prim_ty.as_sym(),
args: clean::GenericArgs::AngleBracketed {
@@ -515,9 +516,7 @@ fn build_module(
))),
cfg: None,
});
- } else if let Some(i) =
- try_inline(cx, did, None, item.res, item.ident.name, None, visited)
- {
+ } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
items.extend(i)
}
}
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 454602481e3c5..3254480ff6502 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -212,7 +212,7 @@ impl ExternalCrate {
crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
let root = self.def_id();
- let as_keyword = |res: Res| {
+ let as_keyword = |res: Res| {
if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = tcx.get_attrs(def_id);
let mut keyword = None;
@@ -243,7 +243,8 @@ impl ExternalCrate {
hir::ItemKind::Use(ref path, hir::UseKind::Single)
if item.vis.node.is_pub() =>
{
- as_keyword(path.res).map(|(_, prim)| (id.def_id.to_def_id(), prim))
+ as_keyword(path.res.expect_non_local())
+ .map(|(_, prim)| (id.def_id.to_def_id(), prim))
}
_ => None,
}
@@ -274,7 +275,7 @@ impl ExternalCrate {
// Also note that this does not attempt to deal with modules tagged
// duplicately for the same primitive. This is handled later on when
// rendering by delegating everything to a hash map.
- let as_primitive = |res: Res| {
+ let as_primitive = |res: Res| {
if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = tcx.get_attrs(def_id);
let mut prim = None;
@@ -309,7 +310,7 @@ impl ExternalCrate {
hir::ItemKind::Use(ref path, hir::UseKind::Single)
if item.vis.node.is_pub() =>
{
- as_primitive(path.res).map(|(_, prim)| {
+ as_primitive(path.res.expect_non_local()).map(|(_, prim)| {
// Pretend the primitive is local.
(id.def_id.to_def_id(), prim)
})
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 3e06b4173144c..3e98ba08fb9ca 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -67,7 +67,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
}
}
- fn visit_item(&mut self, res: Res) {
+ fn visit_item(&mut self, res: Res) {
let def_id = res.def_id();
let vis = self.tcx.visibility(def_id);
let inherited_item_level = if vis == Visibility::Public { self.prev_level } else { None };
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
new file mode 100644
index 0000000000000..180e42519b481
--- /dev/null
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -0,0 +1,101 @@
+// only-cdb
+// compile-flags: -g
+
+// cdb-command: g
+
+// cdb-command: dx r1
+// cdb-check:r1 : (0xa..0xc) [Type: core::ops::range::Range]
+// cdb-command: dx r2
+// cdb-check:r2 : (0x14..0x1e) [Type: core::ops::range::Range]
+
+// cdb-command: g
+
+// cdb-command: dx r1
+// cdb-check:r1 : (0x9..0x64) [Type: core::ops::range::Range]
+// cdb-command: dx r2
+// cdb-check:r2 : (0xc..0x5a) [Type: core::ops::range::Range]
+
+// cdb-command: g
+
+// cdb-command: dx o1
+// cdb-check:o1 : Some [Type: enum$ >]
+// cdb-check: [variant] : Some
+// cdb-check: [+0x004] __0 : 0x4d2 [Type: [...]]
+// cdb-command: dx o2
+// cdb-check:o2 : Some [Type: enum$ >]
+// cdb-check: [variant] : Some
+// cdb-check: [+0x008] __0 : 0x162e [Type: unsigned __int64]
+
+// cdb-command: g
+
+// cdb-command: dx t1
+// cdb-check:t1 : (0xa, 0x14) [Type: tuple$]
+// cdb-check: [0] : 0xa [Type: unsigned int]
+// cdb-check: [1] : 0x14 [Type: unsigned int]
+// cdb-command: dx t2
+// cdb-check:t2 : (0x1e, 0x28) [Type: tuple$]
+// cdb-check: [0] : 0x1e [Type: unsigned __int64]
+// cdb-check: [1] : 0x28 [Type: unsigned __int64]
+
+// cdb-command: g
+
+// cdb-command: dx s
+// cdb-check:s : "this is a static str" [Type: str]
+// cdb-check: [len] : 0x14 [Type: unsigned __int64]
+// cdb-check: [chars]
+
+// cdb-command: g
+
+// cdb-command: dx s
+// cdb-check:s : { len=0x5 } [Type: slice$]
+// cdb-check: [len] : 0x5 [Type: unsigned __int64]
+// cdb-check: [0] : 0x1 [Type: unsigned char]
+// cdb-check: [1] : 0x2 [Type: unsigned char]
+// cdb-check: [2] : 0x3 [Type: unsigned char]
+// cdb-check: [3] : 0x4 [Type: unsigned char]
+// cdb-check: [4] : 0x5 [Type: unsigned char]
+
+use std::ops::Range;
+
+fn range(r1: Range, r2: Range) {
+ zzz(); // #break
+}
+
+fn range_mut(mut r1: Range, mut r2: Range) {
+ if r1.start == 9 {
+ r1.end = 100;
+ }
+
+ if r2.start == 12 {
+ r2.end = 90;
+ }
+
+ zzz(); // #break
+}
+
+fn option(o1: Option, o2: Option) {
+ zzz(); // #break
+}
+
+fn tuple(t1: (u32, u32), t2: (u64, u64)) {
+ zzz(); // #break
+}
+
+fn str(s: &str) {
+ zzz(); // #break
+}
+
+fn slice(s: &[u8]) {
+ zzz(); // #break
+}
+
+fn zzz() { }
+
+fn main() {
+ range(10..12, 20..30);
+ range_mut(9..20, 12..80);
+ option(Some(1234), Some(5678));
+ tuple((10, 20), (30, 40));
+ str("this is a static str");
+ slice(&[1, 2, 3, 4, 5]);
+}
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/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/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/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/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index da259511fe0b9..3a94f47298390 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -520,7 +520,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
}
};
}
- fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
+ fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
tcx.item_children(def_id)
.iter()
.find(|item| item.ident.name.as_str() == name)
@@ -557,7 +557,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
None
}
});
- try_res!(last).res
+ try_res!(last).res.expect_non_local()
}
/// Convenience function to get the `DefId` of a trait by path.
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)
}