Auto merge of #139814 - matthiaskrgr:rollup-lxkkcz6, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #139127 (Fix up partial res of segment in primitive resolution hack) - #139392 (Detect and provide suggestion for `&raw EXPR`) - #139767 (Visit place in `BackwardIncompatibleDropHint` statement) - #139777 (Remove `define_debug_via_print` for `ExistentialProjection`, use regular structural debug impl) - #139796 (ptr docs: add missing backtics around 'usize') - #139801 (Add myself to mailmap) - #139804 (use `realpath` in `bootstrap.py` when creating build-dir) - #139807 (Improve wording of post-merge report) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
990039ec53
24 changed files with 259 additions and 41 deletions
1
.mailmap
1
.mailmap
|
@ -292,6 +292,7 @@ James Hinshelwood <jameshinshelwood1@gmail.com> <james.hinshelwood@bigpayme.com>
|
|||
James Miller <bladeon@gmail.com> <james@aatch.net>
|
||||
James Perry <james.austin.perry@gmail.com>
|
||||
James Sanderson <zofrex@gmail.com>
|
||||
Jamie Hill-Daniel <jamie@hill-daniel.co.uk> <clubby789@gmail.com>
|
||||
Jana Dönszelmann <jana@donsz.nl>
|
||||
Jana Dönszelmann <jana@donsz.nl> <jonathan@donsz.nl>
|
||||
Jana Dönszelmann <jana@donsz.nl> <jonabent@gmail.com>
|
||||
|
|
|
@ -120,6 +120,17 @@ impl Path {
|
|||
Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
|
||||
}
|
||||
|
||||
pub fn is_ident(&self, name: Symbol) -> bool {
|
||||
if let [segment] = self.segments.as_ref()
|
||||
&& segment.args.is_none()
|
||||
&& segment.ident.name == name
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_global(&self) -> bool {
|
||||
self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
|
||||
}
|
||||
|
|
|
@ -77,6 +77,9 @@ pub(crate) fn categorize(context: PlaceContext) -> Option<DefUse> {
|
|||
// Debug info is neither def nor use.
|
||||
PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None,
|
||||
|
||||
// Backwards incompatible drop hint is not a use, just a marker for linting.
|
||||
PlaceContext::NonUse(NonUseContext::BackwardIncompatibleDropHint) => None,
|
||||
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => {
|
||||
bug!("These statements are not allowed in this MIR phase")
|
||||
}
|
||||
|
|
|
@ -1286,7 +1286,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
|||
error_reported
|
||||
}
|
||||
|
||||
/// Through #123739, backward incompatible drops (BIDs) are introduced.
|
||||
/// Through #123739, `BackwardIncompatibleDropHint`s (BIDs) are introduced.
|
||||
/// We would like to emit lints whether borrow checking fails at these future drop locations.
|
||||
#[instrument(level = "debug", skip(self, state))]
|
||||
fn check_backward_incompatible_drop(
|
||||
|
|
|
@ -859,7 +859,7 @@ impl Debug for Statement<'_> {
|
|||
BackwardIncompatibleDropHint { ref place, reason: _ } => {
|
||||
// For now, we don't record the reason because there is only one use case,
|
||||
// which is to report breaking change in drop order by Edition 2024
|
||||
write!(fmt, "backward incompatible drop({place:?})")
|
||||
write!(fmt, "BackwardIncompatibleDropHint({place:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -457,9 +457,15 @@ macro_rules! make_mir_visitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
StatementKind::BackwardIncompatibleDropHint { place, .. } => {
|
||||
self.visit_place(
|
||||
place,
|
||||
PlaceContext::NonUse(NonUseContext::BackwardIncompatibleDropHint),
|
||||
location
|
||||
);
|
||||
}
|
||||
StatementKind::ConstEvalCounter => {}
|
||||
StatementKind::Nop => {}
|
||||
StatementKind::BackwardIncompatibleDropHint { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1348,6 +1354,8 @@ pub enum NonUseContext {
|
|||
AscribeUserTy(ty::Variance),
|
||||
/// The data of a user variable, for debug info.
|
||||
VarDebugInfo,
|
||||
/// A `BackwardIncompatibleDropHint` statement, meant for edition 2024 lints.
|
||||
BackwardIncompatibleDropHint,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -1422,7 +1430,9 @@ impl PlaceContext {
|
|||
use NonUseContext::*;
|
||||
match self {
|
||||
PlaceContext::MutatingUse(_) => ty::Invariant,
|
||||
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
|
||||
PlaceContext::NonUse(
|
||||
StorageDead | StorageLive | VarDebugInfo | BackwardIncompatibleDropHint,
|
||||
) => ty::Invariant,
|
||||
PlaceContext::NonMutatingUse(
|
||||
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | RawBorrow
|
||||
| Projection,
|
||||
|
|
|
@ -35,7 +35,8 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
|
|||
// MIR building, and are not needed after InstrumentCoverage.
|
||||
CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
|
||||
)
|
||||
| StatementKind::FakeRead(..) => statement.make_nop(),
|
||||
| StatementKind::FakeRead(..)
|
||||
| StatementKind::BackwardIncompatibleDropHint { .. } => statement.make_nop(),
|
||||
StatementKind::Assign(box (
|
||||
_,
|
||||
Rvalue::Cast(
|
||||
|
|
|
@ -597,20 +597,6 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
|
||||
if let StatementKind::BackwardIncompatibleDropHint { place, reason: _ } =
|
||||
&mut statement.kind
|
||||
{
|
||||
self.visit_local(
|
||||
&mut place.local,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
location,
|
||||
);
|
||||
} else {
|
||||
self.super_statement(statement, location);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
|
||||
*l = self.map[*l].unwrap();
|
||||
}
|
||||
|
|
|
@ -609,6 +609,8 @@ impl<'a> Parser<'a> {
|
|||
// FIXME: translation requires list formatting (for `expect`)
|
||||
let mut err = self.dcx().struct_span_err(self.token.span, msg_exp);
|
||||
|
||||
self.label_expected_raw_ref(&mut err);
|
||||
|
||||
// Look for usages of '=>' where '>=' was probably intended
|
||||
if self.token == token::FatArrow
|
||||
&& expected.iter().any(|tok| matches!(tok, TokenType::Operator | TokenType::Le))
|
||||
|
@ -750,6 +752,25 @@ impl<'a> Parser<'a> {
|
|||
Err(err)
|
||||
}
|
||||
|
||||
/// Adds a label when `&raw EXPR` was written instead of `&raw const EXPR`/`&raw mut EXPR`.
|
||||
///
|
||||
/// Given that not all parser diagnostics flow through `expected_one_of_not_found`, this
|
||||
/// label may need added to other diagnostics emission paths as needed.
|
||||
pub(super) fn label_expected_raw_ref(&mut self, err: &mut Diag<'_>) {
|
||||
if self.prev_token.is_keyword(kw::Raw)
|
||||
&& self.expected_token_types.contains(TokenType::KwMut)
|
||||
&& self.expected_token_types.contains(TokenType::KwConst)
|
||||
&& self.token.can_begin_expr()
|
||||
{
|
||||
err.span_suggestions(
|
||||
self.prev_token.span.shrink_to_hi(),
|
||||
"`&raw` must be followed by `const` or `mut` to be a raw reference expression",
|
||||
[" const".to_string(), " mut".to_string()],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the current token or the previous token are misspelled keywords
|
||||
/// and adds a helpful suggestion.
|
||||
fn check_for_misspelled_kw(&self, err: &mut Diag<'_>, expected: &[TokenType]) {
|
||||
|
|
|
@ -827,6 +827,18 @@ impl<'a> Parser<'a> {
|
|||
if let Some(lt) = lifetime {
|
||||
self.error_remove_borrow_lifetime(span, lt.ident.span.until(expr.span));
|
||||
}
|
||||
|
||||
// Add expected tokens if we parsed `&raw` as an expression.
|
||||
// This will make sure we see "expected `const`, `mut`", and
|
||||
// guides recovery in case we write `&raw expr`.
|
||||
if borrow_kind == ast::BorrowKind::Ref
|
||||
&& mutbl == ast::Mutability::Not
|
||||
&& matches!(&expr.kind, ExprKind::Path(None, p) if p.is_ident(kw::Raw))
|
||||
{
|
||||
self.expected_token_types.insert(TokenType::KwMut);
|
||||
self.expected_token_types.insert(TokenType::KwConst);
|
||||
}
|
||||
|
||||
Ok((span, ExprKind::AddrOf(borrow_kind, mutbl, expr)))
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,11 @@ impl<'a> Parser<'a> {
|
|||
let prev = self.prev_token.span;
|
||||
let sp = self.token.span;
|
||||
let mut e = self.dcx().struct_span_err(sp, msg);
|
||||
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
|
||||
self.label_expected_raw_ref(&mut e);
|
||||
|
||||
let do_not_suggest_help = self.token.is_keyword(kw::In)
|
||||
|| self.token == token::Colon
|
||||
|| self.prev_token.is_keyword(kw::Raw);
|
||||
|
||||
// Check to see if the user has written something like
|
||||
//
|
||||
|
|
|
@ -4606,6 +4606,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
// Fix up partial res of segment from `resolve_path` call.
|
||||
if let Some(id) = path[0].id {
|
||||
self.r.partial_res_map.insert(id, PartialRes::new(Res::PrimTy(prim)));
|
||||
}
|
||||
|
||||
PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1)
|
||||
}
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
|
||||
|
|
|
@ -60,7 +60,7 @@ define_display_via_print!(
|
|||
PatternKind,
|
||||
);
|
||||
|
||||
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection, PatternKind);
|
||||
define_debug_via_print!(TraitRef, ExistentialTraitRef, PatternKind);
|
||||
|
||||
impl<I: Interner, T> fmt::Display for OutlivesPredicate<I, T>
|
||||
where
|
||||
|
|
|
@ -374,7 +374,7 @@ impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
|
|||
}
|
||||
|
||||
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
|
|
|
@ -278,7 +278,7 @@
|
|||
//! ### Using Strict Provenance
|
||||
//!
|
||||
//! Most code needs no changes to conform to strict provenance, as the only really concerning
|
||||
//! operation is casts from usize to a pointer. For code which *does* cast a `usize` to a pointer,
|
||||
//! operation is casts from `usize` to a pointer. For code which *does* cast a `usize` to a pointer,
|
||||
//! the scope of the change depends on exactly what you're doing.
|
||||
//!
|
||||
//! In general, you just need to make sure that if you want to convert a `usize` address to a
|
||||
|
|
|
@ -1331,7 +1331,7 @@ def bootstrap(args):
|
|||
build.check_vendored_status()
|
||||
|
||||
if not os.path.exists(build.build_dir):
|
||||
os.makedirs(build.build_dir)
|
||||
os.makedirs(os.path.realpath(build.build_dir))
|
||||
|
||||
# Fetch/build the bootstrap
|
||||
build.download_toolchain()
|
||||
|
|
|
@ -520,23 +520,27 @@ fn report_test_diffs(
|
|||
}
|
||||
|
||||
if doctest_count > 0 {
|
||||
let prefix =
|
||||
if doctest_count < original_diff_count { "Additionally, " } else { "" };
|
||||
println!(
|
||||
"\nAdditionally, {doctest_count} doctest {} were found. These are ignored, as they are noisy.",
|
||||
"\n{prefix}{doctest_count} doctest {} were found. These are ignored, as they are noisy.",
|
||||
pluralize("diff", doctest_count)
|
||||
);
|
||||
}
|
||||
|
||||
// Now print the job group index
|
||||
println!("\n**Job group index**\n");
|
||||
for (group, jobs) in job_index.into_iter().enumerate() {
|
||||
println!(
|
||||
"- {}: {}",
|
||||
format_job_group(group as u64),
|
||||
jobs.iter()
|
||||
.map(|j| format_job_link(job_info_resolver, job_metrics, j))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
if !job_index.is_empty() {
|
||||
println!("\n**Job group index**\n");
|
||||
for (group, jobs) in job_index.into_iter().enumerate() {
|
||||
println!(
|
||||
"- {}: {}",
|
||||
format_job_group(group as u64),
|
||||
jobs.iter()
|
||||
.map(|j| format_job_link(job_info_resolver, job_metrics, j))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -73,9 +73,6 @@ fn method_1(_1: Guard) -> () {
|
|||
}
|
||||
|
||||
bb7: {
|
||||
backward incompatible drop(_2);
|
||||
backward incompatible drop(_4);
|
||||
backward incompatible drop(_5);
|
||||
goto -> bb21;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,6 @@ fn method_1(_1: Guard) -> () {
|
|||
}
|
||||
|
||||
bb7: {
|
||||
backward incompatible drop(_2);
|
||||
backward incompatible drop(_4);
|
||||
backward incompatible drop(_5);
|
||||
goto -> bb21;
|
||||
}
|
||||
|
||||
|
|
31
tests/ui/parser/recover/raw-no-const-mut.rs
Normal file
31
tests/ui/parser/recover/raw-no-const-mut.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
fn a() {
|
||||
let x = &raw 1;
|
||||
//~^ ERROR expected one of
|
||||
}
|
||||
|
||||
fn b() {
|
||||
[&raw const 1, &raw 2]
|
||||
//~^ ERROR expected one of
|
||||
//~| ERROR cannot find value `raw` in this scope
|
||||
//~| ERROR cannot take address of a temporary
|
||||
}
|
||||
|
||||
fn c() {
|
||||
if x == &raw z {}
|
||||
//~^ ERROR expected `{`
|
||||
}
|
||||
|
||||
fn d() {
|
||||
f(&raw 2);
|
||||
//~^ ERROR expected one of
|
||||
//~| ERROR cannot find value `raw` in this scope
|
||||
//~| ERROR cannot find function `f` in this scope
|
||||
}
|
||||
|
||||
fn e() {
|
||||
let x;
|
||||
x = &raw 1;
|
||||
//~^ ERROR expected one of
|
||||
}
|
||||
|
||||
fn main() {}
|
109
tests/ui/parser/recover/raw-no-const-mut.stderr
Normal file
109
tests/ui/parser/recover/raw-no-const-mut.stderr
Normal file
|
@ -0,0 +1,109 @@
|
|||
error: expected one of `!`, `.`, `::`, `;`, `?`, `const`, `else`, `mut`, `{`, or an operator, found `1`
|
||||
--> $DIR/raw-no-const-mut.rs:2:18
|
||||
|
|
||||
LL | let x = &raw 1;
|
||||
| ^ expected one of 10 possible tokens
|
||||
|
|
||||
help: `&raw` must be followed by `const` or `mut` to be a raw reference expression
|
||||
|
|
||||
LL | let x = &raw const 1;
|
||||
| +++++
|
||||
LL | let x = &raw mut 1;
|
||||
| +++
|
||||
|
||||
error: expected one of `!`, `,`, `.`, `::`, `?`, `]`, `const`, `mut`, `{`, or an operator, found `2`
|
||||
--> $DIR/raw-no-const-mut.rs:7:25
|
||||
|
|
||||
LL | [&raw const 1, &raw 2]
|
||||
| ^ expected one of 10 possible tokens
|
||||
|
|
||||
help: `&raw` must be followed by `const` or `mut` to be a raw reference expression
|
||||
|
|
||||
LL | [&raw const 1, &raw const 2]
|
||||
| +++++
|
||||
LL | [&raw const 1, &raw mut 2]
|
||||
| +++
|
||||
help: missing `,`
|
||||
|
|
||||
LL | [&raw const 1, &raw, 2]
|
||||
| +
|
||||
|
||||
error: expected `{`, found `z`
|
||||
--> $DIR/raw-no-const-mut.rs:14:18
|
||||
|
|
||||
LL | if x == &raw z {}
|
||||
| ^ expected `{`
|
||||
|
|
||||
note: the `if` expression is missing a block after this condition
|
||||
--> $DIR/raw-no-const-mut.rs:14:8
|
||||
|
|
||||
LL | if x == &raw z {}
|
||||
| ^^^^^^^^^
|
||||
help: `&raw` must be followed by `const` or `mut` to be a raw reference expression
|
||||
|
|
||||
LL | if x == &raw const z {}
|
||||
| +++++
|
||||
LL | if x == &raw mut z {}
|
||||
| +++
|
||||
|
||||
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `const`, `mut`, `{`, or an operator, found `2`
|
||||
--> $DIR/raw-no-const-mut.rs:19:12
|
||||
|
|
||||
LL | f(&raw 2);
|
||||
| ^ expected one of 10 possible tokens
|
||||
|
|
||||
help: `&raw` must be followed by `const` or `mut` to be a raw reference expression
|
||||
|
|
||||
LL | f(&raw const 2);
|
||||
| +++++
|
||||
LL | f(&raw mut 2);
|
||||
| +++
|
||||
help: missing `,`
|
||||
|
|
||||
LL | f(&raw, 2);
|
||||
| +
|
||||
|
||||
error: expected one of `!`, `.`, `::`, `;`, `?`, `const`, `mut`, `{`, `}`, or an operator, found `1`
|
||||
--> $DIR/raw-no-const-mut.rs:27:14
|
||||
|
|
||||
LL | x = &raw 1;
|
||||
| ^ expected one of 10 possible tokens
|
||||
|
|
||||
help: `&raw` must be followed by `const` or `mut` to be a raw reference expression
|
||||
|
|
||||
LL | x = &raw const 1;
|
||||
| +++++
|
||||
LL | x = &raw mut 1;
|
||||
| +++
|
||||
|
||||
error[E0425]: cannot find value `raw` in this scope
|
||||
--> $DIR/raw-no-const-mut.rs:7:21
|
||||
|
|
||||
LL | [&raw const 1, &raw 2]
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `raw` in this scope
|
||||
--> $DIR/raw-no-const-mut.rs:19:8
|
||||
|
|
||||
LL | f(&raw 2);
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error[E0745]: cannot take address of a temporary
|
||||
--> $DIR/raw-no-const-mut.rs:7:17
|
||||
|
|
||||
LL | [&raw const 1, &raw 2]
|
||||
| ^ temporary value
|
||||
|
||||
error[E0425]: cannot find function `f` in this scope
|
||||
--> $DIR/raw-no-const-mut.rs:19:5
|
||||
|
|
||||
LL | fn a() {
|
||||
| ------ similarly named function `a` defined here
|
||||
...
|
||||
LL | f(&raw 2);
|
||||
| ^ help: a function with a similar name exists: `a`
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0745.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
1
tests/ui/resolve/auxiliary/empty.rs
Normal file
1
tests/ui/resolve/auxiliary/empty.rs
Normal file
|
@ -0,0 +1 @@
|
|||
// Intentionally empty.
|
8
tests/ui/resolve/prim-crate-partial-res.rs
Normal file
8
tests/ui/resolve/prim-crate-partial-res.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
//@ aux-build: empty.rs
|
||||
|
||||
extern crate empty as usize;
|
||||
|
||||
fn foo() -> usize<()> { 0 }
|
||||
//~^ ERROR type arguments are not allowed on builtin type `usize`
|
||||
|
||||
fn main() {}
|
17
tests/ui/resolve/prim-crate-partial-res.stderr
Normal file
17
tests/ui/resolve/prim-crate-partial-res.stderr
Normal file
|
@ -0,0 +1,17 @@
|
|||
error[E0109]: type arguments are not allowed on builtin type `usize`
|
||||
--> $DIR/prim-crate-partial-res.rs:5:19
|
||||
|
|
||||
LL | fn foo() -> usize<()> { 0 }
|
||||
| ----- ^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on builtin type `usize`
|
||||
|
|
||||
help: primitive type `usize` doesn't have generic parameters
|
||||
|
|
||||
LL - fn foo() -> usize<()> { 0 }
|
||||
LL + fn foo() -> usize { 0 }
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0109`.
|
Loading…
Add table
Add a link
Reference in a new issue