Auto merge of #95760 - Dylan-DPC:rollup-uskzggh, r=Dylan-DPC
Rollup of 4 pull requests Successful merges: - #95189 (Stop flagging unexpected inner attributes as outer ones in certain diagnostics) - #95752 (Regression test for #82866) - #95753 (Correct safety reasoning in `str::make_ascii_{lower,upper}case()`) - #95757 (Use gender neutral terms) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ed6c958ee4
15 changed files with 86 additions and 34 deletions
|
@ -141,7 +141,7 @@ pub fn expand_include<'cx>(
|
||||||
|
|
||||||
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
||||||
let mut ret = SmallVec::new();
|
let mut ret = SmallVec::new();
|
||||||
while self.p.token != token::Eof {
|
loop {
|
||||||
match self.p.parse_item(ForceCollect::No) {
|
match self.p.parse_item(ForceCollect::No) {
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -149,9 +149,12 @@ pub fn expand_include<'cx>(
|
||||||
}
|
}
|
||||||
Ok(Some(item)) => ret.push(item),
|
Ok(Some(item)) => ret.push(item),
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
let token = pprust::token_to_string(&self.p.token);
|
if self.p.token != token::Eof {
|
||||||
let msg = format!("expected item, found `{}`", token);
|
let token = pprust::token_to_string(&self.p.token);
|
||||||
self.p.struct_span_err(self.p.token.span, &msg).emit();
|
let msg = format!("expected item, found `{}`", token);
|
||||||
|
self.p.struct_span_err(self.p.token.span, &msg).emit();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,7 +315,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
|
||||||
/// only on the nesting depth of repetitions in the originating token tree it
|
/// only on the nesting depth of repetitions in the originating token tree it
|
||||||
/// was derived from.
|
/// was derived from.
|
||||||
///
|
///
|
||||||
/// In layman's terms: `NamedMatch` will form a tree representing nested matches of a particular
|
/// In layperson's terms: `NamedMatch` will form a tree representing nested matches of a particular
|
||||||
/// meta variable. For example, if we are matching the following macro against the following
|
/// meta variable. For example, if we are matching the following macro against the following
|
||||||
/// invocation...
|
/// invocation...
|
||||||
///
|
///
|
||||||
|
|
|
@ -13,7 +13,7 @@ use tracing::debug;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InnerAttrPolicy<'a> {
|
pub enum InnerAttrPolicy<'a> {
|
||||||
Permitted,
|
Permitted,
|
||||||
Forbidden { reason: &'a str, saw_doc_comment: bool, prev_attr_sp: Option<Span> },
|
Forbidden { reason: &'a str, saw_doc_comment: bool, prev_outer_attr_sp: Option<Span> },
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
|
const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
|
||||||
|
@ -22,7 +22,7 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
|
||||||
pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPolicy::Forbidden {
|
pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPolicy::Forbidden {
|
||||||
reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG,
|
reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG,
|
||||||
saw_doc_comment: false,
|
saw_doc_comment: false,
|
||||||
prev_attr_sp: None,
|
prev_outer_attr_sp: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OuterAttributeType {
|
enum OuterAttributeType {
|
||||||
|
@ -34,14 +34,16 @@ enum OuterAttributeType {
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
/// Parses attributes that appear before an item.
|
/// Parses attributes that appear before an item.
|
||||||
pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
|
pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
|
||||||
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
let mut outer_attrs: Vec<ast::Attribute> = Vec::new();
|
||||||
let mut just_parsed_doc_comment = false;
|
let mut just_parsed_doc_comment = false;
|
||||||
let start_pos = self.token_cursor.num_next_calls;
|
let start_pos = self.token_cursor.num_next_calls;
|
||||||
loop {
|
loop {
|
||||||
let attr = if self.check(&token::Pound) {
|
let attr = if self.check(&token::Pound) {
|
||||||
|
let prev_outer_attr_sp = outer_attrs.last().map(|attr| attr.span);
|
||||||
|
|
||||||
let inner_error_reason = if just_parsed_doc_comment {
|
let inner_error_reason = if just_parsed_doc_comment {
|
||||||
"an inner attribute is not permitted following an outer doc comment"
|
"an inner attribute is not permitted following an outer doc comment"
|
||||||
} else if !attrs.is_empty() {
|
} else if prev_outer_attr_sp.is_some() {
|
||||||
"an inner attribute is not permitted following an outer attribute"
|
"an inner attribute is not permitted following an outer attribute"
|
||||||
} else {
|
} else {
|
||||||
DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
|
DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
|
||||||
|
@ -49,7 +51,7 @@ impl<'a> Parser<'a> {
|
||||||
let inner_parse_policy = InnerAttrPolicy::Forbidden {
|
let inner_parse_policy = InnerAttrPolicy::Forbidden {
|
||||||
reason: inner_error_reason,
|
reason: inner_error_reason,
|
||||||
saw_doc_comment: just_parsed_doc_comment,
|
saw_doc_comment: just_parsed_doc_comment,
|
||||||
prev_attr_sp: attrs.last().map(|a| a.span),
|
prev_outer_attr_sp,
|
||||||
};
|
};
|
||||||
just_parsed_doc_comment = false;
|
just_parsed_doc_comment = false;
|
||||||
Some(self.parse_attribute(inner_parse_policy)?)
|
Some(self.parse_attribute(inner_parse_policy)?)
|
||||||
|
@ -97,12 +99,14 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
attrs.push(attr);
|
if attr.style == ast::AttrStyle::Outer {
|
||||||
|
outer_attrs.push(attr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(AttrWrapper::new(attrs.into(), start_pos))
|
Ok(AttrWrapper::new(outer_attrs.into(), start_pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Matches `attribute = # ! [ meta_item ]`.
|
/// Matches `attribute = # ! [ meta_item ]`.
|
||||||
|
@ -215,15 +219,15 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) {
|
pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) {
|
||||||
if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_attr_sp } = policy {
|
if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_outer_attr_sp } = policy {
|
||||||
let prev_attr_note =
|
let prev_outer_attr_note =
|
||||||
if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" };
|
if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" };
|
||||||
|
|
||||||
let mut diag = self.struct_span_err(attr_sp, reason);
|
let mut diag = self.struct_span_err(attr_sp, reason);
|
||||||
|
|
||||||
if let Some(prev_attr_sp) = prev_attr_sp {
|
if let Some(prev_outer_attr_sp) = prev_outer_attr_sp {
|
||||||
diag.span_label(attr_sp, "not permitted following an outer attribute")
|
diag.span_label(attr_sp, "not permitted following an outer attribute")
|
||||||
.span_label(prev_attr_sp, prev_attr_note);
|
.span_label(prev_outer_attr_sp, prev_outer_attr_note);
|
||||||
}
|
}
|
||||||
|
|
||||||
diag.note(
|
diag.note(
|
||||||
|
|
|
@ -1657,7 +1657,7 @@ fn receiver_is_valid<'fcx, 'tcx>(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
||||||
// If he receiver already has errors reported due to it, consider it valid to avoid
|
// If the receiver already has errors reported due to it, consider it valid to avoid
|
||||||
// unnecessary errors (#58712).
|
// unnecessary errors (#58712).
|
||||||
return receiver_ty.references_error();
|
return receiver_ty.references_error();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2700,7 +2700,7 @@ fn linkage_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Linkage {
|
||||||
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
|
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
|
||||||
// applicable to variable declarations and may not really make sense for
|
// applicable to variable declarations and may not really make sense for
|
||||||
// Rust code in the first place but allow them anyway and trust that the
|
// Rust code in the first place but allow them anyway and trust that the
|
||||||
// user knows what s/he's doing. Who knows, unanticipated use cases may pop
|
// user knows what they're doing. Who knows, unanticipated use cases may pop
|
||||||
// up in the future.
|
// up in the future.
|
||||||
//
|
//
|
||||||
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
|
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
|
||||||
|
|
|
@ -2406,7 +2406,7 @@ impl str {
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn make_ascii_uppercase(&mut self) {
|
pub fn make_ascii_uppercase(&mut self) {
|
||||||
// SAFETY: safe because we transmute two types with the same layout.
|
// SAFETY: changing ASCII letters only does not invalidate UTF-8.
|
||||||
let me = unsafe { self.as_bytes_mut() };
|
let me = unsafe { self.as_bytes_mut() };
|
||||||
me.make_ascii_uppercase()
|
me.make_ascii_uppercase()
|
||||||
}
|
}
|
||||||
|
@ -2433,7 +2433,7 @@ impl str {
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn make_ascii_lowercase(&mut self) {
|
pub fn make_ascii_lowercase(&mut self) {
|
||||||
// SAFETY: safe because we transmute two types with the same layout.
|
// SAFETY: changing ASCII letters only does not invalidate UTF-8.
|
||||||
let me = unsafe { self.as_bytes_mut() };
|
let me = unsafe { self.as_bytes_mut() };
|
||||||
me.make_ascii_lowercase()
|
me.make_ascii_lowercase()
|
||||||
}
|
}
|
||||||
|
|
|
@ -644,9 +644,9 @@ fn recursive_rmdir_toctou() {
|
||||||
// Test for time-of-check to time-of-use issues.
|
// Test for time-of-check to time-of-use issues.
|
||||||
//
|
//
|
||||||
// Scenario:
|
// Scenario:
|
||||||
// The attacker wants to get directory contents deleted, to which he does not have access.
|
// The attacker wants to get directory contents deleted, to which they do not have access.
|
||||||
// He has a way to get a privileged Rust binary call `std::fs::remove_dir_all()` on a
|
// They have a way to get a privileged Rust binary call `std::fs::remove_dir_all()` on a
|
||||||
// directory he controls, e.g. in his home directory.
|
// directory they control, e.g. in their home directory.
|
||||||
//
|
//
|
||||||
// The POC sets up the `attack_dest/attack_file` which the attacker wants to have deleted.
|
// The POC sets up the `attack_dest/attack_file` which the attacker wants to have deleted.
|
||||||
// The attacker repeatedly creates a directory and replaces it with a symlink from
|
// The attacker repeatedly creates a directory and replaces it with a symlink from
|
||||||
|
|
|
@ -980,7 +980,7 @@ pub mod fast {
|
||||||
unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
|
unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
|
||||||
// SAFETY: See comment above (this function doc).
|
// SAFETY: See comment above (this function doc).
|
||||||
if !mem::needs_drop::<T>() || unsafe { self.try_register_dtor() } {
|
if !mem::needs_drop::<T>() || unsafe { self.try_register_dtor() } {
|
||||||
// SAFETY: See comment above (his function doc).
|
// SAFETY: See comment above (this function doc).
|
||||||
Some(unsafe { self.inner.initialize(init) })
|
Some(unsafe { self.inner.initialize(init) })
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
7
src/test/ui/match/issue-82866.rs
Normal file
7
src/test/ui/match/issue-82866.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fn main() {
|
||||||
|
match x {
|
||||||
|
//~^ ERROR cannot find value `x` in this scope
|
||||||
|
Some::<v>(v) => (),
|
||||||
|
//~^ ERROR cannot find type `v` in this scope
|
||||||
|
}
|
||||||
|
}
|
16
src/test/ui/match/issue-82866.stderr
Normal file
16
src/test/ui/match/issue-82866.stderr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0425]: cannot find value `x` in this scope
|
||||||
|
--> $DIR/issue-82866.rs:2:11
|
||||||
|
|
|
||||||
|
LL | match x {
|
||||||
|
| ^ not found in this scope
|
||||||
|
|
||||||
|
error[E0412]: cannot find type `v` in this scope
|
||||||
|
--> $DIR/issue-82866.rs:4:16
|
||||||
|
|
|
||||||
|
LL | Some::<v>(v) => (),
|
||||||
|
| ^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0412, E0425.
|
||||||
|
For more information about an error, try `rustc --explain E0412`.
|
|
@ -3,5 +3,4 @@
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context
|
#![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context
|
||||||
//~| ERROR definition of an unknown language item: `foo`
|
|
||||||
fn foo() {}
|
fn foo() {}
|
||||||
|
|
|
@ -3,7 +3,6 @@ error: an inner attribute is not permitted in this context
|
||||||
|
|
|
|
||||||
LL | #![lang = "foo"]
|
LL | #![lang = "foo"]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
LL |
|
|
||||||
LL | fn foo() {}
|
LL | fn foo() {}
|
||||||
| ----------- the inner attribute doesn't annotate this function
|
| ----------- the inner attribute doesn't annotate this function
|
||||||
|
|
|
|
||||||
|
@ -14,12 +13,5 @@ LL - #![lang = "foo"]
|
||||||
LL + #[lang = "foo"]
|
LL + #[lang = "foo"]
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0522]: definition of an unknown language item: `foo`
|
error: aborting due to previous error
|
||||||
--> $DIR/attr.rs:5:1
|
|
||||||
|
|
|
||||||
LL | #![lang = "foo"]
|
|
||||||
| ^^^^^^^^^^^^^^^^ definition of unknown language item `foo`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0522`.
|
|
||||||
|
|
3
src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs
Normal file
3
src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// include file for issue-94340.rs
|
||||||
|
#![deny(rust_2018_idioms)]
|
||||||
|
#![deny(unused_must_use)]
|
8
src/test/ui/parser/issues/issue-94340.rs
Normal file
8
src/test/ui/parser/issues/issue-94340.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Make sure that unexpected inner attributes are not labeled as outer ones in diagnostics when
|
||||||
|
// trying to parse an item and that they are subsequently ignored not triggering confusing extra
|
||||||
|
// diagnostics like "expected item after attributes" which is not true for `include!` which can
|
||||||
|
// include empty files.
|
||||||
|
|
||||||
|
include!("auxiliary/issue-94340-inc.rs");
|
||||||
|
|
||||||
|
fn main() {}
|
20
src/test/ui/parser/issues/issue-94340.stderr
Normal file
20
src/test/ui/parser/issues/issue-94340.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error: an inner attribute is not permitted in this context
|
||||||
|
--> $DIR/auxiliary/issue-94340-inc.rs:2:1
|
||||||
|
|
|
||||||
|
LL | #![deny(rust_2018_idioms)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
|
||||||
|
= note: outer attributes, like `#[test]`, annotate the item following them
|
||||||
|
|
||||||
|
error: an inner attribute is not permitted in this context
|
||||||
|
--> $DIR/auxiliary/issue-94340-inc.rs:3:1
|
||||||
|
|
|
||||||
|
LL | #![deny(unused_must_use)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
|
||||||
|
= note: outer attributes, like `#[test]`, annotate the item following them
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue