Auto merge of #85952 - JohnTitor:rollup-r00gu9q, r=JohnTitor
Rollup of 13 pull requests Successful merges: - #83362 (Stabilize `vecdeque_binary_search`) - #85706 (Turn off frame pointer elimination on all Apple platforms. ) - #85724 (Fix issue 85435 by restricting Fake Read precision) - #85852 (Clarify meaning of MachineApplicable suggestions.) - #85877 (Intra doc link-ify a reference to a function) - #85880 (convert assertion on rvalue::threadlocalref to delay bug) - #85896 (Add test for forward declared const param defaults) - #85897 (Update I-unsound label for triagebot) - #85900 (Use pattern matching instead of checking lengths explicitly) - #85911 (Avoid a clone of output_filenames.) - #85926 (Update cargo) - #85934 (Add `Ty::is_union` predicate) - #85935 (Validate type of locals used as indices) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a93699f20a
25
Cargo.lock
25
Cargo.lock
@ -278,6 +278,7 @@ dependencies = [
|
|||||||
"humantime 2.0.1",
|
"humantime 2.0.1",
|
||||||
"ignore",
|
"ignore",
|
||||||
"im-rc",
|
"im-rc",
|
||||||
|
"itertools 0.10.0",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lazycell",
|
"lazycell",
|
||||||
@ -293,7 +294,7 @@ dependencies = [
|
|||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"rustc-workspace-hack",
|
"rustc-workspace-hack",
|
||||||
"rustfix",
|
"rustfix",
|
||||||
"semver 0.10.0",
|
"semver 1.0.1",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_ignored",
|
"serde_ignored",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -1715,6 +1716,15 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@ -4674,6 +4684,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d023dabf011d5dcb5ac64e3685d97d3b0ef412911077a2851455c6098524a723"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver-parser"
|
name = "semver-parser"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -5033,9 +5052,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tar"
|
name = "tar"
|
||||||
version = "0.4.33"
|
version = "0.4.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0bcfbd6a598361fda270d82469fff3d65089dc33e175c9a131f7b4cd395f228"
|
checksum = "7d779dc6aeff029314570f666ec83f19df7280bb36ef338442cfa8c604021b80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"filetime",
|
"filetime",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -799,7 +799,7 @@ pub fn create_global_ctxt<'tcx>(
|
|||||||
query_result_on_disk_cache,
|
query_result_on_disk_cache,
|
||||||
queries.as_dyn(),
|
queries.as_dyn(),
|
||||||
&crate_name,
|
&crate_name,
|
||||||
&outputs,
|
outputs,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::{is_range_literal, ExprKind, Node};
|
use rustc_hir::{is_range_literal, ExprKind, Node};
|
||||||
use rustc_index::vec::Idx;
|
|
||||||
use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
|
use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
|
||||||
@ -13,7 +12,7 @@ use rustc_span::source_map;
|
|||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::abi::Abi;
|
use rustc_target::abi::Abi;
|
||||||
use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
|
use rustc_target::abi::{Integer, LayoutOf, TagEncoding, Variants};
|
||||||
use rustc_target::spec::abi::Abi as SpecAbi;
|
use rustc_target::spec::abi::Abi as SpecAbi;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -783,25 +782,14 @@ crate fn repr_nullable_ptr<'tcx>(
|
|||||||
) -> Option<Ty<'tcx>> {
|
) -> Option<Ty<'tcx>> {
|
||||||
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
|
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
|
||||||
if let ty::Adt(ty_def, substs) = ty.kind() {
|
if let ty::Adt(ty_def, substs) = ty.kind() {
|
||||||
if ty_def.variants.len() != 2 {
|
let field_ty = match &ty_def.variants.raw[..] {
|
||||||
return None;
|
[var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) {
|
||||||
}
|
([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
|
||||||
|
_ => return None,
|
||||||
let get_variant_fields = |index| &ty_def.variants[VariantIdx::new(index)].fields;
|
},
|
||||||
let variant_fields = [get_variant_fields(0), get_variant_fields(1)];
|
_ => return None,
|
||||||
let fields = if variant_fields[0].is_empty() {
|
|
||||||
&variant_fields[1]
|
|
||||||
} else if variant_fields[1].is_empty() {
|
|
||||||
&variant_fields[0]
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if fields.len() != 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let field_ty = fields[0].ty(cx.tcx, substs);
|
|
||||||
if !ty_is_known_nonnull(cx, field_ty, ckind) {
|
if !ty_is_known_nonnull(cx, field_ty, ckind) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,11 @@ macro_rules! pluralize {
|
|||||||
/// before applying the suggestion.
|
/// before applying the suggestion.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
|
#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
|
||||||
pub enum Applicability {
|
pub enum Applicability {
|
||||||
/// The suggestion is definitely what the user intended. This suggestion should be
|
/// The suggestion is definitely what the user intended, or maintains the exact meaning of the code.
|
||||||
|
/// This suggestion should be automatically applied.
|
||||||
|
///
|
||||||
|
/// In case of multiple `MachineApplicable` suggestions (whether as part of
|
||||||
|
/// the same `multipart_suggestion` or not), all of them should be
|
||||||
/// automatically applied.
|
/// automatically applied.
|
||||||
MachineApplicable,
|
MachineApplicable,
|
||||||
|
|
||||||
|
@ -1135,7 +1135,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
on_disk_cache: Option<query::OnDiskCache<'tcx>>,
|
on_disk_cache: Option<query::OnDiskCache<'tcx>>,
|
||||||
queries: &'tcx dyn query::QueryEngine<'tcx>,
|
queries: &'tcx dyn query::QueryEngine<'tcx>,
|
||||||
crate_name: &str,
|
crate_name: &str,
|
||||||
output_filenames: &OutputFilenames,
|
output_filenames: OutputFilenames,
|
||||||
) -> GlobalCtxt<'tcx> {
|
) -> GlobalCtxt<'tcx> {
|
||||||
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
|
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
|
||||||
s.fatal(&err);
|
s.fatal(&err);
|
||||||
@ -1179,7 +1179,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
stability_interner: Default::default(),
|
stability_interner: Default::default(),
|
||||||
const_stability_interner: Default::default(),
|
const_stability_interner: Default::default(),
|
||||||
alloc_map: Lock::new(interpret::AllocMap::new()),
|
alloc_map: Lock::new(interpret::AllocMap::new()),
|
||||||
output_filenames: Arc::new(output_filenames.clone()),
|
output_filenames: Arc::new(output_filenames),
|
||||||
main_def: resolutions.main_def,
|
main_def: resolutions.main_def,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1837,10 +1837,12 @@ impl<'tcx> TyS<'tcx> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_enum(&self) -> bool {
|
pub fn is_enum(&self) -> bool {
|
||||||
match self.kind() {
|
matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum())
|
||||||
Adt(adt_def, _) => adt_def.is_enum(),
|
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_union(&self) -> bool {
|
||||||
|
matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1965,15 +1965,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
// no move out from an earlier location) then this is an attempt at initialization
|
// no move out from an earlier location) then this is an attempt at initialization
|
||||||
// of the union - we should error in that case.
|
// of the union - we should error in that case.
|
||||||
let tcx = this.infcx.tcx;
|
let tcx = this.infcx.tcx;
|
||||||
if let ty::Adt(def, _) = base.ty(this.body(), tcx).ty.kind() {
|
if base.ty(this.body(), tcx).ty.is_union() {
|
||||||
if def.is_union() {
|
|
||||||
if this.move_data.path_map[mpi].iter().any(|moi| {
|
if this.move_data.path_map[mpi].iter().any(|moi| {
|
||||||
this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
|
this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
|
||||||
}) {
|
}) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.report_use_of_moved_or_uninitialized(
|
this.report_use_of_moved_or_uninitialized(
|
||||||
location,
|
location,
|
||||||
|
@ -331,20 +331,17 @@ fn place_projection_conflict<'tcx>(
|
|||||||
Overlap::EqualOrDisjoint
|
Overlap::EqualOrDisjoint
|
||||||
} else {
|
} else {
|
||||||
let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty;
|
let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty;
|
||||||
match ty.kind() {
|
if ty.is_union() {
|
||||||
ty::Adt(def, _) if def.is_union() => {
|
|
||||||
// Different fields of a union, we are basically stuck.
|
// Different fields of a union, we are basically stuck.
|
||||||
debug!("place_element_conflict: STUCK-UNION");
|
debug!("place_element_conflict: STUCK-UNION");
|
||||||
Overlap::Arbitrary
|
Overlap::Arbitrary
|
||||||
}
|
} else {
|
||||||
_ => {
|
|
||||||
// Different fields of a struct (`a.x` vs. `a.y`). Disjoint!
|
// Different fields of a struct (`a.x` vs. `a.y`). Disjoint!
|
||||||
debug!("place_element_conflict: DISJOINT-FIELD");
|
debug!("place_element_conflict: DISJOINT-FIELD");
|
||||||
Overlap::Disjoint
|
Overlap::Disjoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
(ProjectionElem::Downcast(_, v1), ProjectionElem::Downcast(_, v2)) => {
|
(ProjectionElem::Downcast(_, v1), ProjectionElem::Downcast(_, v2)) => {
|
||||||
// different variants are treated as having disjoint fields,
|
// different variants are treated as having disjoint fields,
|
||||||
// even if they occupy the same "space", because it's
|
// even if they occupy the same "space", because it's
|
||||||
|
@ -519,12 +519,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||||||
// Check if we are assigning into a field of a union, if so, lookup the place
|
// Check if we are assigning into a field of a union, if so, lookup the place
|
||||||
// of the union so it is marked as initialized again.
|
// of the union so it is marked as initialized again.
|
||||||
if let Some((place_base, ProjectionElem::Field(_, _))) = place.last_projection() {
|
if let Some((place_base, ProjectionElem::Field(_, _))) = place.last_projection() {
|
||||||
if let ty::Adt(def, _) = place_base.ty(self.builder.body, self.builder.tcx).ty.kind() {
|
if place_base.ty(self.builder.body, self.builder.tcx).ty.is_union() {
|
||||||
if def.is_union() {
|
|
||||||
place = place_base;
|
place = place_base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) {
|
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) {
|
||||||
let init = self.builder.data.inits.push(Init {
|
let init = self.builder.data.inits.push(Init {
|
||||||
|
@ -356,10 +356,9 @@ impl Validator<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_static(&mut self, def_id: DefId, span: Span) {
|
fn check_static(&mut self, def_id: DefId, span: Span) {
|
||||||
assert!(
|
if self.tcx.is_thread_local_static(def_id) {
|
||||||
!self.tcx.is_thread_local_static(def_id),
|
self.tcx.sess.delay_span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef");
|
||||||
"tls access is checked in `Rvalue::ThreadLocalRef"
|
}
|
||||||
);
|
|
||||||
self.check_op_spanned(ops::StaticAccess, span)
|
self.check_op_spanned(ops::StaticAccess, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,13 +752,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
|||||||
| ProjectionElem::Field(..)
|
| ProjectionElem::Field(..)
|
||||||
| ProjectionElem::Index(_) => {
|
| ProjectionElem::Index(_) => {
|
||||||
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
|
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
|
||||||
match base_ty.ty_adt_def() {
|
if base_ty.is_union() {
|
||||||
Some(def) if def.is_union() => {
|
|
||||||
self.check_op(ops::UnionAccess);
|
self.check_op(ops::UnionAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let base_ty = base.ty(self.body, self.tcx).ty;
|
let base_ty = base.ty(self.body, self.tcx).ty;
|
||||||
if base_ty.ty_adt_def().map_or(false, |adt| adt.is_union()) {
|
if base_ty.is_union() {
|
||||||
// If we did not hit a `Deref` yet and the overall place use is an assignment, the
|
// If we did not hit a `Deref` yet and the overall place use is an assignment, the
|
||||||
// rules are different.
|
// rules are different.
|
||||||
let assign_to_field = !saw_deref
|
let assign_to_field = !saw_deref
|
||||||
|
@ -114,7 +114,7 @@ use rustc_middle::mir::{
|
|||||||
traversal, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, PlaceElem,
|
traversal, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, PlaceElem,
|
||||||
Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
// Empirical measurements have resulted in some observations:
|
// Empirical measurements have resulted in some observations:
|
||||||
// - Running on a body with a single block and 500 locals takes barely any time
|
// - Running on a body with a single block and 500 locals takes barely any time
|
||||||
@ -910,17 +910,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindAssignments<'a, 'tcx> {
|
|||||||
|
|
||||||
// Handle the "subtle case" described above by rejecting any `dest` that is or
|
// Handle the "subtle case" described above by rejecting any `dest` that is or
|
||||||
// projects through a union.
|
// projects through a union.
|
||||||
let is_union = |ty: Ty<'_>| {
|
|
||||||
if let ty::Adt(def, _) = ty.kind() {
|
|
||||||
if def.is_union() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
};
|
|
||||||
let mut place_ty = PlaceTy::from_ty(self.body.local_decls[dest.local].ty);
|
let mut place_ty = PlaceTy::from_ty(self.body.local_decls[dest.local].ty);
|
||||||
if is_union(place_ty.ty) {
|
if place_ty.ty.is_union() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for elem in dest.projection {
|
for elem in dest.projection {
|
||||||
@ -930,7 +921,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindAssignments<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
place_ty = place_ty.projection_ty(self.tcx, elem);
|
place_ty = place_ty.projection_ty(self.tcx, elem);
|
||||||
if is_union(place_ty.ty) {
|
if place_ty.ty.is_union() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,14 +415,12 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||||||
|
|
||||||
ProjectionElem::Field(..) => {
|
ProjectionElem::Field(..) => {
|
||||||
let base_ty = place_base.ty(self.body, self.tcx).ty;
|
let base_ty = place_base.ty(self.body, self.tcx).ty;
|
||||||
if let Some(def) = base_ty.ty_adt_def() {
|
if base_ty.is_union() {
|
||||||
// No promotion of union field accesses.
|
// No promotion of union field accesses.
|
||||||
if def.is_union() {
|
|
||||||
return Err(Unpromotable);
|
return Err(Unpromotable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
self.validate_place(place_base)
|
self.validate_place(place_base)
|
||||||
}
|
}
|
||||||
|
@ -69,21 +69,14 @@ fn involves_a_union<'tcx>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut place_ty = PlaceTy::from_ty(local_decls[place.local].ty);
|
let mut place_ty = PlaceTy::from_ty(local_decls[place.local].ty);
|
||||||
if is_union(place_ty.ty) {
|
if place_ty.ty.is_union() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for elem in place.projection {
|
for elem in place.projection {
|
||||||
place_ty = place_ty.projection_ty(tcx, elem);
|
place_ty = place_ty.projection_ty(tcx, elem);
|
||||||
if is_union(place_ty.ty) {
|
if place_ty.ty.is_union() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_union(ty: Ty<'_>) -> bool {
|
|
||||||
match ty.kind() {
|
|
||||||
ty::Adt(def, _) if def.is_union() => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -11,8 +11,9 @@ use rustc_middle::mir::interpret::Scalar;
|
|||||||
use rustc_middle::mir::traversal;
|
use rustc_middle::mir::traversal;
|
||||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
|
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceElem,
|
||||||
Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind,
|
PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, StatementKind, Terminator,
|
||||||
|
TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::BottomUpFolder;
|
||||||
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
||||||
@ -217,6 +218,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
self.super_operand(operand, location);
|
self.super_operand(operand, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_projection_elem(
|
||||||
|
&mut self,
|
||||||
|
local: Local,
|
||||||
|
proj_base: &[PlaceElem<'tcx>],
|
||||||
|
elem: PlaceElem<'tcx>,
|
||||||
|
context: PlaceContext,
|
||||||
|
location: Location,
|
||||||
|
) {
|
||||||
|
if let ProjectionElem::Index(index) = elem {
|
||||||
|
let index_ty = self.body.local_decls[index].ty;
|
||||||
|
if index_ty != self.tcx.types.usize {
|
||||||
|
self.fail(location, format!("bad index ({:?} != usize)", index_ty))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.super_projection_elem(local, proj_base, elem, context, location);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
|
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
|
||||||
match &statement.kind {
|
match &statement.kind {
|
||||||
StatementKind::Assign(box (dest, rvalue)) => {
|
StatementKind::Assign(box (dest, rvalue)) => {
|
||||||
|
@ -186,9 +186,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
// };
|
// };
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// FIXME(RFC2229, rust#85435): Remove feature gate once diagnostics are
|
|
||||||
// improved and unsafe checking works properly in closure bodies again.
|
|
||||||
if this.tcx.features().capture_disjoint_fields {
|
|
||||||
for (thir_place, cause, hir_id) in fake_reads.into_iter() {
|
for (thir_place, cause, hir_id) in fake_reads.into_iter() {
|
||||||
let place_builder =
|
let place_builder =
|
||||||
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
|
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
|
||||||
@ -206,7 +203,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// see (*) above
|
// see (*) above
|
||||||
let operands: Vec<_> = upvars
|
let operands: Vec<_> = upvars
|
||||||
|
@ -450,7 +450,7 @@ impl<'a> Resolver<'a> {
|
|||||||
err.span_label(shadowed_binding_span, msg);
|
err.span_label(shadowed_binding_span, msg);
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
ResolutionError::ForwardDeclaredTyParam => {
|
ResolutionError::ForwardDeclaredGenericParam => {
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
self.session,
|
self.session,
|
||||||
span,
|
span,
|
||||||
|
@ -242,7 +242,7 @@ enum ResolutionError<'a> {
|
|||||||
shadowed_binding_span: Span,
|
shadowed_binding_span: Span,
|
||||||
},
|
},
|
||||||
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
|
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
|
||||||
ForwardDeclaredTyParam, // FIXME(const_generics_defaults)
|
ForwardDeclaredGenericParam,
|
||||||
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
|
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
|
||||||
ParamInTyOfConstParam(Symbol),
|
ParamInTyOfConstParam(Symbol),
|
||||||
/// generic parameters must not be used inside const evaluations.
|
/// generic parameters must not be used inside const evaluations.
|
||||||
@ -2608,7 +2608,7 @@ impl<'a> Resolver<'a> {
|
|||||||
let res_error = if rib_ident.name == kw::SelfUpper {
|
let res_error = if rib_ident.name == kw::SelfUpper {
|
||||||
ResolutionError::SelfInTyParamDefault
|
ResolutionError::SelfInTyParamDefault
|
||||||
} else {
|
} else {
|
||||||
ResolutionError::ForwardDeclaredTyParam
|
ResolutionError::ForwardDeclaredGenericParam
|
||||||
};
|
};
|
||||||
self.report_error(span, res_error);
|
self.report_error(span, res_error);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ pub fn target() -> Target {
|
|||||||
arch: "aarch64".to_string(),
|
arch: "aarch64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+neon,+fp-armv8,+apple-a7".to_string(),
|
features: "+neon,+fp-armv8,+apple-a7".to_string(),
|
||||||
eliminate_frame_pointer: false,
|
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
unsupported_abis: super::arm_base::unsupported_abis(),
|
unsupported_abis: super::arm_base::unsupported_abis(),
|
||||||
forces_embed_bitcode: true,
|
forces_embed_bitcode: true,
|
||||||
|
@ -10,7 +10,6 @@ pub fn target() -> Target {
|
|||||||
arch: "aarch64".to_string(),
|
arch: "aarch64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+neon,+fp-armv8,+apple-a12".to_string(),
|
features: "+neon,+fp-armv8,+apple-a12".to_string(),
|
||||||
eliminate_frame_pointer: false,
|
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
unsupported_abis: super::arm_base::unsupported_abis(),
|
unsupported_abis: super::arm_base::unsupported_abis(),
|
||||||
forces_embed_bitcode: true,
|
forces_embed_bitcode: true,
|
||||||
|
@ -18,7 +18,6 @@ pub fn target() -> Target {
|
|||||||
arch: "aarch64".to_string(),
|
arch: "aarch64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+neon,+fp-armv8,+apple-a7".to_string(),
|
features: "+neon,+fp-armv8,+apple-a7".to_string(),
|
||||||
eliminate_frame_pointer: false,
|
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
unsupported_abis: super::arm_base::unsupported_abis(),
|
unsupported_abis: super::arm_base::unsupported_abis(),
|
||||||
forces_embed_bitcode: true,
|
forces_embed_bitcode: true,
|
||||||
|
@ -10,7 +10,6 @@ pub fn target() -> Target {
|
|||||||
arch: "aarch64".to_string(),
|
arch: "aarch64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+neon,+fp-armv8,+apple-a7".to_string(),
|
features: "+neon,+fp-armv8,+apple-a7".to_string(),
|
||||||
eliminate_frame_pointer: false,
|
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
unsupported_abis: super::arm_base::unsupported_abis(),
|
unsupported_abis: super::arm_base::unsupported_abis(),
|
||||||
forces_embed_bitcode: true,
|
forces_embed_bitcode: true,
|
||||||
|
@ -27,6 +27,7 @@ pub fn opts(os: &str) -> TargetOptions {
|
|||||||
families: vec!["unix".to_string()],
|
families: vec!["unix".to_string()],
|
||||||
is_like_osx: true,
|
is_like_osx: true,
|
||||||
dwarf_version: Some(2),
|
dwarf_version: Some(2),
|
||||||
|
eliminate_frame_pointer: false,
|
||||||
has_rpath: true,
|
has_rpath: true,
|
||||||
dll_suffix: ".dylib".to_string(),
|
dll_suffix: ".dylib".to_string(),
|
||||||
archive_format: "darwin".to_string(),
|
archive_format: "darwin".to_string(),
|
||||||
|
@ -44,7 +44,6 @@ pub fn opts(os: &str, arch: Arch) -> TargetOptions {
|
|||||||
executables: true,
|
executables: true,
|
||||||
link_env_remove: link_env_remove(arch),
|
link_env_remove: link_env_remove(arch),
|
||||||
has_elf_tls: false,
|
has_elf_tls: false,
|
||||||
eliminate_frame_pointer: false,
|
|
||||||
..super::apple_base::opts(os)
|
..super::apple_base::opts(os)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// Clear previous flag; after a pointer indirection it does not apply any more.
|
// Clear previous flag; after a pointer indirection it does not apply any more.
|
||||||
inside_union = false;
|
inside_union = false;
|
||||||
}
|
}
|
||||||
if source.ty_adt_def().map_or(false, |adt| adt.is_union()) {
|
if source.is_union() {
|
||||||
inside_union = true;
|
inside_union = true;
|
||||||
}
|
}
|
||||||
// Fix up the autoderefs. Autorefs can only occur immediately preceding
|
// Fix up the autoderefs. Autorefs can only occur immediately preceding
|
||||||
|
@ -1588,6 +1588,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||||||
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
|
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
|
||||||
fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId) {
|
fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId) {
|
||||||
if let PlaceBase::Upvar(_) = place.base {
|
if let PlaceBase::Upvar(_) = place.base {
|
||||||
|
// We need to restrict Fake Read precision to avoid fake reading unsafe code,
|
||||||
|
// such as deref of a raw pointer.
|
||||||
|
let place = restrict_capture_precision(place);
|
||||||
|
let place =
|
||||||
|
restrict_repr_packed_field_ref_capture(self.fcx.tcx, self.fcx.param_env, &place);
|
||||||
self.fake_reads.push((place, cause, diag_expr_id));
|
self.fake_reads.push((place, cause, diag_expr_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2416,7 +2416,6 @@ impl<T> VecDeque<T> {
|
|||||||
/// found; the fourth could match any position in `[1, 4]`.
|
/// found; the fourth could match any position in `[1, 4]`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(vecdeque_binary_search)]
|
|
||||||
/// use std::collections::VecDeque;
|
/// use std::collections::VecDeque;
|
||||||
///
|
///
|
||||||
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
||||||
@ -2432,7 +2431,6 @@ impl<T> VecDeque<T> {
|
|||||||
/// sort order:
|
/// sort order:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(vecdeque_binary_search)]
|
|
||||||
/// use std::collections::VecDeque;
|
/// use std::collections::VecDeque;
|
||||||
///
|
///
|
||||||
/// let mut deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
/// let mut deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
||||||
@ -2441,7 +2439,7 @@ impl<T> VecDeque<T> {
|
|||||||
/// deque.insert(idx, num);
|
/// deque.insert(idx, num);
|
||||||
/// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
/// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
|
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
|
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
|
||||||
where
|
where
|
||||||
@ -2476,7 +2474,6 @@ impl<T> VecDeque<T> {
|
|||||||
/// found; the fourth could match any position in `[1, 4]`.
|
/// found; the fourth could match any position in `[1, 4]`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(vecdeque_binary_search)]
|
|
||||||
/// use std::collections::VecDeque;
|
/// use std::collections::VecDeque;
|
||||||
///
|
///
|
||||||
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
||||||
@ -2487,7 +2484,7 @@ impl<T> VecDeque<T> {
|
|||||||
/// let r = deque.binary_search_by(|x| x.cmp(&1));
|
/// let r = deque.binary_search_by(|x| x.cmp(&1));
|
||||||
/// assert!(matches!(r, Ok(1..=4)));
|
/// assert!(matches!(r, Ok(1..=4)));
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
|
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
|
||||||
pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
|
pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
|
||||||
where
|
where
|
||||||
F: FnMut(&'a T) -> Ordering,
|
F: FnMut(&'a T) -> Ordering,
|
||||||
@ -2530,7 +2527,6 @@ impl<T> VecDeque<T> {
|
|||||||
/// fourth could match any position in `[1, 4]`.
|
/// fourth could match any position in `[1, 4]`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(vecdeque_binary_search)]
|
|
||||||
/// use std::collections::VecDeque;
|
/// use std::collections::VecDeque;
|
||||||
///
|
///
|
||||||
/// let deque: VecDeque<_> = vec![(0, 0), (2, 1), (4, 1), (5, 1),
|
/// let deque: VecDeque<_> = vec![(0, 0), (2, 1), (4, 1), (5, 1),
|
||||||
@ -2543,7 +2539,7 @@ impl<T> VecDeque<T> {
|
|||||||
/// let r = deque.binary_search_by_key(&1, |&(a, b)| b);
|
/// let r = deque.binary_search_by_key(&1, |&(a, b)| b);
|
||||||
/// assert!(matches!(r, Ok(1..=4)));
|
/// assert!(matches!(r, Ok(1..=4)));
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
|
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
|
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
|
||||||
where
|
where
|
||||||
@ -2574,7 +2570,6 @@ impl<T> VecDeque<T> {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(vecdeque_binary_search)]
|
|
||||||
/// use std::collections::VecDeque;
|
/// use std::collections::VecDeque;
|
||||||
///
|
///
|
||||||
/// let deque: VecDeque<_> = vec![1, 2, 3, 3, 5, 6, 7].into();
|
/// let deque: VecDeque<_> = vec![1, 2, 3, 3, 5, 6, 7].into();
|
||||||
@ -2584,7 +2579,7 @@ impl<T> VecDeque<T> {
|
|||||||
/// assert!(deque.iter().take(i).all(|&x| x < 5));
|
/// assert!(deque.iter().take(i).all(|&x| x < 5));
|
||||||
/// assert!(deque.iter().skip(i).all(|&x| !(x < 5)));
|
/// assert!(deque.iter().skip(i).all(|&x| !(x < 5)));
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
|
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
|
||||||
pub fn partition_point<P>(&self, mut pred: P) -> usize
|
pub fn partition_point<P>(&self, mut pred: P) -> usize
|
||||||
where
|
where
|
||||||
P: FnMut(&T) -> bool,
|
P: FnMut(&T) -> bool,
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#![feature(binary_heap_as_slice)]
|
#![feature(binary_heap_as_slice)]
|
||||||
#![feature(inplace_iteration)]
|
#![feature(inplace_iteration)]
|
||||||
#![feature(iter_map_while)]
|
#![feature(iter_map_while)]
|
||||||
#![feature(vecdeque_binary_search)]
|
|
||||||
#![feature(slice_group_by)]
|
#![feature(slice_group_by)]
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
#![feature(vec_spare_capacity)]
|
#![feature(vec_spare_capacity)]
|
||||||
|
@ -727,8 +727,8 @@ impl f32 {
|
|||||||
///
|
///
|
||||||
/// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
|
/// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
|
||||||
///
|
///
|
||||||
/// See `from_bits` for some discussion of the portability of this operation
|
/// See [`from_bits`](Self::from_bits) for some discussion of the
|
||||||
/// (there are almost no issues).
|
/// portability of this operation (there are almost no issues).
|
||||||
///
|
///
|
||||||
/// Note that this function is distinct from `as` casting, which attempts to
|
/// Note that this function is distinct from `as` casting, which attempts to
|
||||||
/// preserve the *numeric* value, and not the bitwise value.
|
/// preserve the *numeric* value, and not the bitwise value.
|
||||||
|
@ -741,8 +741,8 @@ impl f64 {
|
|||||||
///
|
///
|
||||||
/// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
|
/// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
|
||||||
///
|
///
|
||||||
/// See `from_bits` for some discussion of the portability of this operation
|
/// See [`from_bits`](Self::from_bits) for some discussion of the
|
||||||
/// (there are almost no issues).
|
/// portability of this operation (there are almost no issues).
|
||||||
///
|
///
|
||||||
/// Note that this function is distinct from `as` casting, which attempts to
|
/// Note that this function is distinct from `as` casting, which attempts to
|
||||||
/// preserve the *numeric* value, and not the bitwise value.
|
/// preserve the *numeric* value, and not the bitwise value.
|
||||||
|
15
src/test/ui/const-generics/defaults/forward-declared.rs
Normal file
15
src/test/ui/const-generics/defaults/forward-declared.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#![feature(const_generics_defaults)]
|
||||||
|
|
||||||
|
struct Foo<const N: usize = M, const M: usize = 10>;
|
||||||
|
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
|
||||||
|
|
||||||
|
enum Bar<const N: usize = M, const M: usize = 10> {}
|
||||||
|
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
|
||||||
|
|
||||||
|
struct Foo2<const N: usize = N>;
|
||||||
|
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
|
||||||
|
|
||||||
|
enum Bar2<const N: usize = N> {}
|
||||||
|
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
|
||||||
|
|
||||||
|
fn main() {}
|
27
src/test/ui/const-generics/defaults/forward-declared.stderr
Normal file
27
src/test/ui/const-generics/defaults/forward-declared.stderr
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
error[E0128]: generic parameters with a default cannot use forward declared identifiers
|
||||||
|
--> $DIR/forward-declared.rs:3:29
|
||||||
|
|
|
||||||
|
LL | struct Foo<const N: usize = M, const M: usize = 10>;
|
||||||
|
| ^ defaulted generic parameters cannot be forward declared
|
||||||
|
|
||||||
|
error[E0128]: generic parameters with a default cannot use forward declared identifiers
|
||||||
|
--> $DIR/forward-declared.rs:6:27
|
||||||
|
|
|
||||||
|
LL | enum Bar<const N: usize = M, const M: usize = 10> {}
|
||||||
|
| ^ defaulted generic parameters cannot be forward declared
|
||||||
|
|
||||||
|
error[E0128]: generic parameters with a default cannot use forward declared identifiers
|
||||||
|
--> $DIR/forward-declared.rs:9:30
|
||||||
|
|
|
||||||
|
LL | struct Foo2<const N: usize = N>;
|
||||||
|
| ^ defaulted generic parameters cannot be forward declared
|
||||||
|
|
||||||
|
error[E0128]: generic parameters with a default cannot use forward declared identifiers
|
||||||
|
--> $DIR/forward-declared.rs:12:28
|
||||||
|
|
|
||||||
|
LL | enum Bar2<const N: usize = N> {}
|
||||||
|
| ^ defaulted generic parameters cannot be forward declared
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0128`.
|
16
src/test/ui/thread-local-static.rs
Normal file
16
src/test/ui/thread-local-static.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// edition:2018
|
||||||
|
|
||||||
|
#![feature(thread_local)]
|
||||||
|
#![feature(const_swap)]
|
||||||
|
#[thread_local]
|
||||||
|
static mut STATIC_VAR_2: [u32; 8] = [4; 8];
|
||||||
|
const fn g(x: &mut [u32; 8]) {
|
||||||
|
//~^ ERROR mutable references are not allowed
|
||||||
|
std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
//~^ ERROR thread-local statics cannot be accessed
|
||||||
|
//~| ERROR mutable references are not allowed
|
||||||
|
//~| ERROR use of mutable static is unsafe
|
||||||
|
//~| constant functions cannot refer to statics
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
44
src/test/ui/thread-local-static.stderr
Normal file
44
src/test/ui/thread-local-static.stderr
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
error[E0658]: mutable references are not allowed in constant functions
|
||||||
|
--> $DIR/thread-local-static.rs:7:12
|
||||||
|
|
|
||||||
|
LL | const fn g(x: &mut [u32; 8]) {
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||||
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0625]: thread-local statics cannot be accessed at compile-time
|
||||||
|
--> $DIR/thread-local-static.rs:9:28
|
||||||
|
|
|
||||||
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0013]: constant functions cannot refer to statics
|
||||||
|
--> $DIR/thread-local-static.rs:9:28
|
||||||
|
|
|
||||||
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||||
|
|
||||||
|
error[E0658]: mutable references are not allowed in constant functions
|
||||||
|
--> $DIR/thread-local-static.rs:9:23
|
||||||
|
|
|
||||||
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||||
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
||||||
|
--> $DIR/thread-local-static.rs:9:23
|
||||||
|
|
|
||||||
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
| ^^^^^^^^^^^^^^^^^ use of mutable static
|
||||||
|
|
|
||||||
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0013, E0133, E0658.
|
||||||
|
For more information about an error, try `rustc --explain E0013`.
|
@ -1 +1 @@
|
|||||||
Subproject commit e931e4796b61de593aa1097649445e535c9c7ee0
|
Subproject commit 0cecbd67323ca14a7eb6505900d0d7307b00355b
|
@ -79,7 +79,7 @@ trigger_labels = [
|
|||||||
"regression-from-stable-to-stable",
|
"regression-from-stable-to-stable",
|
||||||
"regression-from-stable-to-beta",
|
"regression-from-stable-to-beta",
|
||||||
"regression-from-stable-to-nightly",
|
"regression-from-stable-to-nightly",
|
||||||
"I-unsound 💥",
|
"I-unsound",
|
||||||
]
|
]
|
||||||
exclude_labels = [
|
exclude_labels = [
|
||||||
"P-*",
|
"P-*",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user