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:
bors 2021-06-03 08:02:39 +00:00
commit a93699f20a
36 changed files with 227 additions and 133 deletions

View File

@ -278,6 +278,7 @@ dependencies = [
"humantime 2.0.1",
"ignore",
"im-rc",
"itertools 0.10.0",
"jobserver",
"lazy_static",
"lazycell",
@ -293,7 +294,7 @@ dependencies = [
"rand 0.8.3",
"rustc-workspace-hack",
"rustfix",
"semver 0.10.0",
"semver 1.0.1",
"serde",
"serde_ignored",
"serde_json",
@ -1715,6 +1716,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.6"
@ -4674,6 +4684,15 @@ dependencies = [
"serde",
]
[[package]]
name = "semver"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d023dabf011d5dcb5ac64e3685d97d3b0ef412911077a2851455c6098524a723"
dependencies = [
"serde",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
@ -5033,9 +5052,9 @@ dependencies = [
[[package]]
name = "tar"
version = "0.4.33"
version = "0.4.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0bcfbd6a598361fda270d82469fff3d65089dc33e175c9a131f7b4cd395f228"
checksum = "7d779dc6aeff029314570f666ec83f19df7280bb36ef338442cfa8c604021b80"
dependencies = [
"filetime",
"libc",

View File

@ -799,7 +799,7 @@ pub fn create_global_ctxt<'tcx>(
query_result_on_disk_cache,
queries.as_dyn(),
&crate_name,
&outputs,
outputs,
)
})
});

View File

@ -5,7 +5,6 @@
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{is_range_literal, ExprKind, Node};
use rustc_index::vec::Idx;
use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
@ -13,7 +12,7 @@
use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP};
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 std::cmp;
@ -783,25 +782,14 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
) -> Option<Ty<'tcx>> {
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
if let ty::Adt(ty_def, substs) = ty.kind() {
if ty_def.variants.len() != 2 {
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)];
let fields = if variant_fields[0].is_empty() {
&variant_fields[1]
} else if variant_fields[1].is_empty() {
&variant_fields[0]
} else {
return None;
let field_ty = match &ty_def.variants.raw[..] {
[var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) {
([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
_ => return None,
},
_ => 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) {
return None;
}

View File

@ -25,7 +25,11 @@ macro_rules! pluralize {
/// before applying the suggestion.
#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
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.
MachineApplicable,

View File

@ -1135,7 +1135,7 @@ pub fn create_global_ctxt(
on_disk_cache: Option<query::OnDiskCache<'tcx>>,
queries: &'tcx dyn query::QueryEngine<'tcx>,
crate_name: &str,
output_filenames: &OutputFilenames,
output_filenames: OutputFilenames,
) -> GlobalCtxt<'tcx> {
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
s.fatal(&err);
@ -1179,7 +1179,7 @@ pub fn create_global_ctxt(
stability_interner: Default::default(),
const_stability_interner: Default::default(),
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,
}
}

View File

@ -1837,10 +1837,12 @@ pub fn is_trait(&self) -> bool {
#[inline]
pub fn is_enum(&self) -> bool {
match self.kind() {
Adt(adt_def, _) => adt_def.is_enum(),
_ => false,
}
matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum())
}
#[inline]
pub fn is_union(&self) -> bool {
matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union())
}
#[inline]

View File

@ -1965,13 +1965,11 @@ fn check_parent_of_field<'cx, 'tcx>(
// no move out from an earlier location) then this is an attempt at initialization
// of the union - we should error in that case.
let tcx = this.infcx.tcx;
if let ty::Adt(def, _) = base.ty(this.body(), tcx).ty.kind() {
if def.is_union() {
if this.move_data.path_map[mpi].iter().any(|moi| {
this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
}) {
return;
}
if base.ty(this.body(), tcx).ty.is_union() {
if this.move_data.path_map[mpi].iter().any(|moi| {
this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
}) {
return;
}
}

View File

@ -331,17 +331,14 @@ fn place_projection_conflict<'tcx>(
Overlap::EqualOrDisjoint
} else {
let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty;
match ty.kind() {
ty::Adt(def, _) if def.is_union() => {
// Different fields of a union, we are basically stuck.
debug!("place_element_conflict: STUCK-UNION");
Overlap::Arbitrary
}
_ => {
// Different fields of a struct (`a.x` vs. `a.y`). Disjoint!
debug!("place_element_conflict: DISJOINT-FIELD");
Overlap::Disjoint
}
if ty.is_union() {
// Different fields of a union, we are basically stuck.
debug!("place_element_conflict: STUCK-UNION");
Overlap::Arbitrary
} else {
// Different fields of a struct (`a.x` vs. `a.y`). Disjoint!
debug!("place_element_conflict: DISJOINT-FIELD");
Overlap::Disjoint
}
}
}

View File

@ -519,10 +519,8 @@ fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
// 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.
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 def.is_union() {
place = place_base;
}
if place_base.ty(self.builder.body, self.builder.tcx).ty.is_union() {
place = place_base;
}
}

View File

@ -356,10 +356,9 @@ pub fn check_op_spanned<O: NonConstOp>(&mut self, op: O, span: Span) {
}
fn check_static(&mut self, def_id: DefId, span: Span) {
assert!(
!self.tcx.is_thread_local_static(def_id),
"tls access is checked in `Rvalue::ThreadLocalRef"
);
if self.tcx.is_thread_local_static(def_id) {
self.tcx.sess.delay_span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef");
}
self.check_op_spanned(ops::StaticAccess, span)
}
@ -753,12 +752,8 @@ fn visit_projection_elem(
| ProjectionElem::Field(..)
| ProjectionElem::Index(_) => {
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
match base_ty.ty_adt_def() {
Some(def) if def.is_union() => {
self.check_op(ops::UnionAccess);
}
_ => {}
if base_ty.is_union() {
self.check_op(ops::UnionAccess);
}
}
}

View File

@ -221,7 +221,7 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
}
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
// rules are different.
let assign_to_field = !saw_deref

View File

@ -114,7 +114,7 @@
traversal, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, PlaceElem,
Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::TyCtxt;
// Empirical measurements have resulted in some observations:
// - Running on a body with a single block and 500 locals takes barely any time
@ -910,17 +910,8 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
// Handle the "subtle case" described above by rejecting any `dest` that is or
// 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);
if is_union(place_ty.ty) {
if place_ty.ty.is_union() {
return;
}
for elem in dest.projection {
@ -930,7 +921,7 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
}
place_ty = place_ty.projection_ty(self.tcx, elem);
if is_union(place_ty.ty) {
if place_ty.ty.is_union() {
return;
}
}

View File

@ -415,11 +415,9 @@ fn validate_place(&self, place: PlaceRef<'tcx>) -> Result<(), Unpromotable> {
ProjectionElem::Field(..) => {
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.
if def.is_union() {
return Err(Unpromotable);
}
return Err(Unpromotable);
}
}
}

View File

@ -69,21 +69,14 @@ fn involves_a_union<'tcx>(
tcx: TyCtxt<'tcx>,
) -> bool {
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;
}
for elem in place.projection {
place_ty = place_ty.projection_ty(tcx, elem);
if is_union(place_ty.ty) {
if place_ty.ty.is_union() {
return true;
}
}
return false;
}
fn is_union(ty: Ty<'_>) -> bool {
match ty.kind() {
ty::Adt(def, _) if def.is_union() => true,
_ => false,
}
}

View File

@ -11,8 +11,9 @@
use rustc_middle::mir::traversal;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind,
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceElem,
PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, StatementKind, Terminator,
TerminatorKind,
};
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
@ -217,6 +218,23 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: 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) {
match &statement.kind {
StatementKind::Assign(box (dest, rvalue)) => {

View File

@ -186,25 +186,21 @@ 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() {
let place_builder =
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
for (thir_place, cause, hir_id) in fake_reads.into_iter() {
let place_builder =
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
if let Ok(place_builder_resolved) =
place_builder.try_upvars_resolved(this.tcx, this.typeck_results)
{
let mir_place =
place_builder_resolved.into_place(this.tcx, this.typeck_results);
this.cfg.push_fake_read(
block,
this.source_info(this.tcx.hir().span(*hir_id)),
*cause,
mir_place,
);
}
if let Ok(place_builder_resolved) =
place_builder.try_upvars_resolved(this.tcx, this.typeck_results)
{
let mir_place =
place_builder_resolved.into_place(this.tcx, this.typeck_results);
this.cfg.push_fake_read(
block,
this.source_info(this.tcx.hir().span(*hir_id)),
*cause,
mir_place,
);
}
}

View File

@ -450,7 +450,7 @@ impl<'a> Resolver<'a> {
err.span_label(shadowed_binding_span, msg);
err
}
ResolutionError::ForwardDeclaredTyParam => {
ResolutionError::ForwardDeclaredGenericParam => {
let mut err = struct_span_err!(
self.session,
span,

View File

@ -242,7 +242,7 @@ enum ResolutionError<'a> {
shadowed_binding_span: Span,
},
/// 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.
ParamInTyOfConstParam(Symbol),
/// generic parameters must not be used inside const evaluations.
@ -2608,7 +2608,7 @@ fn validate_res_from_ribs(
let res_error = if rib_ident.name == kw::SelfUpper {
ResolutionError::SelfInTyParamDefault
} else {
ResolutionError::ForwardDeclaredTyParam
ResolutionError::ForwardDeclaredGenericParam
};
self.report_error(span, res_error);
}

View File

@ -10,7 +10,6 @@ pub fn target() -> Target {
arch: "aarch64".to_string(),
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".to_string(),
eliminate_frame_pointer: false,
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,

View File

@ -10,7 +10,6 @@ pub fn target() -> Target {
arch: "aarch64".to_string(),
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a12".to_string(),
eliminate_frame_pointer: false,
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,

View File

@ -18,7 +18,6 @@ pub fn target() -> Target {
arch: "aarch64".to_string(),
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".to_string(),
eliminate_frame_pointer: false,
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,

View File

@ -10,7 +10,6 @@ pub fn target() -> Target {
arch: "aarch64".to_string(),
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".to_string(),
eliminate_frame_pointer: false,
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,

View File

@ -27,6 +27,7 @@ pub fn opts(os: &str) -> TargetOptions {
families: vec!["unix".to_string()],
is_like_osx: true,
dwarf_version: Some(2),
eliminate_frame_pointer: false,
has_rpath: true,
dll_suffix: ".dylib".to_string(),
archive_format: "darwin".to_string(),

View File

@ -44,7 +44,6 @@ pub fn opts(os: &str, arch: Arch) -> TargetOptions {
executables: true,
link_env_remove: link_env_remove(arch),
has_elf_tls: false,
eliminate_frame_pointer: false,
..super::apple_base::opts(os)
}
}

View File

@ -248,7 +248,7 @@ pub fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
// Clear previous flag; after a pointer indirection it does not apply any more.
inside_union = false;
}
if source.ty_adt_def().map_or(false, |adt| adt.is_union()) {
if source.is_union() {
inside_union = true;
}
// Fix up the autoderefs. Autorefs can only occur immediately preceding

View File

@ -1588,6 +1588,11 @@ fn init_capture_info_for_place(
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) {
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));
}
}

View File

@ -2416,7 +2416,6 @@ unsafe fn rotate_right_inner(&mut self, k: usize) {
/// found; the fourth could match any position in `[1, 4]`.
///
/// ```
/// #![feature(vecdeque_binary_search)]
/// use std::collections::VecDeque;
///
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
@ -2432,7 +2431,6 @@ unsafe fn rotate_right_inner(&mut self, k: usize) {
/// sort order:
///
/// ```
/// #![feature(vecdeque_binary_search)]
/// use std::collections::VecDeque;
///
/// let mut deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
@ -2441,7 +2439,7 @@ unsafe fn rotate_right_inner(&mut self, k: usize) {
/// deque.insert(idx, num);
/// 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]
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
where
@ -2476,7 +2474,6 @@ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
/// found; the fourth could match any position in `[1, 4]`.
///
/// ```
/// #![feature(vecdeque_binary_search)]
/// use std::collections::VecDeque;
///
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
@ -2487,7 +2484,7 @@ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
/// let r = deque.binary_search_by(|x| x.cmp(&1));
/// 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>
where
F: FnMut(&'a T) -> Ordering,
@ -2530,7 +2527,6 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
/// fourth could match any position in `[1, 4]`.
///
/// ```
/// #![feature(vecdeque_binary_search)]
/// use std::collections::VecDeque;
///
/// let deque: VecDeque<_> = vec![(0, 0), (2, 1), (4, 1), (5, 1),
@ -2543,7 +2539,7 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
/// let r = deque.binary_search_by_key(&1, |&(a, b)| b);
/// assert!(matches!(r, Ok(1..=4)));
/// ```
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
#[inline]
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
where
@ -2574,7 +2570,6 @@ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize
/// # Examples
///
/// ```
/// #![feature(vecdeque_binary_search)]
/// use std::collections::VecDeque;
///
/// let deque: VecDeque<_> = vec![1, 2, 3, 3, 5, 6, 7].into();
@ -2584,7 +2579,7 @@ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize
/// assert!(deque.iter().take(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
where
P: FnMut(&T) -> bool,

View File

@ -17,7 +17,6 @@
#![feature(binary_heap_as_slice)]
#![feature(inplace_iteration)]
#![feature(iter_map_while)]
#![feature(vecdeque_binary_search)]
#![feature(slice_group_by)]
#![feature(slice_partition_dedup)]
#![feature(vec_spare_capacity)]

View File

@ -727,8 +727,8 @@ pub unsafe fn to_int_unchecked<Int>(self) -> Int
///
/// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
///
/// See `from_bits` for some discussion of the portability of this operation
/// (there are almost no issues).
/// See [`from_bits`](Self::from_bits) for some discussion of the
/// portability of this operation (there are almost no issues).
///
/// Note that this function is distinct from `as` casting, which attempts to
/// preserve the *numeric* value, and not the bitwise value.

View File

@ -741,8 +741,8 @@ pub unsafe fn to_int_unchecked<Int>(self) -> Int
///
/// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
///
/// See `from_bits` for some discussion of the portability of this operation
/// (there are almost no issues).
/// See [`from_bits`](Self::from_bits) for some discussion of the
/// portability of this operation (there are almost no issues).
///
/// Note that this function is distinct from `as` casting, which attempts to
/// preserve the *numeric* value, and not the bitwise value.

View 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() {}

View 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`.

View 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() {}

View 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

View File

@ -79,7 +79,7 @@ trigger_labels = [
"regression-from-stable-to-stable",
"regression-from-stable-to-beta",
"regression-from-stable-to-nightly",
"I-unsound 💥",
"I-unsound",
]
exclude_labels = [
"P-*",