Skip to content

Commit e4133ba

Browse files
committed
Auto merge of #116077 - matthiaskrgr:rollup-2y1buzg, r=matthiaskrgr
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
2 parents aadb571 + efee13a commit e4133ba

File tree

23 files changed

+334
-67
lines changed

23 files changed

+334
-67
lines changed

compiler/rustc_error_codes/src/error_codes/E0647.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Erroneous code example:
77
88
#[start]
99
fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
10-
//^ error: start function is not allowed to have a where clause
10+
//^ error: `#[start]` function is not allowed to have a where clause
1111
0
1212
}
1313
```

compiler/rustc_hir_analysis/messages.ftl

+10-10
Original file line numberDiff line numberDiff line change
@@ -270,20 +270,20 @@ hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is hi
270270
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
271271
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
272272
273-
hir_analysis_start_function_parameters = start function is not allowed to have type parameters
274-
.label = start function cannot have type parameters
273+
hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters
274+
.label = `#[start]` function cannot have type parameters
275275
276-
hir_analysis_start_function_where = start function is not allowed to have a `where` clause
277-
.label = start function cannot have a `where` clause
276+
hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause
277+
.label = `#[start]` function cannot have a `where` clause
278278
279-
hir_analysis_start_not_async = `start` is not allowed to be `async`
280-
.label = `start` is not allowed to be `async`
279+
hir_analysis_start_not_async = `#[start]` function is not allowed to be `async`
280+
.label = `#[start]` is not allowed to be `async`
281281
282-
hir_analysis_start_not_target_feature = `start` is not allowed to have `#[target_feature]`
283-
.label = `start` is not allowed to have `#[target_feature]`
282+
hir_analysis_start_not_target_feature = `#[start]` function is not allowed to have `#[target_feature]`
283+
.label = `#[start]` function is not allowed to have `#[target_feature]`
284284
285-
hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]`
286-
.label = `start` is not allowed to be `#[track_caller]`
285+
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
286+
.label = `#[start]` function is not allowed to be `#[track_caller]`
287287
288288
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
289289

compiler/rustc_hir_typeck/src/cast.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
725725
},
726726
// array-ptr-cast
727727
Ptr(mt) => {
728+
if !fcx.type_is_sized_modulo_regions(fcx.param_env, mt.ty) {
729+
return Err(CastError::IllegalCast);
730+
}
728731
self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt)
729732
}
730733
_ => Err(CastError::NonScalar),
@@ -735,15 +738,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
735738
}
736739
_ => return Err(CastError::NonScalar),
737740
};
738-
739741
if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
740742
if adt_def.did().krate != LOCAL_CRATE {
741743
if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
742744
return Err(CastError::ForeignNonExhaustiveAdt);
743745
}
744746
}
745747
}
746-
747748
match (t_from, t_cast) {
748749
// These types have invariants! can't cast into them.
749750
(_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
664664
);
665665
self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
666666

667-
if let Some(hir::Guard::If(e)) = arm.guard {
668-
self.consume_expr(e)
669-
} else if let Some(hir::Guard::IfLet(ref l)) = arm.guard {
670-
self.consume_expr(l.init)
667+
match arm.guard {
668+
Some(hir::Guard::If(ref e)) => self.consume_expr(e),
669+
Some(hir::Guard::IfLet(ref l)) => {
670+
self.walk_local(l.init, l.pat, None, |t| t.borrow_expr(l.init, ty::ImmBorrow))
671+
}
672+
None => {}
671673
}
672674

673675
self.consume_expr(arm.body);

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+113-32
Original file line numberDiff line numberDiff line change
@@ -115,44 +115,125 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
115115
let body = self.builder.body;
116116
let tcx = self.builder.tcx;
117117
let place_ty = place_ref.ty(body, tcx).ty;
118-
match place_ty.kind() {
119-
ty::Ref(..) | ty::RawPtr(..) => {
120-
return Err(MoveError::cannot_move_out_of(
121-
self.loc,
122-
BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
123-
));
124-
}
125-
ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
126-
return Err(MoveError::cannot_move_out_of(
127-
self.loc,
128-
InteriorOfTypeWithDestructor { container_ty: place_ty },
129-
));
130-
}
131-
ty::Adt(adt, _) if adt.is_union() => {
132-
union_path.get_or_insert(base);
133-
}
134-
ty::Slice(_) => {
135-
return Err(MoveError::cannot_move_out_of(
136-
self.loc,
137-
InteriorOfSliceOrArray {
138-
ty: place_ty,
139-
is_index: matches!(elem, ProjectionElem::Index(..)),
140-
},
141-
));
118+
match elem {
119+
ProjectionElem::Deref => match place_ty.kind() {
120+
ty::Ref(..) | ty::RawPtr(..) => {
121+
return Err(MoveError::cannot_move_out_of(
122+
self.loc,
123+
BorrowedContent {
124+
target_place: place_ref.project_deeper(&[elem], tcx),
125+
},
126+
));
127+
}
128+
ty::Adt(adt, _) => {
129+
if !adt.is_box() {
130+
bug!("Adt should be a box type when Place is deref");
131+
}
132+
}
133+
ty::Bool
134+
| ty::Char
135+
| ty::Int(_)
136+
| ty::Uint(_)
137+
| ty::Float(_)
138+
| ty::Foreign(_)
139+
| ty::Str
140+
| ty::Array(_, _)
141+
| ty::Slice(_)
142+
| ty::FnDef(_, _)
143+
| ty::FnPtr(_)
144+
| ty::Dynamic(_, _, _)
145+
| ty::Closure(_, _)
146+
| ty::Generator(_, _, _)
147+
| ty::GeneratorWitness(_)
148+
| ty::GeneratorWitnessMIR(_, _)
149+
| ty::Never
150+
| ty::Tuple(_)
151+
| ty::Alias(_, _)
152+
| ty::Param(_)
153+
| ty::Bound(_, _)
154+
| ty::Infer(_)
155+
| ty::Error(_)
156+
| ty::Placeholder(_) => {
157+
bug!("When Place is Deref it's type shouldn't be {place_ty:#?}")
158+
}
159+
},
160+
ProjectionElem::Field(_, _) => match place_ty.kind() {
161+
ty::Adt(adt, _) => {
162+
if adt.has_dtor(tcx) {
163+
return Err(MoveError::cannot_move_out_of(
164+
self.loc,
165+
InteriorOfTypeWithDestructor { container_ty: place_ty },
166+
));
167+
}
168+
if adt.is_union() {
169+
union_path.get_or_insert(base);
170+
}
171+
}
172+
ty::Closure(_, _) | ty::Generator(_, _, _) | ty::Tuple(_) => (),
173+
ty::Bool
174+
| ty::Char
175+
| ty::Int(_)
176+
| ty::Uint(_)
177+
| ty::Float(_)
178+
| ty::Foreign(_)
179+
| ty::Str
180+
| ty::Array(_, _)
181+
| ty::Slice(_)
182+
| ty::RawPtr(_)
183+
| ty::Ref(_, _, _)
184+
| ty::FnDef(_, _)
185+
| ty::FnPtr(_)
186+
| ty::Dynamic(_, _, _)
187+
| ty::GeneratorWitness(_)
188+
| ty::GeneratorWitnessMIR(_, _)
189+
| ty::Never
190+
| ty::Alias(_, _)
191+
| ty::Param(_)
192+
| ty::Bound(_, _)
193+
| ty::Infer(_)
194+
| ty::Error(_)
195+
| ty::Placeholder(_) => bug!(
196+
"When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
197+
),
198+
},
199+
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
200+
match place_ty.kind() {
201+
ty::Slice(_) => {
202+
return Err(MoveError::cannot_move_out_of(
203+
self.loc,
204+
InteriorOfSliceOrArray {
205+
ty: place_ty,
206+
is_index: matches!(elem, ProjectionElem::Index(..)),
207+
},
208+
));
209+
}
210+
ty::Array(_, _) => (),
211+
_ => bug!("Unexpected type {:#?}", place_ty.is_array()),
212+
}
142213
}
143-
144-
ty::Array(..) => {
145-
if let ProjectionElem::Index(..) = elem {
214+
ProjectionElem::Index(_) => match place_ty.kind() {
215+
ty::Array(..) => {
146216
return Err(MoveError::cannot_move_out_of(
147217
self.loc,
148218
InteriorOfSliceOrArray { ty: place_ty, is_index: true },
149219
));
150220
}
151-
}
152-
153-
_ => {}
154-
};
155-
221+
ty::Slice(_) => {
222+
return Err(MoveError::cannot_move_out_of(
223+
self.loc,
224+
InteriorOfSliceOrArray {
225+
ty: place_ty,
226+
is_index: matches!(elem, ProjectionElem::Index(..)),
227+
},
228+
));
229+
}
230+
_ => bug!("Unexpected type {place_ty:#?}"),
231+
},
232+
// `OpaqueCast` only transmutes the type, so no moves there and
233+
// `Downcast` only changes information about a `Place` without moving
234+
// So it's safe to skip these.
235+
ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
236+
}
156237
if union_path.is_none() {
157238
// inlined from add_move_path because of a borrowck conflict with the iterator
158239
base =

compiler/rustc_serialize/src/opaque.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,16 @@ pub struct FileEncoder {
3838

3939
impl FileEncoder {
4040
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
41+
// File::create opens the file for writing only. When -Zmeta-stats is enabled, the metadata
42+
// encoder rewinds the file to inspect what was written. So we need to always open the file
43+
// for reading and writing.
44+
let file = File::options().read(true).write(true).create(true).truncate(true).open(path)?;
45+
4146
Ok(FileEncoder {
4247
buf: vec![0u8; BUF_SIZE].into_boxed_slice().try_into().unwrap(),
4348
buffered: 0,
4449
flushed: 0,
45-
file: File::create(path)?,
50+
file,
4651
res: Ok(()),
4752
})
4853
}

tests/ui/async-await/issue-68523-start.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
#[start]
66
pub async fn start(_: isize, _: *const *const u8) -> isize {
7-
//~^ ERROR `start` is not allowed to be `async`
7+
//~^ ERROR `#[start]` function is not allowed to be `async`
88
0
99
}

tests/ui/async-await/issue-68523-start.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0752]: `start` is not allowed to be `async`
1+
error[E0752]: `#[start]` function is not allowed to be `async`
22
--> $DIR/issue-68523-start.rs:6:1
33
|
44
LL | pub async fn start(_: isize, _: *const *const u8) -> isize {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `start` is not allowed to be `async`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `#[start]` is not allowed to be `async`
66

77
error: aborting due to previous error
88

tests/ui/cast/unsized-struct-cast.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub struct Data([u8]);
2+
3+
fn main(){
4+
const _: *const Data = &[] as *const Data;
5+
//~^ ERROR: casting `&[_; 0]` as `*const Data` is invalid
6+
}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0606]: casting `&[_; 0]` as `*const Data` is invalid
2+
--> $DIR/unsized-struct-cast.rs:4:28
3+
|
4+
LL | const _: *const Data = &[] as *const Data;
5+
| ^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0606`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0505]: cannot move out of `value` because it is borrowed
2+
--> $DIR/if-let-guards-errors.rs:16:13
3+
|
4+
LL | let f = |x: &E| {
5+
| ------- borrow of `value` occurs here
6+
LL | match &x {
7+
LL | E::Number(_) if let E::Number(ref mut n) = *value => { }
8+
| ------ borrow occurs due to use in closure
9+
...
10+
LL | let x = value;
11+
| ^^^^^ move out of `value` occurs here
12+
LL |
13+
LL | drop(f);
14+
| - borrow later used here
15+
16+
error[E0382]: use of moved value: `value`
17+
--> $DIR/if-let-guards-errors.rs:28:13
18+
|
19+
LL | fn if_let_move(value: Box<E>) {
20+
| ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
21+
LL | let f = |x: &E| {
22+
| ------- value moved into closure here
23+
LL | match &x {
24+
LL | E::Number(_) if let E::String(s) = *value => { }
25+
| ------ variable moved due to use in closure
26+
...
27+
LL | let x = value;
28+
| ^^^^^ value used here after move
29+
30+
error: aborting due to 2 previous errors
31+
32+
Some errors have detailed explanations: E0382, E0505.
33+
For more information about an error, try `rustc --explain E0382`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0505]: cannot move out of `value` because it is borrowed
2+
--> $DIR/if-let-guards-errors.rs:16:13
3+
|
4+
LL | let f = |x: &E| {
5+
| ------- borrow of `*value` occurs here
6+
LL | match &x {
7+
LL | E::Number(_) if let E::Number(ref mut n) = *value => { }
8+
| ------ borrow occurs due to use in closure
9+
...
10+
LL | let x = value;
11+
| ^^^^^ move out of `value` occurs here
12+
LL |
13+
LL | drop(f);
14+
| - borrow later used here
15+
16+
error[E0382]: use of moved value: `value`
17+
--> $DIR/if-let-guards-errors.rs:28:13
18+
|
19+
LL | fn if_let_move(value: Box<E>) {
20+
| ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
21+
LL | let f = |x: &E| {
22+
| ------- value moved into closure here
23+
LL | match &x {
24+
LL | E::Number(_) if let E::String(s) = *value => { }
25+
| ------ variable moved due to use in closure
26+
...
27+
LL | let x = value;
28+
| ^^^^^ value used here after move
29+
30+
error: aborting due to 2 previous errors
31+
32+
Some errors have detailed explanations: E0382, E0505.
33+
For more information about an error, try `rustc --explain E0382`.

0 commit comments

Comments
 (0)