From 4271383e1d7ccc5dcd95bd130182e722e9a8ca2a Mon Sep 17 00:00:00 2001 From: Veera Date: Sun, 5 May 2024 17:39:07 -0400 Subject: [PATCH 1/6] Update Tests --- ...ync-block-control-flow-static-semantics.rs | 4 +- ...block-control-flow-static-semantics.stderr | 8 +-- .../break-inside-coroutine-issue-124495.rs | 26 +++++++ ...break-inside-coroutine-issue-124495.stderr | 69 +++++++++++++++++++ 4 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 tests/ui/coroutine/break-inside-coroutine-issue-124495.rs create mode 100644 tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.rs b/tests/ui/async-await/async-block-control-flow-static-semantics.rs index 0ef7cb7574a..6e04c535cf1 100644 --- a/tests/ui/async-await/async-block-control-flow-static-semantics.rs +++ b/tests/ui/async-await/async-block-control-flow-static-semantics.rs @@ -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 }; } } diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr index c89671cc481..ce0d003f014 100644 --- a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -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 diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs new file mode 100644 index 00000000000..5d93db56722 --- /dev/null +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs @@ -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 +} diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr new file mode 100644 index 00000000000..a7f37fad35e --- /dev/null +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr @@ -0,0 +1,69 @@ +error[E0267]: `break` inside `async` function + --> $DIR/break-inside-coroutine-issue-124495.rs:8:5 + | +LL | async fn async_fn() { + | _____________________- +LL | | break; + | | ^^^^^ cannot `break` inside `async` function +LL | | } + | |_- enclosing `async` function + +error[E0267]: `break` inside `gen` function + --> $DIR/break-inside-coroutine-issue-124495.rs:12:5 + | +LL | gen fn gen_fn() { + | _________________- +LL | | break; + | | ^^^^^ cannot `break` inside `gen` function +LL | | } + | |_- enclosing `gen` function + +error[E0267]: `break` inside `async gen` function + --> $DIR/break-inside-coroutine-issue-124495.rs:16:5 + | +LL | async gen fn async_gen_fn() { + | _____________________________- +LL | | break; + | | ^^^^^ cannot `break` inside `async gen` function +LL | | } + | |_- enclosing `async gen` function + +error[E0267]: `break` inside `async` block + --> $DIR/break-inside-coroutine-issue-124495.rs:20:21 + | +LL | let _ = async { break; }; + | --------^^^^^--- + | | | + | | cannot `break` inside `async` block + | enclosing `async` block + +error[E0267]: `break` inside `async` closure + --> $DIR/break-inside-coroutine-issue-124495.rs:21:24 + | +LL | let _ = async || { break; }; + | --^^^^^--- + | | | + | | cannot `break` inside `async` closure + | enclosing `async` closure + +error[E0267]: `break` inside `gen` block + --> $DIR/break-inside-coroutine-issue-124495.rs:23:19 + | +LL | let _ = gen { break; }; + | ------^^^^^--- + | | | + | | cannot `break` inside `gen` block + | enclosing `gen` block + +error[E0267]: `break` inside `async gen` block + --> $DIR/break-inside-coroutine-issue-124495.rs:25:25 + | +LL | let _ = async gen { break; }; + | ------------^^^^^--- + | | | + | | cannot `break` inside `async gen` block + | enclosing `async gen` block + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0267`. From a8f2e33eec57d56477c45396e4860f92247f353a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 May 2024 23:12:22 -0400 Subject: [PATCH 2/6] Add more ICEs due to malformed diagnostic::on_unimplemented --- .../auxiliary/bad_on_unimplemented.rs | 26 +++++++++++++++- .../malformed_foreign_on_unimplemented.rs | 31 +++++++++++++++++++ .../on_unimplemented_ice.rs | 17 ---------- .../on_unimplemented_ice.stderr | 17 ---------- 4 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs delete mode 100644 tests/ui/diagnostic_namespace/on_unimplemented_ice.rs delete mode 100644 tests/ui/diagnostic_namespace/on_unimplemented_ice.stderr diff --git a/tests/ui/diagnostic_namespace/auxiliary/bad_on_unimplemented.rs b/tests/ui/diagnostic_namespace/auxiliary/bad_on_unimplemented.rs index 4a5fca43e36..e44c7e4e850 100644 --- a/tests/ui/diagnostic_namespace/auxiliary/bad_on_unimplemented.rs +++ b/tests/ui/diagnostic_namespace/auxiliary/bad_on_unimplemented.rs @@ -1,2 +1,26 @@ #[diagnostic::on_unimplemented(aa = "broken")] -pub trait Test {} +pub trait MissingAttr {} + +#[diagnostic::on_unimplemented(label = "a", label = "b")] +pub trait DuplicateAttr {} + +#[diagnostic::on_unimplemented = "broken"] +pub trait NotMetaList {} + +#[diagnostic::on_unimplemented] +pub trait Empty {} + +#[diagnostic::on_unimplemented {}] +pub trait WrongDelim {} + +#[diagnostic::on_unimplemented(label = "{A:.3}")] +pub trait BadFormatter {} + +#[diagnostic::on_unimplemented(label = "test {}")] +pub trait NoImplicitArgs {} + +#[diagnostic::on_unimplemented(label = "{missing}")] +pub trait MissingArg {} + +#[diagnostic::on_unimplemented(label = "{_}")] +pub trait BadArg {} diff --git a/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs new file mode 100644 index 00000000000..8b7467a17d0 --- /dev/null +++ b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs @@ -0,0 +1,31 @@ +//@ edition:2021 +//@ aux-build:bad_on_unimplemented.rs + +// Do not ICE when encountering a malformed `#[diagnostic::on_unimplemented]` annotation in a +// dependency when incorrectly used (#124651). + +extern crate bad_on_unimplemented; + +use bad_on_unimplemented::*; + +fn missing_attr(_: T) {} +fn duplicate_attr(_: T) {} +fn not_meta_list(_: T) {} +fn empty(_: T) {} +fn wrong_delim(_: T) {} +fn bad_formatter>(_: T) {} +fn no_implicit_args(_: T) {} +fn missing_arg(_: T) {} +fn bad_arg(_: T) {} + +fn main() { + missing_attr(()); //~ ERROR E0277 + duplicate_attr(()); //~ ERROR E0277 + not_meta_list(()); //~ ERROR E0277 + empty(()); //~ ERROR E0277 + wrong_delim(()); //~ ERROR E0277 + bad_formatter(()); //~ ERROR E0277 + no_implicit_args(()); //~ ERROR E0277 + missing_arg(()); //~ ERROR E0277 + bad_arg(()); //~ ERROR E0277 +} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented_ice.rs b/tests/ui/diagnostic_namespace/on_unimplemented_ice.rs deleted file mode 100644 index 8969f5030e2..00000000000 --- a/tests/ui/diagnostic_namespace/on_unimplemented_ice.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ edition:2021 -//@ compile-flags:--test -//@ aux-build:bad_on_unimplemented.rs - -// Do not ICE when encountering a malformed `#[diagnostic::on_unimplemented]` annotation in a -// dependency when incorrectly used (#124651). - -extern crate bad_on_unimplemented; - -use bad_on_unimplemented::Test; - -fn breakage(_: T) {} - -#[test] -fn test() { - breakage(1); //~ ERROR E0277 -} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented_ice.stderr b/tests/ui/diagnostic_namespace/on_unimplemented_ice.stderr deleted file mode 100644 index 1c0da96abd9..00000000000 --- a/tests/ui/diagnostic_namespace/on_unimplemented_ice.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: the trait bound `{integer}: Test` is not satisfied - --> $DIR/on_unimplemented_ice.rs:16:14 - | -LL | breakage(1); - | -------- ^ the trait `Test` is not implemented for `{integer}` - | | - | required by a bound introduced by this call - | -note: required by a bound in `breakage` - --> $DIR/on_unimplemented_ice.rs:12:16 - | -LL | fn breakage(_: T) {} - | ^^^^ required by this bound in `breakage` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. From 7dbdbaaa8e4ce77f9b2f1428c82f7166fe6f02fb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 May 2024 23:12:36 -0400 Subject: [PATCH 3/6] Fix ICEs in diagnostic::on_unimplemented --- .../error_reporting/on_unimplemented.rs | 120 +++++++++------- .../malformed_foreign_on_unimplemented.stderr | 134 ++++++++++++++++++ 2 files changed, 203 insertions(+), 51 deletions(-) create mode 100644 tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index f1eb5b7e826..4b49e014c0f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -350,12 +350,14 @@ fn maybe_emit_warning<'tcx>( 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 }, + ); + } } } } @@ -639,30 +641,38 @@ fn parse_attribute( 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) @@ -791,12 +801,14 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara || 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) => { @@ -812,15 +824,17 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara 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(), @@ -842,12 +856,14 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara // `{: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(), @@ -870,12 +886,14 @@ fn verify(&self, tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result<(), ErrorGuara // 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(); diff --git a/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr new file mode 100644 index 00000000000..c3e56550b70 --- /dev/null +++ b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr @@ -0,0 +1,134 @@ +error[E0277]: the trait bound `(): bad_on_unimplemented::MissingAttr` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:22:18 + | +LL | missing_attr(()); + | ------------ ^^ the trait `bad_on_unimplemented::MissingAttr` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `missing_attr` + --> $DIR/malformed_foreign_on_unimplemented.rs:11:20 + | +LL | fn missing_attr(_: T) {} + | ^^^^^^^^^^^ required by this bound in `missing_attr` + +error[E0277]: the trait bound `(): bad_on_unimplemented::DuplicateAttr` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:23:20 + | +LL | duplicate_attr(()); + | -------------- ^^ a + | | + | required by a bound introduced by this call + | + = help: the trait `bad_on_unimplemented::DuplicateAttr` is not implemented for `()` +note: required by a bound in `duplicate_attr` + --> $DIR/malformed_foreign_on_unimplemented.rs:12:22 + | +LL | fn duplicate_attr(_: T) {} + | ^^^^^^^^^^^^^ required by this bound in `duplicate_attr` + +error[E0277]: the trait bound `(): bad_on_unimplemented::NotMetaList` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:24:19 + | +LL | not_meta_list(()); + | ------------- ^^ the trait `bad_on_unimplemented::NotMetaList` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `not_meta_list` + --> $DIR/malformed_foreign_on_unimplemented.rs:13:21 + | +LL | fn not_meta_list(_: T) {} + | ^^^^^^^^^^^ required by this bound in `not_meta_list` + +error[E0277]: the trait bound `(): bad_on_unimplemented::Empty` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:25:11 + | +LL | empty(()); + | ----- ^^ the trait `bad_on_unimplemented::Empty` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `empty` + --> $DIR/malformed_foreign_on_unimplemented.rs:14:13 + | +LL | fn empty(_: T) {} + | ^^^^^ required by this bound in `empty` + +error[E0277]: the trait bound `(): bad_on_unimplemented::WrongDelim` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:26:17 + | +LL | wrong_delim(()); + | ----------- ^^ the trait `bad_on_unimplemented::WrongDelim` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `wrong_delim` + --> $DIR/malformed_foreign_on_unimplemented.rs:15:19 + | +LL | fn wrong_delim(_: T) {} + | ^^^^^^^^^^ required by this bound in `wrong_delim` + +error[E0277]: the trait bound `(): bad_on_unimplemented::BadFormatter<()>` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:27:19 + | +LL | bad_formatter(()); + | ------------- ^^ () + | | + | required by a bound introduced by this call + | + = help: the trait `bad_on_unimplemented::BadFormatter<()>` is not implemented for `()` +note: required by a bound in `bad_formatter` + --> $DIR/malformed_foreign_on_unimplemented.rs:16:21 + | +LL | fn bad_formatter>(_: T) {} + | ^^^^^^^^^^^^^^^^ required by this bound in `bad_formatter` + +error[E0277]: the trait bound `(): bad_on_unimplemented::NoImplicitArgs` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:28:22 + | +LL | no_implicit_args(()); + | ---------------- ^^ test {} + | | + | required by a bound introduced by this call + | + = help: the trait `bad_on_unimplemented::NoImplicitArgs` is not implemented for `()` +note: required by a bound in `no_implicit_args` + --> $DIR/malformed_foreign_on_unimplemented.rs:17:24 + | +LL | fn no_implicit_args(_: T) {} + | ^^^^^^^^^^^^^^ required by this bound in `no_implicit_args` + +error[E0277]: the trait bound `(): bad_on_unimplemented::MissingArg` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:29:17 + | +LL | missing_arg(()); + | ----------- ^^ {missing} + | | + | required by a bound introduced by this call + | + = help: the trait `bad_on_unimplemented::MissingArg` is not implemented for `()` +note: required by a bound in `missing_arg` + --> $DIR/malformed_foreign_on_unimplemented.rs:18:19 + | +LL | fn missing_arg(_: T) {} + | ^^^^^^^^^^ required by this bound in `missing_arg` + +error[E0277]: the trait bound `(): bad_on_unimplemented::BadArg` is not satisfied + --> $DIR/malformed_foreign_on_unimplemented.rs:30:13 + | +LL | bad_arg(()); + | ------- ^^ {_} + | | + | required by a bound introduced by this call + | + = help: the trait `bad_on_unimplemented::BadArg` is not implemented for `()` +note: required by a bound in `bad_arg` + --> $DIR/malformed_foreign_on_unimplemented.rs:19:15 + | +LL | fn bad_arg(_: T) {} + | ^^^^^^ required by this bound in `bad_arg` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0277`. From c078a44247d733111d1737dfc0468b105ea91d55 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 7 May 2024 10:31:58 +0200 Subject: [PATCH 4/6] Migrate `run-make/rustdoc-map-file` to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/rustdoc-map-file/Makefile | 5 ----- tests/run-make/rustdoc-map-file/rmake.rs | 15 +++++++++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) delete mode 100644 tests/run-make/rustdoc-map-file/Makefile create mode 100644 tests/run-make/rustdoc-map-file/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f4ae7b06cdb..8ebcb439382 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -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 diff --git a/tests/run-make/rustdoc-map-file/Makefile b/tests/run-make/rustdoc-map-file/Makefile deleted file mode 100644 index 5cbf7747af6..00000000000 --- a/tests/run-make/rustdoc-map-file/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - $(RUSTDOC) -Z unstable-options --generate-redirect-map foo.rs -o "$(TMPDIR)/out" - "$(PYTHON)" validate_json.py "$(TMPDIR)/out" diff --git a/tests/run-make/rustdoc-map-file/rmake.rs b/tests/run-make/rustdoc-map-file/rmake.rs new file mode 100644 index 00000000000..aaa7fea0b6b --- /dev/null +++ b/tests/run-make/rustdoc-map-file/rmake.rs @@ -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()); +} From 0ca1a94b2bd58d19a1bd492300abd5bffe5263fb Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 8 May 2024 17:21:06 -0400 Subject: [PATCH 5/6] Handle field projections like slice indexing in invalid_reference_casting --- compiler/rustc_lint/src/reference_casting.rs | 3 ++- tests/ui/lint/reference_casting.rs | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 63d55a73a98..b80e90c25a3 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -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; } diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 3d0c36ca118..87a682249b0 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -255,6 +255,12 @@ unsafe fn slice_index(array: &mut [u8], offset: usize) { let a3 = a2 as *mut u64; unsafe { *a3 = 3 }; } + + unsafe fn field_access(v: &mut Vec3) { + let r = &mut v.0; + let ptr = r as *mut i32 as *mut Vec3; + unsafe { *ptr = Vec3(0, 0, 0) } + } } const RAW_PTR: *mut u8 = 1 as *mut u8; From 21ccec0cc8a5ee253f021cdc81e05dbab43e59e1 Mon Sep 17 00:00:00 2001 From: Veera Date: Sun, 5 May 2024 18:14:23 -0400 Subject: [PATCH 6/6] Fix Error Messages for `break` Inside Coroutines Previously, `break` inside `gen` blocks and functions were incorrectly identified to be enclosed by a closure. This PR fixes it by displaying an appropriate error message for async blocks, async closures, async functions, gen blocks, gen closures, gen functions, async gen blocks, async gen closures and async gen functions. Note: gen closure and async gen closure are not supported by the compiler yet but I have added an error message here assuming that they might be implemented in the future. Also, fixes grammar in a few places by replacing `inside of a $coroutine` with `inside a $coroutine`. --- compiler/rustc_passes/messages.ftl | 10 ++++----- compiler/rustc_passes/src/errors.rs | 10 +++++---- compiler/rustc_passes/src/loops.rs | 32 +++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 9d58d301e2b..3deefcaa06c 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -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 diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 65cad82cc8c..b8586e7e974 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -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)] diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 4b5c4dfe991..3b20112eab7 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -13,7 +13,7 @@ use rustc_span::{BytePos, Span}; use crate::errors::{ - BreakInsideAsyncBlock, BreakInsideClosure, BreakNonLoop, ContinueLabeledBlock, OutsideLoop, + BreakInsideClosure, BreakInsideCoroutine, BreakNonLoop, ContinueLabeledBlock, OutsideLoop, OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock, }; @@ -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, @@ -89,12 +89,10 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'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); @@ -227,8 +225,24 @@ fn require_break_cx(&self, name: &str, span: Span, break_span: Span) { 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 });