Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ James Hinshelwood <[email protected]> <[email protected]>
James Miller <[email protected]> <[email protected]>
James Perry <[email protected]>
James Sanderson <[email protected]>
Jamie Hill-Daniel <[email protected]> <[email protected]>
Jana Dönszelmann <[email protected]>
Jana Dönszelmann <[email protected]> <[email protected]>
Jana Dönszelmann <[email protected]> <[email protected]>
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_borrowck/src/def_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:?})")
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 { .. } => {}
}
}

Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
14 changes: 0 additions & 14 deletions compiler/rustc_mir_transform/src/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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]) {
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
}

Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
//
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/ir_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
26 changes: 15 additions & 11 deletions src/ci/citool/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(", ")
);
}
}
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ fn method_1(_1: Guard) -> () {
}

bb7: {
backward incompatible drop(_2);
backward incompatible drop(_4);
backward incompatible drop(_5);
goto -> bb21;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ fn method_1(_1: Guard) -> () {
}

bb7: {
backward incompatible drop(_2);
backward incompatible drop(_4);
backward incompatible drop(_5);
goto -> bb21;
}

Expand Down
31 changes: 31 additions & 0 deletions tests/ui/parser/recover/raw-no-const-mut.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Loading
Loading