Skip to content

Rollup of 4 pull requests #124916

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 10 commits into from
May 9, 2024
Merged
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/reference_casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ fn is_cast_to_bigger_memory_layout<'tcx>(

// if the current expr looks like this `&mut expr[index]` then just looking
// at `expr[index]` won't give us the underlying allocation, so we just skip it
if let ExprKind::Index(..) = e_alloc.kind {
// the same logic applies field access like `&mut expr.field`
if let ExprKind::Index(..) | ExprKind::Field(..) = e_alloc.kind {
return None;
}

Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ passes_attr_only_in_functions =
passes_both_ffi_const_and_pure =
`#[ffi_const]` function cannot be `#[ffi_pure]`

passes_break_inside_async_block =
`{$name}` inside of an `async` block
.label = cannot `{$name}` inside of an `async` block
.async_block_label = enclosing `async` block

passes_break_inside_closure =
`{$name}` inside of a closure
.label = cannot `{$name}` inside of a closure
.closure_label = enclosing closure

passes_break_inside_coroutine =
`{$name}` inside `{$kind}` {$source}
.label = cannot `{$name}` inside `{$kind}` {$source}
.coroutine_label = enclosing `{$kind}` {$source}

passes_break_non_loop =
`break` with value from a `{$kind}` loop
.label = can only break with a value inside `loop` or breakable block
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,14 +1086,16 @@ pub struct BreakInsideClosure<'a> {
}

#[derive(Diagnostic)]
#[diag(passes_break_inside_async_block, code = E0267)]
pub struct BreakInsideAsyncBlock<'a> {
#[diag(passes_break_inside_coroutine, code = E0267)]
pub struct BreakInsideCoroutine<'a> {
#[primary_span]
#[label]
pub span: Span,
#[label(passes_async_block_label)]
pub closure_span: Span,
#[label(passes_coroutine_label)]
pub coroutine_span: Span,
pub name: &'a str,
pub kind: &'a str,
pub source: &'a str,
}

#[derive(Diagnostic)]
Expand Down
32 changes: 23 additions & 9 deletions compiler/rustc_passes/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::{BytePos, Span};

use crate::errors::{
BreakInsideAsyncBlock, BreakInsideClosure, BreakNonLoop, ContinueLabeledBlock, OutsideLoop,
BreakInsideClosure, BreakInsideCoroutine, BreakNonLoop, ContinueLabeledBlock, OutsideLoop,
OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
};

Expand All @@ -23,7 +23,7 @@ enum Context {
Fn,
Loop(hir::LoopSource),
Closure(Span),
AsyncClosure(Span),
Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource },
UnlabeledBlock(Span),
LabeledBlock,
Constant,
Expand Down Expand Up @@ -89,12 +89,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
hir::ExprKind::Closure(&hir::Closure {
ref fn_decl, body, fn_decl_span, kind, ..
}) => {
// FIXME(coroutines): This doesn't handle coroutines correctly
let cx = match kind {
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Block,
)) => AsyncClosure(fn_decl_span),
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(kind, source)) => {
Coroutine { coroutine_span: fn_decl_span, kind, source }
}
_ => Closure(fn_decl_span),
};
self.visit_fn_decl(fn_decl);
Expand Down Expand Up @@ -227,8 +225,24 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
Closure(closure_span) => {
self.sess.dcx().emit_err(BreakInsideClosure { span, closure_span, name });
}
AsyncClosure(closure_span) => {
self.sess.dcx().emit_err(BreakInsideAsyncBlock { span, closure_span, name });
Coroutine { coroutine_span, kind, source } => {
let kind = match kind {
hir::CoroutineDesugaring::Async => "async",
hir::CoroutineDesugaring::Gen => "gen",
hir::CoroutineDesugaring::AsyncGen => "async gen",
};
let source = match source {
hir::CoroutineSource::Block => "block",
hir::CoroutineSource::Closure => "closure",
hir::CoroutineSource::Fn => "function",
};
self.sess.dcx().emit_err(BreakInsideCoroutine {
span,
coroutine_span,
name,
kind,
source,
});
}
UnlabeledBlock(block_span) if is_break && block_span.eq_ctxt(break_span) => {
let suggestion = Some(OutsideLoopSuggestion { block_span, break_span });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,14 @@ impl IgnoredDiagnosticOption {
option_name: &'static str,
) {
if let (Some(new_item), Some(old_item)) = (new, old) {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
);
}
}
}
}
Expand Down Expand Up @@ -639,30 +641,38 @@ impl<'tcx> OnUnimplementedDirective {
AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span),
};

tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
report_span,
MalformedOnUnimplementedAttrLint::new(report_span),
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
report_span,
MalformedOnUnimplementedAttrLint::new(report_span),
);
}
Ok(None)
}
} else if is_diagnostic_namespace_variant {
match &attr.kind {
AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
attr.span,
MalformedOnUnimplementedAttrLint::new(attr.span),
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
attr.span,
MalformedOnUnimplementedAttrLint::new(attr.span),
);
}
}
_ => {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
attr.span,
MissingOptionsForOnUnimplementedAttr,
)
}
}
_ => tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
attr.span,
MissingOptionsForOnUnimplementedAttr,
),
};

Ok(None)
Expand Down Expand Up @@ -791,12 +801,14 @@ impl<'tcx> OnUnimplementedFormatString {
|| format_spec.precision_span.is_some()
|| format_spec.fill_span.is_some())
{
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
InvalidFormatSpecifier,
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
InvalidFormatSpecifier,
);
}
}
match a.position {
Position::ArgumentNamed(s) => {
Expand All @@ -812,15 +824,17 @@ impl<'tcx> OnUnimplementedFormatString {
s if generics.params.iter().any(|param| param.name == s) => (),
s => {
if self.is_diagnostic_namespace_variant {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
UnknownFormatParameterForOnUnimplementedAttr {
argument_name: s,
trait_name,
},
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
UnknownFormatParameterForOnUnimplementedAttr {
argument_name: s,
trait_name,
},
);
}
} else {
result = Err(struct_span_code_err!(
tcx.dcx(),
Expand All @@ -842,12 +856,14 @@ impl<'tcx> OnUnimplementedFormatString {
// `{:1}` and `{}` are not to be used
Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => {
if self.is_diagnostic_namespace_variant {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
DisallowedPositionalArgument,
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
DisallowedPositionalArgument,
);
}
} else {
let reported = struct_span_code_err!(
tcx.dcx(),
Expand All @@ -870,12 +886,14 @@ impl<'tcx> OnUnimplementedFormatString {
// so that users are aware that something is not correct
for e in parser.errors {
if self.is_diagnostic_namespace_variant {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
self.span,
WrappedParserError { description: e.description, label: e.label },
);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
self.span,
WrappedParserError { description: e.description, label: e.label },
);
}
} else {
let reported =
struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description,).emit();
Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ run-make/rlib-format-packed-bundled-libs/Makefile
run-make/rmeta-preferred/Makefile
run-make/rustc-macro-dep-files/Makefile
run-make/rustdoc-io-error/Makefile
run-make/rustdoc-map-file/Makefile
run-make/rustdoc-output-path/Makefile
run-make/rustdoc-scrape-examples-invalid-expr/Makefile
run-make/rustdoc-scrape-examples-macros/Makefile
Expand Down
5 changes: 0 additions & 5 deletions tests/run-make/rustdoc-map-file/Makefile

This file was deleted.

15 changes: 15 additions & 0 deletions tests/run-make/rustdoc-map-file/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use run_make_support::{rustdoc, tmp_dir};
use std::process::Command;

fn main() {
let out_dir = tmp_dir().join("out");
rustdoc()
.input("foo.rs")
.arg("-Zunstable-options")
.arg("--generate-redirect-map")
.output(&out_dir)
.run();
// FIXME (GuillaumeGomez): Port the python script to Rust as well.
let python = std::env::var("PYTHON").unwrap_or("python".into());
assert!(Command::new(python).arg("validate_json.py").arg(&out_dir).status().unwrap().success());
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ async fn return_targets_async_block_not_async_fn() -> u8 {

fn no_break_in_async_block() {
async {
break 0u8; //~ ERROR `break` inside of an `async` block
break 0u8; //~ ERROR `break` inside `async` block
};
}

fn no_break_in_async_block_even_with_outer_loop() {
loop {
async {
break 0u8; //~ ERROR `break` inside of an `async` block
break 0u8; //~ ERROR `break` inside `async` block
};
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
error[E0267]: `break` inside of an `async` block
error[E0267]: `break` inside `async` block
--> $DIR/async-block-control-flow-static-semantics.rs:32:9
|
LL | / async {
LL | | break 0u8;
| | ^^^^^^^^^ cannot `break` inside of an `async` block
| | ^^^^^^^^^ cannot `break` inside `async` block
LL | | };
| |_____- enclosing `async` block

error[E0267]: `break` inside of an `async` block
error[E0267]: `break` inside `async` block
--> $DIR/async-block-control-flow-static-semantics.rs:39:13
|
LL | / async {
LL | | break 0u8;
| | ^^^^^^^^^ cannot `break` inside of an `async` block
| | ^^^^^^^^^ cannot `break` inside `async` block
LL | | };
| |_________- enclosing `async` block

Expand Down
26 changes: 26 additions & 0 deletions tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ edition: 2024
//@ compile-flags: -Z unstable-options

#![feature(gen_blocks)]
#![feature(async_closure)]

async fn async_fn() {
break; //~ ERROR `break` inside `async` function
}

gen fn gen_fn() {
break; //~ ERROR `break` inside `gen` function
}

async gen fn async_gen_fn() {
break; //~ ERROR `break` inside `async gen` function
}

fn main() {
let _ = async { break; }; //~ ERROR `break` inside `async` block
let _ = async || { break; }; //~ ERROR `break` inside `async` closure

let _ = gen { break; }; //~ ERROR `break` inside `gen` block

let _ = async gen { break; }; //~ ERROR `break` inside `async gen` block
}
Loading
Loading