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",
|
||||
"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",
|
||||
|
@ -799,7 +799,7 @@ pub fn create_global_ctxt<'tcx>(
|
||||
query_result_on_disk_cache,
|
||||
queries.as_dyn(),
|
||||
&crate_name,
|
||||
&outputs,
|
||||
outputs,
|
||||
)
|
||||
})
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -1965,15 +1965,13 @@ 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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.report_use_of_moved_or_uninitialized(
|
||||
location,
|
||||
|
@ -331,20 +331,17 @@ 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() => {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(ProjectionElem::Downcast(_, v1), ProjectionElem::Downcast(_, v2)) => {
|
||||
// different variants are treated as having disjoint fields,
|
||||
// even if they occupy the same "space", because it's
|
||||
|
@ -519,12 +519,10 @@ 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() {
|
||||
if place_base.ty(self.builder.body, self.builder.tcx).ty.is_union() {
|
||||
place = place_base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) {
|
||||
let init = self.builder.data.inits.push(Init {
|
||||
|
@ -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,13 +752,9 @@ 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() => {
|
||||
if base_ty.is_union() {
|
||||
self.check_op(ops::UnionAccess);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -415,14 +415,12 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.validate_place(place_base)
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)) => {
|
||||
|
@ -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() {
|
||||
let place_builder =
|
||||
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
|
||||
@ -206,7 +203,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see (*) above
|
||||
let operands: Vec<_> = upvars
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
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-beta",
|
||||
"regression-from-stable-to-nightly",
|
||||
"I-unsound 💥",
|
||||
"I-unsound",
|
||||
]
|
||||
exclude_labels = [
|
||||
"P-*",
|
||||
|
Loading…
Reference in New Issue
Block a user