Skip to content

Commit

Permalink
Auto merge of #124916 - matthiaskrgr:rollup-vmpmt4u, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 4 pull requests

Successful merges:

 - #124777 (Fix Error Messages for `break` Inside Coroutines)
 - #124837 (Migrate `run-make/rustdoc-map-file` to rmake)
 - #124875 (Fix more ICEs in `diagnostic::on_unimplemented`)
 - #124908 (Handle field projections like slice indexing in invalid_reference_casting)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 9, 2024
2 parents 37dc766 + 48b1e1a commit 5f8c17d
Show file tree
Hide file tree
Showing 18 changed files with 417 additions and 117 deletions.
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

0 comments on commit 5f8c17d

Please sign in to comment.