Auto merge of #115615 - matthiaskrgr:rollup-49fosdf, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #114511 (Remove the unhelpful let binding diag comes from FormatArguments)
 - #115473 (Add explanatory note to 'expected item' error)
 - #115574 (Replace `rustc_data_structures` dependency with `rustc_index` in `rustc_parse_format`)
 - #115578 (Clarify cryptic comments)
 - #115587 (fix #115348)
 - #115596 (A small change)
 - #115598 (Fix log formatting in bootstrap)
 - #115605 (Better Debug for `Ty` in smir)
 - #115614 (Fix minor grammar typo)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-09-06 18:16:06 +00:00
commit 4e2116296c
33 changed files with 193 additions and 39 deletions

View File

@ -4175,7 +4175,7 @@ dependencies = [
name = "rustc_parse_format"
version = "0.0.0"
dependencies = [
"rustc_data_structures",
"rustc_index",
"rustc_lexer",
]

View File

@ -2130,21 +2130,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// misleading users in cases like `tests/ui/nll/borrowed-temporary-error.rs`.
/// We could expand the analysis to suggest hoising all of the relevant parts of
/// the users' code to make the code compile, but that could be too much.
struct NestedStatementVisitor {
/// We found the `prop_expr` by the way to check whether the expression is a `FormatArguments`,
/// which is a special case since it's generated by the compiler.
struct NestedStatementVisitor<'tcx> {
span: Span,
current: usize,
found: usize,
prop_expr: Option<&'tcx hir::Expr<'tcx>>,
}
impl<'tcx> Visitor<'tcx> for NestedStatementVisitor {
fn visit_block(&mut self, block: &hir::Block<'tcx>) {
impl<'tcx> Visitor<'tcx> for NestedStatementVisitor<'tcx> {
fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
self.current += 1;
walk_block(self, block);
self.current -= 1;
}
fn visit_expr(&mut self, expr: &hir::Expr<'tcx>) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
if self.span == expr.span.source_callsite() {
self.found = self.current;
if self.prop_expr.is_none() {
self.prop_expr = Some(expr);
}
}
walk_expr(self, expr);
}
@ -2162,22 +2168,40 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
span: proper_span,
current: 0,
found: 0,
prop_expr: None,
};
visitor.visit_stmt(stmt);
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
let expr_ty: Option<Ty<'_>> = visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs());
let is_format_arguments_item =
if let Some(expr_ty) = expr_ty
&& let ty::Adt(adt, _) = expr_ty.kind() {
self.infcx.tcx.lang_items().get(LangItem::FormatArguments) == Some(adt.did())
} else {
false
};
if visitor.found == 0
&& stmt.span.contains(proper_span)
&& let Some(p) = sm.span_to_margin(stmt.span)
&& let Ok(s) = sm.span_to_snippet(proper_span)
{
let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
err.multipart_suggestion_verbose(
msg,
vec![
(stmt.span.shrink_to_lo(), addition),
(proper_span, "binding".to_string()),
],
Applicability::MaybeIncorrect,
);
if !is_format_arguments_item {
let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
err.multipart_suggestion_verbose(
msg,
vec![
(stmt.span.shrink_to_lo(), addition),
(proper_span, "binding".to_string()),
],
Applicability::MaybeIncorrect,
);
} else {
err.note("the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used");
err.note("to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>");
}
suggested = true;
break;
}

View File

@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
};
let def_id = trait_predicate.trait_ref.def_id;
if cx.tcx.lang_items().drop_trait() == Some(def_id) {
// Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern.
// Explicitly allow `impl Drop`, a drop-guards-as-unnameable-type pattern.
if trait_predicate.trait_ref.self_ty().is_impl_trait() {
continue;
}

View File

@ -4363,7 +4363,7 @@ declare_lint! {
/// pub struct S;
/// }
///
/// pub fn get_voldemort() -> m::S { m::S }
/// pub fn get_unnameable() -> m::S { m::S }
/// # fn main() {}
/// ```
///

View File

@ -2857,7 +2857,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Uint(..)
| ty::Float(..) => true,
// The voldemort ZSTs are fine.
// ZST which can't be named are fine.
ty::FnDef(..) => true,
ty::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(),

View File

@ -483,7 +483,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResu
// `mir_built` force this.
let body = &tcx.mir_built(def).borrow();
if body.is_custom_mir() {
if body.is_custom_mir() || body.tainted_by_errors.is_some() {
return tcx.arena.alloc(UnsafetyCheckResult {
violations: Vec::new(),
used_unsafe_blocks: Default::default(),

View File

@ -106,7 +106,7 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
let mut cursor_snapshot = self.cursor_snapshot.clone();
let tokens =
std::iter::once((FlatToken::Token(self.start_token.0.clone()), self.start_token.1))
.chain((0..self.num_calls).map(|_| {
.chain(std::iter::repeat_with(|| {
let token = cursor_snapshot.next();
(FlatToken::Token(token.0), token.1)
}))

View File

@ -73,12 +73,16 @@ impl<'a> Parser<'a> {
if !self.maybe_consume_incorrect_semicolon(&items) {
let msg = format!("expected item, found {token_str}");
let mut err = self.struct_span_err(self.token.span, msg);
let label = if self.is_kw_followed_by_ident(kw::Let) {
"consider using `const` or `static` instead of `let` for global variables"
let span = self.token.span;
if self.is_kw_followed_by_ident(kw::Let) {
err.span_label(
span,
"consider using `const` or `static` instead of `let` for global variables",
);
} else {
"expected item"
err.span_label(span, "expected item")
.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
};
err.span_label(self.token.span, label);
return Err(err);
}
}

View File

@ -5,4 +5,4 @@ edition = "2021"
[dependencies]
rustc_lexer = { path = "../rustc_lexer" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_index = { path = "../rustc_index", default-features = false }

View File

@ -1011,7 +1011,7 @@ fn unescape_string(string: &str) -> Option<string::String> {
// Assert a reasonable size for `Piece`
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Piece<'_>, 16);
rustc_index::static_assert_size!(Piece<'_>, 16);
#[cfg(test)]
mod tests;

View File

@ -4,10 +4,17 @@ use super::{
with, AllocId, DefId,
};
use crate::rustc_internal::Opaque;
use std::fmt::{self, Debug, Formatter};
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone)]
pub struct Ty(pub usize);
impl Debug for Ty {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Ty").field("id", &self.0).field("kind", &self.kind()).finish()
}
}
impl Ty {
pub fn kind(&self) -> TyKind {
with(|context| context.ty_kind(*self))

View File

@ -37,7 +37,7 @@ responsibilities they cover:
The panic and error systems are not entirely distinct. Often times errors
that are anticipated runtime failures in an API might instead represent bugs
to a caller. For these situations the standard library provides APIs for
constructing panics with an `Error` as it's source.
constructing panics with an `Error` as its source.
* [`Result::unwrap`]
* [`Result::expect`]

View File

@ -1019,7 +1019,7 @@ impl Build {
fn info(&self, msg: &str) {
match self.config.dry_run {
DryRun::SelfCheck => return,
DryRun::SelfCheck => (),
DryRun::Disabled | DryRun::UserSelected => {
println!("{msg}");
}

View File

@ -598,9 +598,9 @@ fn configure_cmake(
} else if target.contains("linux") {
cfg.define("CMAKE_SYSTEM_NAME", "Linux");
} else {
builder.info(
builder.info(&format!(
"could not determine CMAKE_SYSTEM_NAME from the target `{target}`, build may fail",
);
));
}
// When cross-compiling we should also set CMAKE_SYSTEM_VERSION, but in

View File

@ -0,0 +1,16 @@
#![allow(dead_code)]
fn bar<'a>(_: std::fmt::Arguments<'a>) {}
fn main() {
let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3);
//~^ ERROR temporary value dropped while borrowed
bar(x);
let foo = format_args!("{}", "hi");
//~^ ERROR temporary value dropped while borrowed
bar(foo);
let foo = format_args!("hi"); // no placeholder in arguments, so no error
bar(foo);
}

View File

@ -0,0 +1,33 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/issue-114374-invalid-help-fmt-args.rs:5:13
|
LL | let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
...
LL | bar(x);
| - borrow later used here
|
= note: the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used
= note: to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>
= note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0716]: temporary value dropped while borrowed
--> $DIR/issue-114374-invalid-help-fmt-args.rs:10:15
|
LL | let foo = format_args!("{}", "hi");
| ^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
LL |
LL | bar(foo);
| --- borrow later used here
|
= note: the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used
= note: to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>
= note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0716`.

View File

@ -2,13 +2,13 @@
#![deny(drop_bounds)]
// As a special exemption, `impl Drop` in the return position raises no error.
// This allows a convenient way to return an unnamed drop guard.
fn voldemort_type() -> impl Drop {
struct Voldemort;
impl Drop for Voldemort {
fn unnameable_type() -> impl Drop {
struct Unnameable;
impl Drop for Unnameable {
fn drop(&mut self) {}
}
Voldemort
Unnameable
}
fn main() {
let _ = voldemort_type();
let _ = unnameable_type();
}

View File

@ -11,6 +11,8 @@ error: expected item, found keyword `pub`
|
LL | default pub const async unsafe extern fn err() {}
| ^^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 2 previous errors

View File

@ -11,6 +11,8 @@ error: expected item, found reserved keyword `do`
|
LL | default do
| ^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 2 previous errors

View File

@ -35,6 +35,8 @@ error: expected item, found keyword `unsafe`
|
LL | default unsafe FAIL
| ^^^^^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 6 previous errors

View File

@ -11,6 +11,8 @@ error: expected item, found `==`
|
LL | B == 2
| ^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 2 previous errors

View File

@ -0,0 +1 @@
5 //~ ERROR expected item, found `5`

View File

@ -0,0 +1,10 @@
error: expected item, found `5`
--> $DIR/issue-113110-non-item-at-module-root.rs:1:2
|
LL | 5
| ^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to previous error

View File

@ -3,6 +3,8 @@ error: expected item, found keyword `where`
|
LL | struct Bar<T> { x: T } where T: Copy
| ^^^^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to previous error

View File

@ -11,6 +11,8 @@ error: expected item, found `|`
|
LL | |
| ^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 2 previous errors

View File

@ -17,6 +17,8 @@ error: expected item, found `"\u\"`
|
LL | "\u\"
| ^^^^^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 3 previous errors

View File

@ -15,6 +15,8 @@ error: expected item, found `)`
|
LL | enum e{A((?'a a+?+l))}
| ^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 3 previous errors

View File

@ -3,6 +3,8 @@ error: expected item, found `[`
|
LL | [allow(unused_variables)]
| ^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to previous error

View File

@ -3,6 +3,8 @@ error: expected item, found reserved keyword `virtual`
|
LL | virtual struct SuperStruct {
| ^^^^^^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to previous error

View File

@ -20,10 +20,10 @@ mod m {
}
}
pub trait Voldemort<T> {}
pub trait Unnameable<T> {}
impl Voldemort<m::PubStruct> for i32 {}
impl Voldemort<m::PubE> for i32 {}
impl<T> Voldemort<T> for u32 where T: m::PubTr {}
impl Unnameable<m::PubStruct> for i32 {}
impl Unnameable<m::PubE> for i32 {}
impl<T> Unnameable<T> for u32 where T: m::PubTr {}
fn main() {}

View File

@ -11,6 +11,8 @@ error: expected item, found `(`
|
LL | pub(crate) () fn foo() {}
| ^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
error: aborting due to 2 previous errors

View File

@ -0,0 +1,16 @@
// Regression test for #115348.
unsafe fn uwu() {}
// Tests that the false-positive warning "unnecessary `unsafe` block"
// should not be reported, when the error "non-exhaustive patterns"
// appears.
fn foo(x: Option<u32>) {
match x {
//~^ ERROR non-exhaustive patterns: `None` not covered
Some(_) => unsafe { uwu() },
}
}
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0004]: non-exhaustive patterns: `None` not covered
--> $DIR/issue-115348-false-positive-warning-of-unnecessary-unsafe.rs:10:11
|
LL | match x {
| ^ pattern `None` not covered
|
note: `Option<u32>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<u32>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Some(_) => unsafe { uwu() },
LL ~ None => todo!(),
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0004`.