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
This commit is contained in:
commit
e4133ba9b1
@ -7,7 +7,7 @@ Erroneous code example:
|
|||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
|
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
|
0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -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
|
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
|
||||||
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
|
.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
|
hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters
|
||||||
.label = start function cannot 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
|
hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause
|
||||||
.label = start function cannot have a `where` clause
|
.label = `#[start]` function cannot have a `where` clause
|
||||||
|
|
||||||
hir_analysis_start_not_async = `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`
|
.label = `#[start]` is not allowed to be `async`
|
||||||
|
|
||||||
hir_analysis_start_not_target_feature = `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` 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]`
|
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
|
||||||
.label = `start` 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
|
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
|
||||||
|
|
||||||
|
@ -725,6 +725,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
},
|
},
|
||||||
// array-ptr-cast
|
// array-ptr-cast
|
||||||
Ptr(mt) => {
|
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)
|
self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt)
|
||||||
}
|
}
|
||||||
_ => Err(CastError::NonScalar),
|
_ => Err(CastError::NonScalar),
|
||||||
@ -735,7 +738,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
}
|
}
|
||||||
_ => return Err(CastError::NonScalar),
|
_ => return Err(CastError::NonScalar),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
|
if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
|
||||||
if adt_def.did().krate != LOCAL_CRATE {
|
if adt_def.did().krate != LOCAL_CRATE {
|
||||||
if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
|
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) {
|
match (t_from, t_cast) {
|
||||||
// These types have invariants! can't cast into them.
|
// These types have invariants! can't cast into them.
|
||||||
(_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),
|
(_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),
|
||||||
|
@ -664,10 +664,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
|
self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
|
||||||
|
|
||||||
if let Some(hir::Guard::If(e)) = arm.guard {
|
match arm.guard {
|
||||||
self.consume_expr(e)
|
Some(hir::Guard::If(ref e)) => self.consume_expr(e),
|
||||||
} else if let Some(hir::Guard::IfLet(ref l)) = arm.guard {
|
Some(hir::Guard::IfLet(ref l)) => {
|
||||||
self.consume_expr(l.init)
|
self.walk_local(l.init, l.pat, None, |t| t.borrow_expr(l.init, ty::ImmBorrow))
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.consume_expr(arm.body);
|
self.consume_expr(arm.body);
|
||||||
|
@ -115,22 +115,109 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||||||
let body = self.builder.body;
|
let body = self.builder.body;
|
||||||
let tcx = self.builder.tcx;
|
let tcx = self.builder.tcx;
|
||||||
let place_ty = place_ref.ty(body, tcx).ty;
|
let place_ty = place_ref.ty(body, tcx).ty;
|
||||||
match place_ty.kind() {
|
match elem {
|
||||||
|
ProjectionElem::Deref => match place_ty.kind() {
|
||||||
ty::Ref(..) | ty::RawPtr(..) => {
|
ty::Ref(..) | ty::RawPtr(..) => {
|
||||||
return Err(MoveError::cannot_move_out_of(
|
return Err(MoveError::cannot_move_out_of(
|
||||||
self.loc,
|
self.loc,
|
||||||
BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
|
BorrowedContent {
|
||||||
|
target_place: place_ref.project_deeper(&[elem], tcx),
|
||||||
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
|
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(
|
return Err(MoveError::cannot_move_out_of(
|
||||||
self.loc,
|
self.loc,
|
||||||
InteriorOfTypeWithDestructor { container_ty: place_ty },
|
InteriorOfTypeWithDestructor { container_ty: place_ty },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
ty::Adt(adt, _) if adt.is_union() => {
|
if adt.is_union() {
|
||||||
union_path.get_or_insert(base);
|
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()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(_) => {
|
ty::Slice(_) => {
|
||||||
return Err(MoveError::cannot_move_out_of(
|
return Err(MoveError::cannot_move_out_of(
|
||||||
self.loc,
|
self.loc,
|
||||||
@ -140,19 +227,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
_ => bug!("Unexpected type {place_ty:#?}"),
|
||||||
ty::Array(..) => {
|
},
|
||||||
if let ProjectionElem::Index(..) = elem {
|
// `OpaqueCast` only transmutes the type, so no moves there and
|
||||||
return Err(MoveError::cannot_move_out_of(
|
// `Downcast` only changes information about a `Place` without moving
|
||||||
self.loc,
|
// So it's safe to skip these.
|
||||||
InteriorOfSliceOrArray { ty: place_ty, is_index: true },
|
ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
if union_path.is_none() {
|
if union_path.is_none() {
|
||||||
// inlined from add_move_path because of a borrowck conflict with the iterator
|
// inlined from add_move_path because of a borrowck conflict with the iterator
|
||||||
base =
|
base =
|
||||||
|
@ -38,11 +38,16 @@ pub struct FileEncoder {
|
|||||||
|
|
||||||
impl FileEncoder {
|
impl FileEncoder {
|
||||||
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
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 {
|
Ok(FileEncoder {
|
||||||
buf: vec![0u8; BUF_SIZE].into_boxed_slice().try_into().unwrap(),
|
buf: vec![0u8; BUF_SIZE].into_boxed_slice().try_into().unwrap(),
|
||||||
buffered: 0,
|
buffered: 0,
|
||||||
flushed: 0,
|
flushed: 0,
|
||||||
file: File::create(path)?,
|
file,
|
||||||
res: Ok(()),
|
res: Ok(()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
pub async fn start(_: isize, _: *const *const u8) -> isize {
|
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
|
0
|
||||||
}
|
}
|
||||||
|
@ -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
|
--> $DIR/issue-68523-start.rs:6:1
|
||||||
|
|
|
|
||||||
LL | pub async fn start(_: isize, _: *const *const u8) -> isize {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
6
tests/ui/cast/unsized-struct-cast.rs
Normal file
6
tests/ui/cast/unsized-struct-cast.rs
Normal file
@ -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
tests/ui/cast/unsized-struct-cast.stderr
Normal file
9
tests/ui/cast/unsized-struct-cast.stderr
Normal file
@ -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`.
|
@ -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`.
|
@ -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`.
|
@ -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<E>) {
|
||||||
|
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<E>) {
|
||||||
|
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() {}
|
@ -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<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let _ = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_copy(value: Box<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::Number(n) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_ref(value: Box<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::Number(ref n) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_ref_mut(mut value: Box<E>) {
|
||||||
|
|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() {}
|
@ -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
|
--> $DIR/E0132.rs:4:5
|
||||||
|
|
|
|
||||||
LL | fn f< T >() {}
|
LL | fn f< T >() {}
|
||||||
| ^^^^^ start function cannot have type parameters
|
| ^^^^^ `#[start]` function cannot have type parameters
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -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
|
--> $DIR/E0647.rs:7:50
|
||||||
|
|
|
|
||||||
LL | fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -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
|
--> $DIR/issue-50714-1.rs:9:50
|
||||||
|
|
|
|
||||||
LL | fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#![feature(start)]
|
#![feature(start)]
|
||||||
|
|
||||||
#[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 {
|
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
panic!("{}: oh no", std::panic::Location::caller());
|
panic!("{}: oh no", std::panic::Location::caller());
|
||||||
}
|
}
|
||||||
|
@ -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
|
--> $DIR/error-with-start.rs:4:1
|
||||||
|
|
|
|
||||||
LL | #[track_caller]
|
LL | #[track_caller]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
LL | fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
#[target_feature(enable = "avx2")]
|
#[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 }
|
fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 }
|
||||||
|
@ -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
|
--> $DIR/issue-108645-target-feature-on-start.rs:7:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "avx2")]
|
LL | #[target_feature(enable = "avx2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
LL |
|
LL |
|
||||||
LL | fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 }
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
7
tests/ui/stats/meta-stats.rs
Normal file
7
tests/ui/stats/meta-stats.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// build-pass
|
||||||
|
// dont-check-compiler-stderr
|
||||||
|
// compile-flags: -Zmeta-stats
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
pub fn a() {}
|
@ -598,7 +598,6 @@ compiler-team = [
|
|||||||
compiler-team-contributors = [
|
compiler-team-contributors = [
|
||||||
"@compiler-errors",
|
"@compiler-errors",
|
||||||
"@jackh726",
|
"@jackh726",
|
||||||
"@TaKO8Ki",
|
|
||||||
"@WaffleLapkin",
|
"@WaffleLapkin",
|
||||||
"@b-naber",
|
"@b-naber",
|
||||||
]
|
]
|
||||||
@ -645,7 +644,6 @@ diagnostics = [
|
|||||||
"@compiler-errors",
|
"@compiler-errors",
|
||||||
"@davidtwco",
|
"@davidtwco",
|
||||||
"@oli-obk",
|
"@oli-obk",
|
||||||
"@TaKO8Ki",
|
|
||||||
]
|
]
|
||||||
parser = [
|
parser = [
|
||||||
"@compiler-errors",
|
"@compiler-errors",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user