From 22b1acb45500f34bb100f7da4d5e90fcc37bca92 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 12 Sep 2023 10:28:37 +0300 Subject: [PATCH 01/10] match on elem first --- .../src/move_paths/builder.rs | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 2e3b9577b5030..e5c627ade8e35 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -115,44 +115,56 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { let body = self.builder.body; let tcx = self.builder.tcx; let place_ty = place_ref.ty(body, tcx).ty; - match place_ty.kind() { - ty::Ref(..) | ty::RawPtr(..) => { - return Err(MoveError::cannot_move_out_of( - self.loc, - BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) }, - )); - } - ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => { - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfTypeWithDestructor { container_ty: place_ty }, - )); - } - ty::Adt(adt, _) if adt.is_union() => { - union_path.get_or_insert(base); - } - ty::Slice(_) => { - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfSliceOrArray { - ty: place_ty, - is_index: matches!(elem, ProjectionElem::Index(..)), - }, - )); - } - - ty::Array(..) => { - if let ProjectionElem::Index(..) = elem { + match elem { + ProjectionElem::Deref => match place_ty.kind() { + ty::Ref(..) | ty::RawPtr(..) => { return Err(MoveError::cannot_move_out_of( self.loc, - InteriorOfSliceOrArray { ty: place_ty, is_index: true }, + BorrowedContent { + target_place: place_ref.project_deeper(&[elem], tcx), + }, )); } - } - - _ => {} - }; + _ => (), + }, + ProjectionElem::Field(_, _) + | ProjectionElem::OpaqueCast(_) + | ProjectionElem::Downcast(_, _) => match place_ty.kind() { + ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => { + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfTypeWithDestructor { container_ty: place_ty }, + )); + } + ty::Adt(adt, _) if adt.is_union() => { + union_path.get_or_insert(base); + } + _ => (), + }, + ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Index(_) + | ProjectionElem::Subslice { .. } => match place_ty.kind() { + ty::Slice(_) => { + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { + ty: place_ty, + is_index: matches!(elem, ProjectionElem::Index(..)), + }, + )); + } + ty::Array(..) => { + if let ProjectionElem::Index(..) = elem { + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { ty: place_ty, is_index: true }, + )); + } + } + _ => (), + }, + } if union_path.is_none() { // inlined from add_move_path because of a borrowck conflict with the iterator base = From 0cb22a66eb577254b8a507ef75b7f10728b396ca Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 12 Sep 2023 21:09:29 +0300 Subject: [PATCH 02/10] very verbose error handling --- .../src/move_paths/builder.rs | 106 ++++++++++++++---- 1 file changed, 86 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index e5c627ade8e35..31efa26a6aae4 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -125,35 +125,88 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { }, )); } - _ => (), + ty::Adt(adt, _) => { + if !adt.is_box() { + bug!("Adt should be a box type"); + } + } + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Slice(_) + | ty::FnDef(_, _) + | ty::FnPtr(_) + | ty::Dynamic(_, _, _) + | ty::Closure(_, _) + | ty::Generator(_, _, _) + | ty::GeneratorWitness(_) + | ty::GeneratorWitnessMIR(_, _) + | ty::Never + | ty::Tuple(_) + | ty::Alias(_, _) + | ty::Param(_) + | ty::Bound(_, _) + | ty::Infer(_) + | ty::Error(_) + | ty::Placeholder(_) => bug!("Place has a wrong type {place_ty:#?}"), }, - ProjectionElem::Field(_, _) - | ProjectionElem::OpaqueCast(_) - | ProjectionElem::Downcast(_, _) => match place_ty.kind() { - ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => { + ProjectionElem::Field(_, _) => match place_ty.kind() { + ty::Adt(adt, _) if adt.has_dtor(tcx) => { return Err(MoveError::cannot_move_out_of( self.loc, InteriorOfTypeWithDestructor { container_ty: place_ty }, )); } - ty::Adt(adt, _) if adt.is_union() => { - union_path.get_or_insert(base); + ty::Adt(adt, _) => { + if adt.is_union() { + union_path.get_or_insert(base); + } } - - _ => (), + ty::Closure(_, _) | ty::Generator(_, _, _) | ty::Tuple(_) => (), + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::Ref(_, _, _) + | ty::FnDef(_, _) + | ty::FnPtr(_) + | ty::Dynamic(_, _, _) + | ty::GeneratorWitness(_) + | ty::GeneratorWitnessMIR(_, _) + | ty::Never + | ty::Alias(_, _) + | ty::Param(_) + | ty::Bound(_, _) + | ty::Infer(_) + | ty::Error(_) + | ty::Placeholder(_) => bug!("Place has a wrong type {place_ty:#?}"), }, - ProjectionElem::ConstantIndex { .. } - | ProjectionElem::Index(_) - | ProjectionElem::Subslice { .. } => match place_ty.kind() { - ty::Slice(_) => { - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfSliceOrArray { - ty: place_ty, - is_index: matches!(elem, ProjectionElem::Index(..)), - }, - )); + ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { + match place_ty.kind() { + ty::Slice(_) => { + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { + ty: place_ty, + is_index: matches!(elem, ProjectionElem::Index(..)), + }, + )); + } + _ => (), } + } + ProjectionElem::Index(_) => match place_ty.kind() { ty::Array(..) => { if let ProjectionElem::Index(..) = elem { return Err(MoveError::cannot_move_out_of( @@ -162,8 +215,21 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { )); } } + ty::Slice(_) => { + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { + ty: place_ty, + is_index: matches!(elem, ProjectionElem::Index(..)), + }, + )); + } _ => (), }, + // `OpaqueCast` only transmutes the type, so no moves there and + // `Downcast` only changes information about a `Place` without moving + // So it's safe to skip these. + ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (), } if union_path.is_none() { // inlined from add_move_path because of a borrowck conflict with the iterator From d6efedcaf578e67f07293349d2128c06043a239f Mon Sep 17 00:00:00 2001 From: ouz-a Date: Fri, 22 Sep 2023 11:21:55 +0300 Subject: [PATCH 03/10] remove inner match --- compiler/rustc_mir_dataflow/src/move_paths/builder.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 31efa26a6aae4..d19b1a902f44c 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -208,12 +208,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } ProjectionElem::Index(_) => match place_ty.kind() { ty::Array(..) => { - if let ProjectionElem::Index(..) = elem { - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfSliceOrArray { ty: place_ty, is_index: true }, - )); - } + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { ty: place_ty, is_index: true }, + )); } ty::Slice(_) => { return Err(MoveError::cannot_move_out_of( From 442c87a0b0168e644a40ef8ecd874c53fe7e04b8 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Fri, 22 Sep 2023 11:31:14 +0300 Subject: [PATCH 04/10] better bug message --- compiler/rustc_mir_dataflow/src/move_paths/builder.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index d19b1a902f44c..8732489418ae0 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -127,7 +127,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } ty::Adt(adt, _) => { if !adt.is_box() { - bug!("Adt should be a box type"); + bug!("Adt should be a box type when Place is deref"); } } ty::Bool @@ -153,7 +153,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { | ty::Bound(_, _) | ty::Infer(_) | ty::Error(_) - | ty::Placeholder(_) => bug!("Place has a wrong type {place_ty:#?}"), + | ty::Placeholder(_) => { + bug!("When Place is Deref it's type shouldn't be {place_ty:#?}") + } }, ProjectionElem::Field(_, _) => match place_ty.kind() { ty::Adt(adt, _) if adt.has_dtor(tcx) => { @@ -190,7 +192,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { | ty::Bound(_, _) | ty::Infer(_) | ty::Error(_) - | ty::Placeholder(_) => bug!("Place has a wrong type {place_ty:#?}"), + | ty::Placeholder(_) => bug!( + "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}" + ), }, ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { match place_ty.kind() { From d4ffb3b08aa11e3b012e7efc31b28b78e01ed4bc Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 20 Sep 2023 11:57:00 +0000 Subject: [PATCH 05/10] Capture scrutinee of if let guards correctly Previously we were always capturing by value. --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 10 ++-- .../match/if-let-guards-errors.e2018.stderr | 33 +++++++++++ .../match/if-let-guards-errors.e2021.stderr | 33 +++++++++++ .../match/if-let-guards-errors.rs | 37 +++++++++++++ .../match/if-let-guards.rs | 55 +++++++++++++++++++ 5 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr create mode 100644 tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr create mode 100644 tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs create mode 100644 tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 840910732d89f..8bc66ac5509be 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -664,10 +664,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { ); self.walk_pat(discr_place, arm.pat, arm.guard.is_some()); - if let Some(hir::Guard::If(e)) = arm.guard { - self.consume_expr(e) - } else if let Some(hir::Guard::IfLet(ref l)) = arm.guard { - self.consume_expr(l.init) + match arm.guard { + Some(hir::Guard::If(ref e)) => self.consume_expr(e), + Some(hir::Guard::IfLet(ref l)) => { + self.walk_local(l.init, l.pat, None, |t| t.borrow_expr(l.init, ty::ImmBorrow)) + } + None => {} } self.consume_expr(arm.body); diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr new file mode 100644 index 0000000000000..394629c000136 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr @@ -0,0 +1,33 @@ +error[E0505]: cannot move out of `value` because it is borrowed + --> $DIR/if-let-guards-errors.rs:16:13 + | +LL | let f = |x: &E| { + | ------- borrow of `value` occurs here +LL | match &x { +LL | E::Number(_) if let E::Number(ref mut n) = *value => { } + | ------ borrow occurs due to use in closure +... +LL | let x = value; + | ^^^^^ move out of `value` occurs here +LL | +LL | drop(f); + | - borrow later used here + +error[E0382]: use of moved value: `value` + --> $DIR/if-let-guards-errors.rs:28:13 + | +LL | fn if_let_move(value: Box) { + | ----- move occurs because `value` has type `Box`, which does not implement the `Copy` trait +LL | let f = |x: &E| { + | ------- value moved into closure here +LL | match &x { +LL | E::Number(_) if let E::String(s) = *value => { } + | ------ variable moved due to use in closure +... +LL | let x = value; + | ^^^^^ value used here after move + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0382, E0505. +For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr new file mode 100644 index 0000000000000..5672845019b8f --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr @@ -0,0 +1,33 @@ +error[E0505]: cannot move out of `value` because it is borrowed + --> $DIR/if-let-guards-errors.rs:16:13 + | +LL | let f = |x: &E| { + | ------- borrow of `*value` occurs here +LL | match &x { +LL | E::Number(_) if let E::Number(ref mut n) = *value => { } + | ------ borrow occurs due to use in closure +... +LL | let x = value; + | ^^^^^ move out of `value` occurs here +LL | +LL | drop(f); + | - borrow later used here + +error[E0382]: use of moved value: `value` + --> $DIR/if-let-guards-errors.rs:28:13 + | +LL | fn if_let_move(value: Box) { + | ----- move occurs because `value` has type `Box`, which does not implement the `Copy` trait +LL | let f = |x: &E| { + | ------- value moved into closure here +LL | match &x { +LL | E::Number(_) if let E::String(s) = *value => { } + | ------ variable moved due to use in closure +... +LL | let x = value; + | ^^^^^ value used here after move + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0382, E0505. +For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs new file mode 100644 index 0000000000000..17e38c033b168 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs @@ -0,0 +1,37 @@ +// Check the if let guards don't force capture by value +// revisions: e2018 e2021 +//[e2018] edition:2018 +//[e2021] edition:2021 + +#![feature(if_let_guard)] +#![allow(irrefutable_let_patterns)] + +fn if_let_ref_mut(mut value: Box) { + let f = |x: &E| { + match &x { + E::Number(_) if let E::Number(ref mut n) = *value => { } + _ => {} + } + }; + let x = value; + //~^ ERROR cannot move out of `value` because it is borrowed + drop(f); +} + +fn if_let_move(value: Box) { + let f = |x: &E| { + match &x { + E::Number(_) if let E::String(s) = *value => { } + _ => {} + } + }; + let x = value; + //~^ ERROR use of moved value: `value` +} + +enum E { + String(String), + Number(i32), +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs b/tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs new file mode 100644 index 0000000000000..fa331707be465 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs @@ -0,0 +1,55 @@ +// Check the if let guards don't force capture by value +// revisions: e2018 e2021 +// check-pass +//[e2018] edition:2018 +//[e2021] edition:2021 + +#![feature(if_let_guard)] +#![allow(irrefutable_let_patterns)] + +fn if_let_underscore(value: Box) { + |x: &E| { + match &x { + E::Number(_) if let _ = *value => { } + _ => {} + } + }; + let x = value; +} + +fn if_let_copy(value: Box) { + |x: &E| { + match &x { + E::Number(_) if let E::Number(n) = *value => { } + _ => {} + } + }; + let x = value; +} + +fn if_let_ref(value: Box) { + |x: &E| { + match &x { + E::Number(_) if let E::Number(ref n) = *value => { } + _ => {} + } + }; + let x = value; +} + +fn if_let_ref_mut(mut value: Box) { + |x: &E| { + match &x { + E::Number(_) if let E::Number(ref mut n) = *value => { } + _ => {} + } + }; + let x = value; +} + +enum E { + String(String), + Number(i32), +} + +fn main() {} From 63df126f59622f280dd34489eb7b3a03bdd7417d Mon Sep 17 00:00:00 2001 From: ouz-a Date: Fri, 22 Sep 2023 16:28:45 +0300 Subject: [PATCH 06/10] match array for constantindex and subslice --- .../src/move_paths/builder.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 8732489418ae0..213b81eaac9a4 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -158,13 +158,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } }, ProjectionElem::Field(_, _) => match place_ty.kind() { - ty::Adt(adt, _) if adt.has_dtor(tcx) => { - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfTypeWithDestructor { container_ty: place_ty }, - )); - } ty::Adt(adt, _) => { + if adt.has_dtor(tcx) { + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfTypeWithDestructor { container_ty: place_ty }, + )); + } if adt.is_union() { union_path.get_or_insert(base); } @@ -207,7 +207,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { }, )); } - _ => (), + ty::Array(_, _) => (), + _ => bug!("Unexpected type {:#?}", place_ty.is_array()), } } ProjectionElem::Index(_) => match place_ty.kind() { @@ -226,7 +227,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { }, )); } - _ => (), + _ => bug!("Unexpected type {place_ty:#?}"), }, // `OpaqueCast` only transmutes the type, so no moves there and // `Downcast` only changes information about a `Place` without moving From 8e06b25e3900b8b14d9043ff6d2b846199672b2b Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:31:19 +0200 Subject: [PATCH 07/10] Remove TaKO8Ki from reviewers --- triagebot.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 4a84f3caa95d2..dbced481993a9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -598,7 +598,6 @@ compiler-team = [ compiler-team-contributors = [ "@compiler-errors", "@jackh726", - "@TaKO8Ki", "@WaffleLapkin", "@b-naber", ] @@ -645,7 +644,6 @@ diagnostics = [ "@compiler-errors", "@davidtwco", "@oli-obk", - "@TaKO8Ki", ] parser = [ "@compiler-errors", From 17dfabff9c1d9dc34a07a7e4a8d18186d303a205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Fri, 22 Sep 2023 15:58:43 +0200 Subject: [PATCH 08/10] Change `start` to `#[start]` in some diagnosis They refer to a function with the `start` attribute, but not necessarily named `start`. --- .../src/error_codes/E0647.md | 2 +- compiler/rustc_hir_analysis/messages.ftl | 20 +++++++++---------- tests/ui/async-await/issue-68523-start.rs | 2 +- tests/ui/async-await/issue-68523-start.stderr | 4 ++-- tests/ui/error-codes/E0132.stderr | 4 ++-- tests/ui/error-codes/E0647.stderr | 4 ++-- tests/ui/issues/issue-50714-1.stderr | 4 ++-- .../rfc-2091-track-caller/error-with-start.rs | 2 +- .../error-with-start.stderr | 4 ++-- .../issue-108645-target-feature-on-start.rs | 2 +- ...ssue-108645-target-feature-on-start.stderr | 4 ++-- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0647.md b/compiler/rustc_error_codes/src/error_codes/E0647.md index 8ca6e777f301d..59bb47ba62a9f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0647.md +++ b/compiler/rustc_error_codes/src/error_codes/E0647.md @@ -7,7 +7,7 @@ Erroneous code example: #[start] fn start(_: isize, _: *const *const u8) -> isize where (): Copy { - //^ error: start function is not allowed to have a where clause + //^ error: `#[start]` function is not allowed to have a where clause 0 } ``` diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 1160290cdff59..2a68d745c7693 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -270,20 +270,20 @@ hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is hi hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable .help = add `#![feature(min_specialization)]` to the crate attributes to enable -hir_analysis_start_function_parameters = start function is not allowed to have type parameters - .label = start function cannot have type parameters +hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters + .label = `#[start]` function cannot have type parameters -hir_analysis_start_function_where = start function is not allowed to have a `where` clause - .label = start function cannot have a `where` clause +hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause + .label = `#[start]` function cannot have a `where` clause -hir_analysis_start_not_async = `start` is not allowed to be `async` - .label = `start` is not allowed to be `async` +hir_analysis_start_not_async = `#[start]` function is not allowed to be `async` + .label = `#[start]` is not allowed to be `async` -hir_analysis_start_not_target_feature = `start` is not allowed to have `#[target_feature]` - .label = `start` is not allowed to have `#[target_feature]` +hir_analysis_start_not_target_feature = `#[start]` function is not allowed to have `#[target_feature]` + .label = `#[start]` function is not allowed to have `#[target_feature]` -hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]` - .label = `start` is not allowed to be `#[track_caller]` +hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]` + .label = `#[start]` function is not allowed to be `#[track_caller]` hir_analysis_static_specialize = cannot specialize on `'static` lifetime diff --git a/tests/ui/async-await/issue-68523-start.rs b/tests/ui/async-await/issue-68523-start.rs index 2ced88a16cc45..5adc28b203a47 100644 --- a/tests/ui/async-await/issue-68523-start.rs +++ b/tests/ui/async-await/issue-68523-start.rs @@ -4,6 +4,6 @@ #[start] pub async fn start(_: isize, _: *const *const u8) -> isize { -//~^ ERROR `start` is not allowed to be `async` +//~^ ERROR `#[start]` function is not allowed to be `async` 0 } diff --git a/tests/ui/async-await/issue-68523-start.stderr b/tests/ui/async-await/issue-68523-start.stderr index 3a0a3b5dece10..7c06fe3400ee0 100644 --- a/tests/ui/async-await/issue-68523-start.stderr +++ b/tests/ui/async-await/issue-68523-start.stderr @@ -1,8 +1,8 @@ -error[E0752]: `start` is not allowed to be `async` +error[E0752]: `#[start]` function is not allowed to be `async` --> $DIR/issue-68523-start.rs:6:1 | LL | pub async fn start(_: isize, _: *const *const u8) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `start` is not allowed to be `async` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `#[start]` is not allowed to be `async` error: aborting due to previous error diff --git a/tests/ui/error-codes/E0132.stderr b/tests/ui/error-codes/E0132.stderr index c21363756b3e6..d4ddc07b52112 100644 --- a/tests/ui/error-codes/E0132.stderr +++ b/tests/ui/error-codes/E0132.stderr @@ -1,8 +1,8 @@ -error[E0132]: start function is not allowed to have type parameters +error[E0132]: `#[start]` function is not allowed to have type parameters --> $DIR/E0132.rs:4:5 | LL | fn f< T >() {} - | ^^^^^ start function cannot have type parameters + | ^^^^^ `#[start]` function cannot have type parameters error: aborting due to previous error diff --git a/tests/ui/error-codes/E0647.stderr b/tests/ui/error-codes/E0647.stderr index 08cedfaef04ce..9d1ab967127ad 100644 --- a/tests/ui/error-codes/E0647.stderr +++ b/tests/ui/error-codes/E0647.stderr @@ -1,8 +1,8 @@ -error[E0647]: start function is not allowed to have a `where` clause +error[E0647]: `#[start]` function is not allowed to have a `where` clause --> $DIR/E0647.rs:7:50 | LL | fn start(_: isize, _: *const *const u8) -> isize where (): Copy { - | ^^^^^^^^^^^^^^ start function cannot have a `where` clause + | ^^^^^^^^^^^^^^ `#[start]` function cannot have a `where` clause error: aborting due to previous error diff --git a/tests/ui/issues/issue-50714-1.stderr b/tests/ui/issues/issue-50714-1.stderr index 28469bee01714..bacd09b2ae11c 100644 --- a/tests/ui/issues/issue-50714-1.stderr +++ b/tests/ui/issues/issue-50714-1.stderr @@ -1,8 +1,8 @@ -error[E0647]: start function is not allowed to have a `where` clause +error[E0647]: `#[start]` function is not allowed to have a `where` clause --> $DIR/issue-50714-1.rs:9:50 | LL | fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { - | ^^^^^^^^^^^^^^^^^ start function cannot have a `where` clause + | ^^^^^^^^^^^^^^^^^ `#[start]` function cannot have a `where` clause error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs index 0cab47170631b..f0e111b578f9f 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs @@ -1,7 +1,7 @@ #![feature(start)] #[start] -#[track_caller] //~ ERROR `start` is not allowed to be `#[track_caller]` +#[track_caller] //~ ERROR `#[start]` function is not allowed to be `#[track_caller]` fn start(_argc: isize, _argv: *const *const u8) -> isize { panic!("{}: oh no", std::panic::Location::caller()); } diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr index 454c98ff93437..b6ef6215275e8 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr @@ -1,10 +1,10 @@ -error: `start` is not allowed to be `#[track_caller]` +error: `#[start]` function is not allowed to be `#[track_caller]` --> $DIR/error-with-start.rs:4:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ LL | fn start(_argc: isize, _argv: *const *const u8) -> isize { - | -------------------------------------------------------- `start` is not allowed to be `#[track_caller]` + | -------------------------------------------------------- `#[start]` function is not allowed to be `#[track_caller]` error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs index 50e8ce2fdd5ed..221c0416dbf70 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs @@ -5,5 +5,5 @@ #[start] #[target_feature(enable = "avx2")] -//~^ ERROR `start` is not allowed to have `#[target_feature]` +//~^ ERROR `#[start]` function is not allowed to have `#[target_feature]` fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 } diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr index 07687f3c7f4a2..b49f8afd960da 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr @@ -1,11 +1,11 @@ -error: `start` is not allowed to have `#[target_feature]` +error: `#[start]` function is not allowed to have `#[target_feature]` --> $DIR/issue-108645-target-feature-on-start.rs:7:1 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 } - | -------------------------------------------------------- `start` is not allowed to have `#[target_feature]` + | -------------------------------------------------------- `#[start]` function is not allowed to have `#[target_feature]` error: aborting due to previous error From 861448b426d2cc62a4f62cf173591f9bc7a6c7a3 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Fri, 22 Sep 2023 13:31:26 +0300 Subject: [PATCH 09/10] make unsized cast illegal --- compiler/rustc_hir_typeck/src/cast.rs | 5 +++-- tests/ui/cast/unsized-struct-cast.rs | 6 ++++++ tests/ui/cast/unsized-struct-cast.stderr | 9 +++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/ui/cast/unsized-struct-cast.rs create mode 100644 tests/ui/cast/unsized-struct-cast.stderr diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index fa779701e61ed..57cd88afcdcab 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -725,6 +725,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { }, // array-ptr-cast Ptr(mt) => { + if !fcx.type_is_sized_modulo_regions(fcx.param_env, mt.ty) { + return Err(CastError::IllegalCast); + } self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt) } _ => Err(CastError::NonScalar), @@ -735,7 +738,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { } _ => return Err(CastError::NonScalar), }; - if let ty::Adt(adt_def, _) = *self.expr_ty.kind() { if adt_def.did().krate != LOCAL_CRATE { if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) { @@ -743,7 +745,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } } - match (t_from, t_cast) { // These types have invariants! can't cast into them. (_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar), diff --git a/tests/ui/cast/unsized-struct-cast.rs b/tests/ui/cast/unsized-struct-cast.rs new file mode 100644 index 0000000000000..52bb6cedcd6d7 --- /dev/null +++ b/tests/ui/cast/unsized-struct-cast.rs @@ -0,0 +1,6 @@ +pub struct Data([u8]); + +fn main(){ + const _: *const Data = &[] as *const Data; + //~^ ERROR: casting `&[_; 0]` as `*const Data` is invalid +} diff --git a/tests/ui/cast/unsized-struct-cast.stderr b/tests/ui/cast/unsized-struct-cast.stderr new file mode 100644 index 0000000000000..79b3d973c32fd --- /dev/null +++ b/tests/ui/cast/unsized-struct-cast.stderr @@ -0,0 +1,9 @@ +error[E0606]: casting `&[_; 0]` as `*const Data` is invalid + --> $DIR/unsized-struct-cast.rs:4:28 + | +LL | const _: *const Data = &[] as *const Data; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0606`. From 09960e03194626738b3533b6c2d06a0c505117d3 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 22 Sep 2023 12:34:30 -0400 Subject: [PATCH 10/10] Open the FileEncoder file for reading and writing --- compiler/rustc_serialize/src/opaque.rs | 7 ++++++- tests/ui/stats/meta-stats.rs | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/ui/stats/meta-stats.rs diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 44855ae629c13..552554390515c 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -38,11 +38,16 @@ pub struct FileEncoder { impl FileEncoder { pub fn new>(path: P) -> io::Result { + // File::create opens the file for writing only. When -Zmeta-stats is enabled, the metadata + // encoder rewinds the file to inspect what was written. So we need to always open the file + // for reading and writing. + let file = File::options().read(true).write(true).create(true).truncate(true).open(path)?; + Ok(FileEncoder { buf: vec![0u8; BUF_SIZE].into_boxed_slice().try_into().unwrap(), buffered: 0, flushed: 0, - file: File::create(path)?, + file, res: Ok(()), }) } diff --git a/tests/ui/stats/meta-stats.rs b/tests/ui/stats/meta-stats.rs new file mode 100644 index 0000000000000..2d38e0882866d --- /dev/null +++ b/tests/ui/stats/meta-stats.rs @@ -0,0 +1,7 @@ +// build-pass +// dont-check-compiler-stderr +// compile-flags: -Zmeta-stats + +#![crate_type = "lib"] + +pub fn a() {}