Skip to content

Commit 8e9d5db

Browse files
committed
Auto merge of #76912 - RalfJung:rollup-q9ur56h, r=RalfJung
Rollup of 14 pull requests Successful merges: - #73963 (deny(unsafe_op_in_unsafe_fn) in libstd/path.rs) - #75099 (lint/ty: move fns to avoid abstraction violation) - #75502 (Use implicit (not explicit) rules for promotability by default in `const fn`) - #75580 (Add test for checking duplicated branch or-patterns) - #76310 (Add `[T; N]: TryFrom<Vec<T>>` (insta-stable)) - #76400 (Clean up vec benches bench_in_place style) - #76434 (do not inline black_box when building for Miri) - #76492 (Add associated constant `BITS` to all integer types) - #76525 (Add as_str() to string::Drain.) - #76636 (assert ScalarMaybeUninit size) - #76749 (give *even better* suggestion when matching a const range) - #76757 (don't convert types to the same type with try_into (clippy::useless_conversion)) - #76796 (Give a better error message when x.py uses the wrong stage for CI) - #76798 (Build fixes for RISC-V 32-bit Linux support) Failed merges: r? `@ghost`
2 parents fd702d2 + b4c3f40 commit 8e9d5db

File tree

46 files changed

+456
-181
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+456
-181
lines changed

compiler/rustc_data_structures/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![feature(generators)]
1515
#![feature(generator_trait)]
1616
#![feature(fn_traits)]
17+
#![feature(int_bits_const)]
1718
#![feature(min_specialization)]
1819
#![feature(optin_builtin_traits)]
1920
#![feature(nll)]

compiler/rustc_data_structures/src/tagged_ptr/copy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ where
4848
P: Pointer,
4949
T: Tag,
5050
{
51-
const TAG_BIT_SHIFT: usize = (8 * std::mem::size_of::<usize>()) - T::BITS;
51+
const TAG_BIT_SHIFT: usize = usize::BITS as usize - T::BITS;
5252
const ASSERTION: () = {
5353
assert!(T::BITS <= P::BITS);
5454
// Used for the transmute_copy's below

compiler/rustc_lint/src/builtin.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
//! `late_lint_methods!` invocation in `lib.rs`.
2222
2323
use crate::{
24-
types::CItemKind, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
24+
types::{transparent_newtype_field, CItemKind},
25+
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
2526
};
2627
use rustc_ast::attr::{self, HasAttrs};
2728
use rustc_ast::tokenstream::{TokenStream, TokenTree};
@@ -2688,8 +2689,7 @@ impl ClashingExternDeclarations {
26882689
if is_transparent && !is_non_null {
26892690
debug_assert!(def.variants.len() == 1);
26902691
let v = &def.variants[VariantIdx::new(0)];
2691-
ty = v
2692-
.transparent_newtype_field(tcx)
2692+
ty = transparent_newtype_field(tcx, v)
26932693
.expect(
26942694
"single-variant transparent structure with zero-sized field",
26952695
)

compiler/rustc_lint/src/types.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,26 @@ crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: &ty::AdtD
639639
.any(|a| tcx.sess.check_name(a, sym::rustc_nonnull_optimization_guaranteed))
640640
}
641641

642+
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
643+
/// field.
644+
pub fn transparent_newtype_field<'a, 'tcx>(
645+
tcx: TyCtxt<'tcx>,
646+
variant: &'a ty::VariantDef,
647+
) -> Option<&'a ty::FieldDef> {
648+
let param_env = tcx.param_env(variant.def_id);
649+
for field in &variant.fields {
650+
let field_ty = tcx.type_of(field.did);
651+
let is_zst =
652+
tcx.layout_of(param_env.and(field_ty)).map(|layout| layout.is_zst()).unwrap_or(false);
653+
654+
if !is_zst {
655+
return Some(field);
656+
}
657+
}
658+
659+
None
660+
}
661+
642662
/// Is type known to be non-null?
643663
crate fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKind) -> bool {
644664
let tcx = cx.tcx;
@@ -654,7 +674,7 @@ crate fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: C
654674
}
655675

656676
for variant in &def.variants {
657-
if let Some(field) = variant.transparent_newtype_field(tcx) {
677+
if let Some(field) = transparent_newtype_field(cx.tcx, variant) {
658678
if ty_is_known_nonnull(cx, field.ty(tcx, substs), mode) {
659679
return true;
660680
}
@@ -675,7 +695,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
675695
ty::Adt(field_def, field_substs) => {
676696
let inner_field_ty = {
677697
let first_non_zst_ty =
678-
field_def.variants.iter().filter_map(|v| v.transparent_newtype_field(tcx));
698+
field_def.variants.iter().filter_map(|v| transparent_newtype_field(cx.tcx, v));
679699
debug_assert_eq!(
680700
first_non_zst_ty.clone().count(),
681701
1,
@@ -816,7 +836,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
816836
if def.repr.transparent() {
817837
// Can assume that only one field is not a ZST, so only check
818838
// that field's type for FFI-safety.
819-
if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) {
839+
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
820840
self.check_field_type_for_ffi(cache, field, substs)
821841
} else {
822842
bug!("malformed transparent type");

compiler/rustc_middle/src/mir/interpret/value.rs

+3
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,9 @@ pub enum ScalarMaybeUninit<Tag = ()> {
578578
Uninit,
579579
}
580580

581+
#[cfg(target_arch = "x86_64")]
582+
static_assert_size!(ScalarMaybeUninit, 24);
583+
581584
impl<Tag> From<Scalar<Tag>> for ScalarMaybeUninit<Tag> {
582585
#[inline(always)]
583586
fn from(s: Scalar<Tag>) -> Self {

compiler/rustc_middle/src/ty/mod.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ pub struct VariantDef {
19991999
flags: VariantFlags,
20002000
}
20012001

2002-
impl<'tcx> VariantDef {
2002+
impl VariantDef {
20032003
/// Creates a new `VariantDef`.
20042004
///
20052005
/// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
@@ -2065,19 +2065,6 @@ impl<'tcx> VariantDef {
20652065
pub fn is_recovered(&self) -> bool {
20662066
self.flags.intersects(VariantFlags::IS_RECOVERED)
20672067
}
2068-
2069-
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
2070-
/// field.
2071-
pub fn transparent_newtype_field(&self, tcx: TyCtxt<'tcx>) -> Option<&FieldDef> {
2072-
for field in &self.fields {
2073-
let field_ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.def_id));
2074-
if !field_ty.is_zst(tcx, self.def_id) {
2075-
return Some(field);
2076-
}
2077-
}
2078-
2079-
None
2080-
}
20812068
}
20822069

20832070
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]

compiler/rustc_middle/src/ty/sty.rs

-5
Original file line numberDiff line numberDiff line change
@@ -2322,9 +2322,4 @@ impl<'tcx> TyS<'tcx> {
23222322
}
23232323
}
23242324
}
2325-
2326-
/// Is this a zero-sized type?
2327-
pub fn is_zst(&'tcx self, tcx: TyCtxt<'tcx>, did: DefId) -> bool {
2328-
tcx.layout_of(tcx.param_env(did).and(self)).map(|layout| layout.is_zst()).unwrap_or(false)
2329-
}
23302325
}

compiler/rustc_mir/src/dataflow/move_paths/builder.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use rustc_middle::mir::*;
44
use rustc_middle::ty::{self, TyCtxt};
55
use smallvec::{smallvec, SmallVec};
66

7-
use std::convert::TryInto;
87
use std::mem;
98

109
use super::abs_domain::Lift;
@@ -481,12 +480,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
481480
};
482481
let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty;
483482
let len: u64 = match base_ty.kind() {
484-
ty::Array(_, size) => {
485-
let length = size.eval_usize(self.builder.tcx, self.builder.param_env);
486-
length
487-
.try_into()
488-
.expect("slice pattern of array with more than u32::MAX elements")
489-
}
483+
ty::Array(_, size) => size.eval_usize(self.builder.tcx, self.builder.param_env),
490484
_ => bug!("from_end: false slice pattern of non-array type"),
491485
};
492486
for offset in from..to {

compiler/rustc_mir/src/interpret/place.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ where
551551
let n = base.len(self)?;
552552
if n < min_length {
553553
// This can only be reached in ConstProp and non-rustc-MIR.
554-
throw_ub!(BoundsCheckFailed { len: min_length.into(), index: n });
554+
throw_ub!(BoundsCheckFailed { len: min_length, index: n });
555555
}
556556

557557
let index = if from_end {
@@ -565,9 +565,7 @@ where
565565
self.mplace_index(base, index)?
566566
}
567567

568-
Subslice { from, to, from_end } => {
569-
self.mplace_subslice(base, u64::from(from), u64::from(to), from_end)?
570-
}
568+
Subslice { from, to, from_end } => self.mplace_subslice(base, from, to, from_end)?,
571569
})
572570
}
573571

compiler/rustc_mir/src/transform/promote_consts.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,14 @@ impl<'tcx> Validator<'_, 'tcx> {
734734
) -> Result<(), Unpromotable> {
735735
let fn_ty = callee.ty(self.body, self.tcx);
736736

737-
if !self.explicit && self.const_kind.is_none() {
737+
// `const` and `static` use the explicit rules for promotion regardless of the `Candidate`,
738+
// meaning calls to `const fn` can be promoted.
739+
let context_uses_explicit_promotion_rules = matches!(
740+
self.const_kind,
741+
Some(hir::ConstContext::Static(_) | hir::ConstContext::Const)
742+
);
743+
744+
if !self.explicit && !context_uses_explicit_promotion_rules {
738745
if let ty::FnDef(def_id, _) = *fn_ty.kind() {
739746
// Never promote runtime `const fn` calls of
740747
// functions without `#[rustc_promotable]`.

compiler/rustc_mir_build/src/build/matches/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3333
let tcx = self.hir.tcx();
3434
let (min_length, exact_size) = match place.ty(&self.local_decls, tcx).ty.kind() {
3535
ty::Array(_, length) => {
36-
(length.eval_usize(tcx, self.hir.param_env).try_into().unwrap(), true)
36+
(length.eval_usize(tcx, self.hir.param_env), true)
3737
}
3838
_ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
3939
};

compiler/rustc_typeck/src/check/pat.rs

+46-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::check::FnCtxt;
22
use rustc_ast as ast;
3+
34
use rustc_ast::util::lev_distance::find_best_match_for_name;
45
use rustc_data_structures::fx::FxHashMap;
56
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
@@ -740,6 +741,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
740741
pat_ty
741742
}
742743

744+
fn maybe_suggest_range_literal(
745+
&self,
746+
e: &mut DiagnosticBuilder<'_>,
747+
opt_def_id: Option<hir::def_id::DefId>,
748+
ident: Ident,
749+
) -> bool {
750+
match opt_def_id {
751+
Some(def_id) => match self.tcx.hir().get_if_local(def_id) {
752+
Some(hir::Node::Item(hir::Item {
753+
kind: hir::ItemKind::Const(_, body_id), ..
754+
})) => match self.tcx.hir().get(body_id.hir_id) {
755+
hir::Node::Expr(expr) => {
756+
if hir::is_range_literal(expr) {
757+
let span = self.tcx.hir().span(body_id.hir_id);
758+
if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) {
759+
e.span_suggestion_verbose(
760+
ident.span,
761+
"you may want to move the range into the match block",
762+
snip,
763+
Applicability::MachineApplicable,
764+
);
765+
return true;
766+
}
767+
}
768+
}
769+
_ => (),
770+
},
771+
_ => (),
772+
},
773+
_ => (),
774+
}
775+
false
776+
}
777+
743778
fn emit_bad_pat_path(
744779
&self,
745780
mut e: DiagnosticBuilder<'_>,
@@ -772,12 +807,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
772807
);
773808
}
774809
_ => {
775-
let const_def_id = match pat_ty.kind() {
810+
let (type_def_id, item_def_id) = match pat_ty.kind() {
776811
Adt(def, _) => match res {
777-
Res::Def(DefKind::Const, _) => Some(def.did),
778-
_ => None,
812+
Res::Def(DefKind::Const, def_id) => (Some(def.did), Some(def_id)),
813+
_ => (None, None),
779814
},
780-
_ => None,
815+
_ => (None, None),
781816
};
782817

783818
let ranges = &[
@@ -788,11 +823,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
788823
self.tcx.lang_items().range_inclusive_struct(),
789824
self.tcx.lang_items().range_to_inclusive_struct(),
790825
];
791-
if const_def_id != None && ranges.contains(&const_def_id) {
792-
let msg = "constants only support matching by type, \
793-
if you meant to match against a range of values, \
794-
consider using a range pattern like `min ..= max` in the match block";
795-
e.note(msg);
826+
if type_def_id != None && ranges.contains(&type_def_id) {
827+
if !self.maybe_suggest_range_literal(&mut e, item_def_id, *ident) {
828+
let msg = "constants only support matching by type, \
829+
if you meant to match against a range of values, \
830+
consider using a range pattern like `min ..= max` in the match block";
831+
e.note(msg);
832+
}
796833
} else {
797834
let msg = "introduce a new binding instead";
798835
let sugg = format!("other_{}", ident.as_str().to_lowercase());

library/alloc/benches/vec.rs

+21-22
Original file line numberDiff line numberDiff line change
@@ -457,17 +457,16 @@ fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
457457
}
458458

459459
macro_rules! bench_in_place {
460-
(
461-
$($fname:ident, $type:ty , $count:expr, $init: expr);*
462-
) => {
460+
($($fname:ident, $type:ty, $count:expr, $init:expr);*) => {
463461
$(
464462
#[bench]
465463
fn $fname(b: &mut Bencher) {
466464
b.iter(|| {
467465
let src: Vec<$type> = black_box(vec![$init; $count]);
468466
let mut sink = src.into_iter()
469467
.enumerate()
470-
.map(|(idx, e)| { (idx as $type) ^ e }).collect::<Vec<$type>>();
468+
.map(|(idx, e)| idx as $type ^ e)
469+
.collect::<Vec<$type>>();
471470
black_box(sink.as_mut_ptr())
472471
});
473472
}
@@ -476,24 +475,24 @@ macro_rules! bench_in_place {
476475
}
477476

478477
bench_in_place![
479-
bench_in_place_xxu8_i0_0010, u8, 10, 0;
480-
bench_in_place_xxu8_i0_0100, u8, 100, 0;
481-
bench_in_place_xxu8_i0_1000, u8, 1000, 0;
482-
bench_in_place_xxu8_i1_0010, u8, 10, 1;
483-
bench_in_place_xxu8_i1_0100, u8, 100, 1;
484-
bench_in_place_xxu8_i1_1000, u8, 1000, 1;
485-
bench_in_place_xu32_i0_0010, u32, 10, 0;
486-
bench_in_place_xu32_i0_0100, u32, 100, 0;
487-
bench_in_place_xu32_i0_1000, u32, 1000, 0;
488-
bench_in_place_xu32_i1_0010, u32, 10, 1;
489-
bench_in_place_xu32_i1_0100, u32, 100, 1;
490-
bench_in_place_xu32_i1_1000, u32, 1000, 1;
491-
bench_in_place_u128_i0_0010, u128, 10, 0;
492-
bench_in_place_u128_i0_0100, u128, 100, 0;
493-
bench_in_place_u128_i0_1000, u128, 1000, 0;
494-
bench_in_place_u128_i1_0010, u128, 10, 1;
495-
bench_in_place_u128_i1_0100, u128, 100, 1;
496-
bench_in_place_u128_i1_1000, u128, 1000, 1
478+
bench_in_place_xxu8_0010_i0, u8, 10, 0;
479+
bench_in_place_xxu8_0100_i0, u8, 100, 0;
480+
bench_in_place_xxu8_1000_i0, u8, 1000, 0;
481+
bench_in_place_xxu8_0010_i1, u8, 10, 1;
482+
bench_in_place_xxu8_0100_i1, u8, 100, 1;
483+
bench_in_place_xxu8_1000_i1, u8, 1000, 1;
484+
bench_in_place_xu32_0010_i0, u32, 10, 0;
485+
bench_in_place_xu32_0100_i0, u32, 100, 0;
486+
bench_in_place_xu32_1000_i0, u32, 1000, 0;
487+
bench_in_place_xu32_0010_i1, u32, 10, 1;
488+
bench_in_place_xu32_0100_i1, u32, 100, 1;
489+
bench_in_place_xu32_1000_i1, u32, 1000, 1;
490+
bench_in_place_u128_0010_i0, u128, 10, 0;
491+
bench_in_place_u128_0100_i0, u128, 100, 0;
492+
bench_in_place_u128_1000_i0, u128, 1000, 0;
493+
bench_in_place_u128_0010_i1, u128, 10, 1;
494+
bench_in_place_u128_0100_i1, u128, 100, 1;
495+
bench_in_place_u128_1000_i1, u128, 1000, 1
497496
];
498497

499498
#[bench]

library/alloc/src/collections/binary_heap.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146

147147
use core::fmt;
148148
use core::iter::{FromIterator, FusedIterator, InPlaceIterable, SourceIter, TrustedLen};
149-
use core::mem::{self, size_of, swap, ManuallyDrop};
149+
use core::mem::{self, swap, ManuallyDrop};
150150
use core::ops::{Deref, DerefMut};
151151
use core::ptr;
152152

@@ -617,7 +617,7 @@ impl<T: Ord> BinaryHeap<T> {
617617

618618
#[inline(always)]
619619
fn log2_fast(x: usize) -> usize {
620-
8 * size_of::<usize>() - (x.leading_zeros() as usize) - 1
620+
(usize::BITS - x.leading_zeros() - 1) as usize
621621
}
622622

623623
// `rebuild` takes O(len1 + len2) operations

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
#![feature(fn_traits)]
102102
#![feature(fundamental)]
103103
#![feature(inplace_iteration)]
104+
#![feature(int_bits_const)]
104105
#![feature(lang_items)]
105106
#![feature(layout_for_ptr)]
106107
#![feature(libc)]

library/alloc/src/raw_vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ unsafe impl<#[may_dangle] T, A: AllocRef> Drop for RawVec<T, A> {
528528

529529
#[inline]
530530
fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
531-
if mem::size_of::<usize>() < 8 && alloc_size > isize::MAX as usize {
531+
if usize::BITS < 64 && alloc_size > isize::MAX as usize {
532532
Err(CapacityOverflow)
533533
} else {
534534
Ok(())

0 commit comments

Comments
 (0)