diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index bffb4df836e3b..d1cc7a8ce988f 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -31,7 +31,7 @@ impl<'a> DefCollector<'a> { self.definitions.create_def_with_parent(parent_def, node_id, data, self.expansion, span) } - pub fn with_parent(&mut self, parent_def: DefIndex, f: F) { + fn with_parent(&mut self, parent_def: DefIndex, f: F) { let orig_parent_def = std::mem::replace(&mut self.parent_def, parent_def); f(self); self.parent_def = orig_parent_def; @@ -74,6 +74,22 @@ impl<'a> DefCollector<'a> { }) } + fn collect_field(&mut self, field: &'a StructField, index: Option) { + if field.is_placeholder { + self.visit_macro_invoc(field.id); + } else { + let name = field.ident.map(|ident| ident.name) + .or_else(|| index.map(sym::integer)) + .unwrap_or_else(|| { + let node_id = NodeId::placeholder_from_expn_id(self.expansion); + sym::integer(self.definitions.placeholder_field_indices[&node_id]) + }) + .as_interned_str(); + let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span); + self.with_parent(def, |this| visit::walk_struct_field(this, field)); + } + } + pub fn visit_macro_invoc(&mut self, id: NodeId) { self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def); } @@ -170,17 +186,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } fn visit_variant_data(&mut self, data: &'a VariantData) { + // The assumption here is that non-`cfg` macro expansion cannot change field indices. + // It currently holds because only inert attributes are accepted on fields, + // and every such attribute expands into a single field after it's resolved. for (index, field) in data.fields().iter().enumerate() { - if field.is_placeholder { - self.visit_macro_invoc(field.id); - continue; + self.collect_field(field, Some(index)); + if field.is_placeholder && field.ident.is_none() { + self.definitions.placeholder_field_indices.insert(field.id, index); } - let name = field.ident.map(|ident| ident.name) - .unwrap_or_else(|| sym::integer(index)); - let def = self.create_def(field.id, - DefPathData::ValueNs(name.as_interned_str()), - field.span); - self.with_parent(def, |this| visit::walk_struct_field(this, field)); } } @@ -338,16 +351,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } } - fn visit_struct_field(&mut self, sf: &'a StructField) { - if sf.is_placeholder { - self.visit_macro_invoc(sf.id) - } else { - let name = sf.ident.map(|ident| ident.name) - .unwrap_or_else(|| panic!("don't know the field number in this context")); - let def = self.create_def(sf.id, - DefPathData::ValueNs(name.as_interned_str()), - sf.span); - self.with_parent(def, |this| visit::walk_struct_field(this, sf)); - } + // This method is called only when we are visiting an individual field + // after expanding an attribute on it. + fn visit_struct_field(&mut self, field: &'a StructField) { + self.collect_field(field, None); } } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 651fe8449ac93..187bc59332460 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -104,6 +104,8 @@ pub struct Definitions { /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` /// we know what parent node that fragment should be attached to thanks to this table. invocation_parents: FxHashMap, + /// Indices of unnamed struct or variant fields with unresolved attributes. + pub(super) placeholder_field_indices: NodeMap, } /// A unique identifier that we can use to lookup a definition diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index aecf5c5b52dba..cf19a9eb147a8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -669,6 +669,22 @@ impl DeprecatedAttr { } } +fn lint_deprecated_attr( + cx: &EarlyContext<'_>, + attr: &ast::Attribute, + msg: &str, + suggestion: Option<&str>, +) { + cx.struct_span_lint(DEPRECATED, attr.span, &msg) + .span_suggestion_short( + attr.span, + suggestion.unwrap_or("remove this attribute"), + String::new(), + Applicability::MachineApplicable + ) + .emit(); +} + impl EarlyLintPass for DeprecatedAttr { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { for &&(n, _, _, ref g) in &self.depr_attrs { @@ -679,18 +695,15 @@ impl EarlyLintPass for DeprecatedAttr { _) = g { let msg = format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); - let mut err = cx.struct_span_lint(DEPRECATED, attr.span, &msg); - err.span_suggestion_short( - attr.span, - suggestion.unwrap_or("remove this attribute"), - String::new(), - Applicability::MachineApplicable - ); - err.emit(); + lint_deprecated_attr(cx, attr, &msg, suggestion); } return; } } + if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) { + let msg = format!("use of deprecated attribute `{}`: no longer used.", attr.path); + lint_deprecated_attr(cx, attr, &msg, None); + } } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 06b7206f4292c..9ad1542905b68 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -477,7 +477,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { use rustc::mir::PlaceBase; - let mut op = match &place.base { + let base_op = match &place.base { PlaceBase::Local(mir::RETURN_PLACE) => throw_unsup!(ReadFromReturnPointer), PlaceBase::Local(local) => { @@ -497,9 +497,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } }; - for elem in place.projection.iter() { - op = self.operand_projection(op, elem)? - } + let op = place.projection.iter().try_fold( + base_op, + |op, elem| self.operand_projection(op, elem) + )?; trace!("eval_place_to_op: got {:?}", *op); Ok(op) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index bd8b5e13c6205..9096d14645100 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -237,7 +237,8 @@ impl<'a> base::Resolver for Resolver<'a> { if let Res::Def(..) = res { self.session.span_err( span, - "expected an inert attribute, found an attribute macro" + &format!("expected an inert attribute, found {} {}", + res.article(), res.descr()), ); return Ok(InvocationRes::Single(self.dummy_ext(kind))); } @@ -322,7 +323,7 @@ impl<'a> Resolver<'a> { self.check_stability_and_deprecation(&ext, path); Ok(if ext.macro_kind() != kind { - let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() }; + let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() }; let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path); self.session.struct_span_err(path.span, &msg) .span_label(path.span, format!("not {} {}", kind.article(), expected)) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ae7ab0a771754..1197160fa9501 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -400,7 +400,7 @@ pub struct UnsafetyState { impl UnsafetyState { pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState { - UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true } + UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true } } pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState { diff --git a/src/test/ui/attributes/item-attributes.rs b/src/test/ui/attributes/item-attributes.rs index c760a28ecf0ba..79cd0f5fbc358 100644 --- a/src/test/ui/attributes/item-attributes.rs +++ b/src/test/ui/attributes/item-attributes.rs @@ -11,8 +11,6 @@ #![rustc_dummy] #![rustc_dummy(attr5)] -#![crate_id="foobar#0.1"] - // These are attributes of the following mod #[rustc_dummy = "val"] #[rustc_dummy = "val"] diff --git a/src/test/ui/attributes/unnamed-field-attributes.rs b/src/test/ui/attributes/unnamed-field-attributes.rs new file mode 100644 index 0000000000000..93f364047e9a5 --- /dev/null +++ b/src/test/ui/attributes/unnamed-field-attributes.rs @@ -0,0 +1,9 @@ +// check-pass + +struct S( + #[rustfmt::skip] u8, + u16, + #[rustfmt::skip] u32, +); + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 6d51bb3f8ada8..68ff95e420895 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -84,12 +84,12 @@ #![crate_name = "0900"] #![crate_type = "bin"] // cannot pass "0800" here -// For #![crate_id], see issue #43142. (I cannot bear to enshrine current behavior in a test) +#![crate_id = "10"] //~ WARN use of deprecated attribute // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// For #![no_start], see issue #43144. (I cannot bear to enshrine current behavior in a test) +#![no_start] //~ WARN use of deprecated attribute // (cannot easily gating state of crate-level #[no_main]; but non crate-level is below at "0400") #![no_builtins] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 864df35a79fe3..b2a6018b5354d 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -186,6 +186,20 @@ LL | mod inner { #![macro_escape] } | = help: consider an outer attribute, `#[macro_use]` mod ... +warning: use of deprecated attribute `crate_id`: no longer used. + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:87:1 + | +LL | #![crate_id = "10"] + | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | + = note: `#[warn(deprecated)]` on by default + +warning: use of deprecated attribute `no_start`: no longer used. + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:92:1 + | +LL | #![no_start] + | ^^^^^^^^^^^^ help: remove this attribute + warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable --> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:12 | diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs index 63b5a4dd1b31a..77278ecda6ecb 100644 --- a/src/test/ui/issues/issue-1251.rs +++ b/src/test/ui/issues/issue-1251.rs @@ -6,8 +6,6 @@ #![feature(rustc_private)] -#![crate_id="rust_get_test_int"] - mod rustrt { extern crate libc; diff --git a/src/test/ui/issues/issue-49934-errors.rs b/src/test/ui/issues/issue-49934-errors.rs index 58f64d137b9f9..6fa5f01ffd926 100644 --- a/src/test/ui/issues/issue-49934-errors.rs +++ b/src/test/ui/issues/issue-49934-errors.rs @@ -1,10 +1,10 @@ fn foo<#[derive(Debug)] T>() { //~^ ERROR `derive` may only be applied to structs, enums and unions -//~| ERROR expected an inert attribute, found an attribute macro +//~| ERROR expected an inert attribute, found a derive macro match 0 { #[derive(Debug)] //~^ ERROR `derive` may only be applied to structs, enums and unions - //~| ERROR expected an inert attribute, found an attribute macro + //~| ERROR expected an inert attribute, found a derive macro _ => (), } } diff --git a/src/test/ui/issues/issue-49934-errors.stderr b/src/test/ui/issues/issue-49934-errors.stderr index fce1f65881266..8778d88d0ebec 100644 --- a/src/test/ui/issues/issue-49934-errors.stderr +++ b/src/test/ui/issues/issue-49934-errors.stderr @@ -4,7 +4,7 @@ error: `derive` may only be applied to structs, enums and unions LL | fn foo<#[derive(Debug)] T>() { | ^^^^^^^^^^^^^^^^ -error: expected an inert attribute, found an attribute macro +error: expected an inert attribute, found a derive macro --> $DIR/issue-49934-errors.rs:1:17 | LL | fn foo<#[derive(Debug)] T>() { @@ -16,7 +16,7 @@ error: `derive` may only be applied to structs, enums and unions LL | #[derive(Debug)] | ^^^^^^^^^^^^^^^^ -error: expected an inert attribute, found an attribute macro +error: expected an inert attribute, found a derive macro --> $DIR/issue-49934-errors.rs:5:18 | LL | #[derive(Debug)] diff --git a/src/test/ui/issues/issue-6919.rs b/src/test/ui/issues/issue-6919.rs index 11aed12087313..6f1e1f97708ef 100644 --- a/src/test/ui/issues/issue-6919.rs +++ b/src/test/ui/issues/issue-6919.rs @@ -4,7 +4,6 @@ // pretty-expanded FIXME #23616 -#![crate_id="issue-6919"] extern crate issue6919_3; pub fn main() {