Auto merge of #64478 - Centril:rollup-bnt51w1, r=Centril
Rollup of 5 pull requests Successful merges: - #64457 (def_collector: Do not ICE on attributes on unnamed fields) - #64463 (resolve: Tweak some expected/found wording) - #64471 (Warn on no_start, crate_id attribute use) - #64473 (Use try_fold instead of manually carrying an accumulator) - #64475 (simplify the initialization) Failed merges: r? @ghost
This commit is contained in:
commit
8bf776d5c2
14 changed files with 88 additions and 47 deletions
|
@ -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<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
|
||||
fn with_parent<F: FnOnce(&mut Self)>(&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<usize>) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ExpnId, DefIndex>,
|
||||
/// Indices of unnamed struct or variant fields with unresolved attributes.
|
||||
pub(super) placeholder_field_indices: NodeMap<usize>,
|
||||
}
|
||||
|
||||
/// A unique identifier that we can use to lookup a definition
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"]
|
||||
|
|
9
src/test/ui/attributes/unnamed-field-attributes.rs
Normal file
9
src/test/ui/attributes/unnamed-field-attributes.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// check-pass
|
||||
|
||||
struct S(
|
||||
#[rustfmt::skip] u8,
|
||||
u16,
|
||||
#[rustfmt::skip] u32,
|
||||
);
|
||||
|
||||
fn main() {}
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
#![crate_id="rust_get_test_int"]
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
|
|
|
@ -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
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![crate_id="issue-6919"]
|
||||
extern crate issue6919_3;
|
||||
|
||||
pub fn main() {
|
||||
|
|
Loading…
Reference in a new issue