Skip to content

Rollup of 4 pull requests #88662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 5, 2021
140 changes: 119 additions & 21 deletions compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use super::{AttrWrapper, Capturing, Parser, PathStyle};
use super::{AttrWrapper, Capturing, ForceCollect, Parser, PathStyle};
use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast_pretty::pprust;
use rustc_errors::{error_code, PResult};
use rustc_span::{sym, Span};
use rustc_errors::{error_code, DiagnosticBuilder, PResult};
use rustc_span::{sym, BytePos, Span};
use std::convert::TryInto;

use tracing::debug;
Expand All @@ -25,6 +25,12 @@ pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPo
prev_attr_sp: None,
};

enum OuterAttributeType {
DocComment,
DocBlockComment,
Attribute,
}

impl<'a> Parser<'a> {
/// Parses attributes that appear before an item.
pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
Expand All @@ -49,18 +55,32 @@ impl<'a> Parser<'a> {
Some(self.parse_attribute(inner_parse_policy)?)
} else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
if attr_style != ast::AttrStyle::Outer {
self.sess
.span_diagnostic
.struct_span_err_with_code(
self.token.span,
"expected outer doc comment",
error_code!(E0753),
)
.note(
"inner doc comments like this (starting with \
`//!` or `/*!`) can only appear before items",
)
.emit();
let span = self.token.span;
let mut err = self.sess.span_diagnostic.struct_span_err_with_code(
span,
"expected outer doc comment",
error_code!(E0753),
);
if let Some(replacement_span) = self.annotate_following_item_if_applicable(
&mut err,
span,
match comment_kind {
token::CommentKind::Line => OuterAttributeType::DocComment,
token::CommentKind::Block => OuterAttributeType::DocBlockComment,
},
) {
err.note(
"inner doc comments like this (starting with `//!` or `/*!`) can \
only appear before items",
);
err.span_suggestion_verbose(
replacement_span,
"you might have meant to write a regular comment",
String::new(),
rustc_errors::Applicability::MachineApplicable,
);
}
err.emit();
}
self.bump();
just_parsed_doc_comment = true;
Expand Down Expand Up @@ -97,7 +117,7 @@ impl<'a> Parser<'a> {
inner_parse_policy, self.token
);
let lo = self.token.span;
// Attributse can't have attributes of their own
// Attributes can't have attributes of their own [Editor's note: not with that attitude]
self.collect_tokens_no_attrs(|this| {
if this.eat(&token::Pound) {
let style = if this.eat(&token::Not) {
Expand Down Expand Up @@ -125,6 +145,75 @@ impl<'a> Parser<'a> {
})
}

fn annotate_following_item_if_applicable(
&self,
err: &mut DiagnosticBuilder<'_>,
span: Span,
attr_type: OuterAttributeType,
) -> Option<Span> {
let mut snapshot = self.clone();
let lo = span.lo()
+ BytePos(match attr_type {
OuterAttributeType::Attribute => 1,
_ => 2,
});
let hi = lo + BytePos(1);
let replacement_span = span.with_lo(lo).with_hi(hi);
if let OuterAttributeType::DocBlockComment | OuterAttributeType::DocComment = attr_type {
snapshot.bump();
}
loop {
// skip any other attributes, we want the item
if snapshot.token.kind == token::Pound {
if let Err(mut err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) {
err.cancel();
return Some(replacement_span);
}
} else {
break;
}
}
match snapshot.parse_item_common(
AttrWrapper::empty(),
true,
false,
|_| true,
ForceCollect::No,
) {
Ok(Some(item)) => {
let attr_name = match attr_type {
OuterAttributeType::Attribute => "attribute",
_ => "doc comment",
};
err.span_label(
item.span,
&format!("the inner {} doesn't annotate this {}", attr_name, item.kind.descr()),
);
err.span_suggestion_verbose(
replacement_span,
&format!(
"to annotate the {}, change the {} from inner to outer style",
item.kind.descr(),
attr_name
),
(match attr_type {
OuterAttributeType::Attribute => "",
OuterAttributeType::DocBlockComment => "*",
OuterAttributeType::DocComment => "/",
})
.to_string(),
rustc_errors::Applicability::MachineApplicable,
);
return None;
}
Err(mut item_err) => {
item_err.cancel();
}
Ok(None) => {}
}
Some(replacement_span)
}

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 {
let prev_attr_note =
Expand All @@ -138,11 +227,20 @@ impl<'a> Parser<'a> {
}

diag.note(
"inner attributes, like `#![no_std]`, annotate the item enclosing them, \
and are usually found at the beginning of source files. \
Outer attributes, like `#[test]`, annotate the item following them.",
)
.emit();
"inner attributes, like `#![no_std]`, annotate the item enclosing them, and \
are usually found at the beginning of source files",
);
if self
.annotate_following_item_if_applicable(
&mut diag,
attr_sp,
OuterAttributeType::Attribute,
)
.is_some()
{
diag.note("outer attributes, like `#[test]`, annotate the item following them");
};
diag.emit();
}
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ok(s) if s.starts_with('<') => sugg,
_ => format!("<{}>", sugg),
};
let replace = String::from("use `dyn`");
let sugg_label = "use `dyn`";
if self.sess().edition() >= Edition::Edition2021 {
let mut err = rustc_errors::struct_span_err!(
self.sess(),
Expand All @@ -956,8 +956,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
err.span_suggestion(
self_ty.span,
&sugg,
replace,
sugg_label,
sugg,
Applicability::MachineApplicable,
)
.emit();
Expand All @@ -968,7 +968,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_ty.span,
|lint| {
let mut db = lint.build(msg);
db.span_suggestion(self_ty.span, &replace, sugg, app);
db.span_suggestion(self_ty.span, sugg_label, sugg, app);
db.emit()
},
);
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl<T, A: Allocator> RawVec<T, A> {
pub fn reserve(&mut self, len: usize, additional: usize) {
// Callers expect this function to be very cheap when there is already sufficient capacity.
// Therefore, we move all the resizing and error-handling logic from grow_amortized and
// handle_reserve behind a call, while making sure that the this function is likely to be
// handle_reserve behind a call, while making sure that this function is likely to be
// inlined as just a comparison and a call if the comparison fails.
#[cold]
fn do_reserve_and_handle<T, A: Allocator>(
Expand Down
20 changes: 18 additions & 2 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ impl Step for Std {
add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
}

// don't run on std twice with x.py clippy
if builder.kind == Kind::Clippy {
return;
}

// Then run cargo again, once we've put the rmeta files for the library
// crates into the sysroot. This is needed because e.g., core's tests
// depend on `libtest` -- Cargo presumes it will exist, but it doesn't
Expand All @@ -120,6 +125,7 @@ impl Step for Std {
target,
cargo_subcommand(builder.kind),
);

cargo.arg("--all-targets");
std_cargo(builder, target, compiler.stage, &mut cargo);

Expand Down Expand Up @@ -192,7 +198,12 @@ impl Step for Rustc {
cargo_subcommand(builder.kind),
);
rustc_cargo(builder, &mut cargo, target);
cargo.arg("--all-targets");

// For ./x.py clippy, don't run with --all-targets because
// linting tests and benchmarks can produce very noisy results
if builder.kind != Kind::Clippy {
cargo.arg("--all-targets");
}

// Explicitly pass -p for all compiler krates -- this will force cargo
// to also check the tests/benches/examples for these crates, rather
Expand Down Expand Up @@ -313,7 +324,12 @@ macro_rules! tool_check_step {
$source_type,
&[],
);
cargo.arg("--all-targets");

// For ./x.py clippy, don't run with --all-targets because
// linting tests and benchmarks can produce very noisy results
if builder.kind != Kind::Clippy {
cargo.arg("--all-targets");
}

// Enable internal lints for clippy and rustdoc
// NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]`
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/editions/dyn-trait-sugg-2021.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// edition:2021

trait Foo<T> {}

impl<T> dyn Foo<T> {
fn hi(_x: T) {}
}

fn main() {
Foo::hi(123);
//~^ ERROR trait objects without an explicit `dyn` are deprecated
}
9 changes: 9 additions & 0 deletions src/test/ui/editions/dyn-trait-sugg-2021.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0783]: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-trait-sugg-2021.rs:10:5
|
LL | Foo::hi(123);
| ^^^ help: use `dyn`: `<dyn Foo>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0783`.
Loading