Skip to content

Commit

Permalink
Auto merge of #116077 - matthiaskrgr:rollup-2y1buzg, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #115770 (Match on elem first while building move paths)
 - #115999 (Capture scrutinee of if let guards correctly)
 - #116056 (Make unsized casts illegal)
 - #116061 (Remove TaKO8Ki from review rotation)
 - #116062 (Change `start` to `#[start]` in some diagnosis)
 - #116067 (Open the FileEncoder file for reading and writing)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 22, 2023
2 parents aadb571 + efee13a commit e4133ba
Show file tree
Hide file tree
Showing 23 changed files with 334 additions and 67 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0647.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
```
20 changes: 10 additions & 10 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -735,15 +738,13 @@ 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) {
return Err(CastError::ForeignNonExhaustiveAdt);
}
}
}

match (t_from, t_cast) {
// These types have invariants! can't cast into them.
(_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
145 changes: 113 additions & 32 deletions compiler/rustc_mir_dataflow/src/move_paths/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,44 +115,125 @@ 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(..)),
},
));
match elem {
ProjectionElem::Deref => 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.is_box() {
bug!("Adt should be a box type when Place is deref");
}
}
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!("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) {
return Err(MoveError::cannot_move_out_of(
self.loc,
InteriorOfTypeWithDestructor { container_ty: place_ty },
));
}
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!(
"When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
),
},
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(..)),
},
));
}
ty::Array(_, _) => (),
_ => bug!("Unexpected type {:#?}", place_ty.is_array()),
}
}

ty::Array(..) => {
if let ProjectionElem::Index(..) = elem {
ProjectionElem::Index(_) => match place_ty.kind() {
ty::Array(..) => {
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(
self.loc,
InteriorOfSliceOrArray {
ty: place_ty,
is_index: matches!(elem, ProjectionElem::Index(..)),
},
));
}
_ => bug!("Unexpected type {place_ty:#?}"),
},
// `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
base =
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_serialize/src/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,16 @@ pub struct FileEncoder {

impl FileEncoder {
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
// 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(()),
})
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/issue-68523-start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions tests/ui/async-await/issue-68523-start.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/cast/unsized-struct-cast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub struct Data([u8]);

fn main(){
const _: *const Data = &[] as *const Data;
//~^ ERROR: casting `&[_; 0]` as `*const Data` is invalid
}
9 changes: 9 additions & 0 deletions tests/ui/cast/unsized-struct-cast.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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<E>) {
| ----- move occurs because `value` has type `Box<E>`, 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`.
Original file line number Diff line number Diff line change
@@ -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<E>) {
| ----- move occurs because `value` has type `Box<E>`, 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`.
Loading

0 comments on commit e4133ba

Please sign in to comment.