Skip to content

Commit

Permalink
Auto merge of rust-lang#133818 - matthiaskrgr:rollup-iav1wq7, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#132937 (a release operation synchronizes with an acquire operation)
 - rust-lang#133681 (improve TagEncoding::Niche docs, sanity check, and UB checks)
 - rust-lang#133726 (Add `core::arch::breakpoint` and test)
 - rust-lang#133768 (Remove `generic_associated_types_extended` feature gate)
 - rust-lang#133811 ([AIX] change AIX default codemodel=large)
 - rust-lang#133812 (Update wasm-component-ld to 0.5.11)
 - rust-lang#133813 (compiletest: explain that UI tests are expected not to compile by default)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 4, 2024
2 parents c44b3d5 + cd56913 commit 3b38264
Show file tree
Hide file tree
Showing 51 changed files with 566 additions and 240 deletions.
13 changes: 11 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5803,17 +5803,20 @@ checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"

[[package]]
name = "wasm-component-ld"
version = "0.5.10"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d4aa6bd7fbe7cffbed29fe3e236fda74419def1bdef6f80f989ec51137edf44"
checksum = "a2b05c3820968b335f10e703218459e4fd2cc91fdfc8f7936a993f1aacaa0938"
dependencies = [
"anyhow",
"clap",
"lexopt",
"libc",
"tempfile",
"wasi-preview1-component-adapter-provider",
"wasmparser 0.219.1",
"wat",
"windows-sys 0.59.0",
"winsplit",
"wit-component",
"wit-parser",
]
Expand Down Expand Up @@ -6185,6 +6188,12 @@ dependencies = [
"memchr",
]

[[package]]
name = "winsplit"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab703352da6a72f35c39a533526393725640575bb211f61987a2748323ad956"

[[package]]
name = "wit-component"
version = "0.219.1"
Expand Down
30 changes: 24 additions & 6 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,15 @@ impl Scalar {
Scalar::Union { .. } => true,
}
}

/// Returns `true` if this is a signed integer scalar
#[inline]
pub fn is_signed(&self) -> bool {
match self.primitive() {
Primitive::Int(_, signed) => signed,
_ => false,
}
}
}

// NOTE: This struct is generic over the FieldIdx for rust-analyzer usage.
Expand Down Expand Up @@ -1401,10 +1410,7 @@ impl BackendRepr {
#[inline]
pub fn is_signed(&self) -> bool {
match self {
BackendRepr::Scalar(scal) => match scal.primitive() {
Primitive::Int(_, signed) => signed,
_ => false,
},
BackendRepr::Scalar(scal) => scal.is_signed(),
_ => panic!("`is_signed` on non-scalar ABI {self:?}"),
}
}
Expand Down Expand Up @@ -1499,7 +1505,11 @@ impl BackendRepr {
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
Single { index: VariantIdx },
Single {
/// Always 0 for non-enums/generators.
/// For enums without a variant, this is an invalid index!
index: VariantIdx,
},

/// Enum-likes with more than one variant: each variant comes with
/// a *discriminant* (usually the same as the variant index but the user can
Expand Down Expand Up @@ -1528,14 +1538,22 @@ pub enum TagEncoding<VariantIdx: Idx> {
/// The variant `untagged_variant` contains a niche at an arbitrary
/// offset (field `tag_field` of the enum), which for a variant with
/// discriminant `d` is set to
/// `(d - niche_variants.start).wrapping_add(niche_start)`.
/// `(d - niche_variants.start).wrapping_add(niche_start)`
/// (this is wrapping arithmetic using the type of the niche field).
///
/// For example, `Option<(usize, &T)>` is represented such that
/// `None` has a null pointer for the second tuple field, and
/// `Some` is the identity function (with a non-null reference).
///
/// Other variants that are not `untagged_variant` and that are outside the `niche_variants`
/// range cannot be represented; they must be uninhabited.
Niche {
untagged_variant: VariantIdx,
/// This range *may* contain `untagged_variant`; that is then just a "dead value" and
/// not used to encode anything.
niche_variants: RangeInclusive<VariantIdx>,
/// This is inbounds of the type of the niche field
/// (not sign-extended, i.e., all bits beyond the niche field size are 0).
niche_start: u128,
},
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use rustc_abi::VariantIdx;
use rustc_middle::query::{Key, TyCtxtAt};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use tracing::instrument;
Expand Down Expand Up @@ -85,5 +86,6 @@ pub fn tag_for_variant_provider<'tcx>(
crate::const_eval::DummyMachine,
);

ecx.tag_for_variant(ty, variant_index).unwrap().map(|(tag, _tag_field)| tag)
let layout = ecx.layout_of(ty).unwrap();
ecx.tag_for_variant(layout, variant_index).unwrap().map(|(tag, _tag_field)| tag)
}
45 changes: 25 additions & 20 deletions compiler/rustc_const_eval/src/interpret/discriminant.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines).
use rustc_abi::{self as abi, TagEncoding, VariantIdx, Variants};
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt};
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
use rustc_middle::ty::{self, CoroutineArgsExt, ScalarInt, Ty};
use rustc_middle::{mir, span_bug};
use tracing::{instrument, trace};
Expand All @@ -21,17 +21,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
variant_index: VariantIdx,
dest: &impl Writeable<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
// Layout computation excludes uninhabited variants from consideration
// therefore there's no way to represent those variants in the given layout.
// Essentially, uninhabited variants do not have a tag that corresponds to their
// discriminant, so we cannot do anything here.
// When evaluating we will always error before even getting here, but ConstProp 'executes'
// dead code, so we cannot ICE here.
if dest.layout().for_variant(self, variant_index).is_uninhabited() {
throw_ub!(UninhabitedEnumVariantWritten(variant_index))
}

match self.tag_for_variant(dest.layout().ty, variant_index)? {
match self.tag_for_variant(dest.layout(), variant_index)? {
Some((tag, tag_field)) => {
// No need to validate that the discriminant here because the
// `TyAndLayout::for_variant()` call earlier already checks the
Expand Down Expand Up @@ -80,7 +70,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
if ty.is_enum() {
// Hilariously, `Single` is used even for 0-variant enums.
// (See https://github.com/rust-lang/rust/issues/89765).
if matches!(ty.kind(), ty::Adt(def, ..) if def.variants().is_empty()) {
if ty.ty_adt_def().unwrap().variants().is_empty() {
throw_ub!(UninhabitedEnumVariantRead(index))
}
// For consistency with `write_discriminant`, and to make sure that
Expand Down Expand Up @@ -188,6 +178,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let variants =
ty.ty_adt_def().expect("tagged layout for non adt").variants();
assert!(variant_index < variants.next_index());
if variant_index == untagged_variant {
// The untagged variant can be in the niche range, but even then it
// is not a valid encoding.
throw_ub!(InvalidTag(Scalar::from_uint(tag_bits, tag_layout.size)))
}
variant_index
} else {
untagged_variant
Expand Down Expand Up @@ -236,10 +231,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// given field index.
pub(crate) fn tag_for_variant(
&self,
ty: Ty<'tcx>,
layout: TyAndLayout<'tcx>,
variant_index: VariantIdx,
) -> InterpResult<'tcx, Option<(ScalarInt, usize)>> {
match self.layout_of(ty)?.variants {
// Layout computation excludes uninhabited variants from consideration.
// Therefore, there's no way to represent those variants in the given layout.
// Essentially, uninhabited variants do not have a tag that corresponds to their
// discriminant, so we have to bail out here.
if layout.for_variant(self, variant_index).is_uninhabited() {
throw_ub!(UninhabitedEnumVariantWritten(variant_index))
}

match layout.variants {
abi::Variants::Single { .. } => {
// The tag of a `Single` enum is like the tag of the niched
// variant: there's no tag as the discriminant is encoded
Expand All @@ -260,7 +263,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// raw discriminants for enums are isize or bigger during
// their computation, but the in-memory tag is the smallest possible
// representation
let discr = self.discriminant_for_variant(ty, variant_index)?;
let discr = self.discriminant_for_variant(layout.ty, variant_index)?;
let discr_size = discr.layout.size;
let discr_val = discr.to_scalar().to_bits(discr_size)?;
let tag_size = tag_layout.size(self);
Expand All @@ -286,11 +289,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
..
} => {
assert!(variant_index != untagged_variant);
// We checked that this variant is inhabited, so it must be in the niche range.
assert!(
niche_variants.contains(&variant_index),
"invalid variant index for this enum"
);
let variants_start = niche_variants.start().as_u32();
let variant_index_relative = variant_index
.as_u32()
.checked_sub(variants_start)
.expect("overflow computing relative variant idx");
let variant_index_relative = variant_index.as_u32().strict_sub(variants_start);
// We need to use machine arithmetic when taking into account `niche_start`:
// tag_val = variant_index_relative + niche_start_val
let tag_layout = self.layout_of(tag_layout.primitive().to_int_ty(*self.tcx))?;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(slice_ptr_get)]
#![feature(strict_overflow_ops)]
#![feature(trait_alias)]
#![feature(try_blocks)]
#![feature(unqualified_local_imports)]
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0622.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ Erroneous code example:
#![allow(internal_features)]
extern "rust-intrinsic" {
pub static breakpoint: fn(); // error: intrinsic must be a function
pub static atomic_singlethreadfence_seqcst: fn();
// error: intrinsic must be a function
}
fn main() { unsafe { breakpoint(); } }
fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
```

An intrinsic is a function available for use in a given programming language
Expand All @@ -22,8 +23,8 @@ error, just declare a function. Example:
#![allow(internal_features)]
extern "rust-intrinsic" {
pub fn breakpoint(); // ok!
pub fn atomic_singlethreadfence_seqcst(); // ok!
}
fn main() { unsafe { breakpoint(); } }
fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
```
7 changes: 7 additions & 0 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ declare_features! (
(removed, generator_clone, "1.65.0", Some(95360), Some("renamed to `coroutine_clone`")),
/// Allows defining generators.
(removed, generators, "1.21.0", Some(43122), Some("renamed to `coroutines`")),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
(removed, generic_associated_types_extended, "CURRENT_RUSTC_VERSION", Some(95451),
Some(
"feature needs overhaul and reimplementation pending \
better implied higher-ranked implied bounds support"
)
),
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
(removed, impl_trait_in_bindings, "1.55.0", Some(63065),
Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,6 @@ declare_features! (
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
(unstable, generic_arg_infer, "1.55.0", Some(85077)),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
(incomplete, generic_associated_types_extended, "1.61.0", Some(95451)),
/// Allows non-trivial generic constants which have to have wfness manually propagated to callers
(incomplete, generic_const_exprs, "1.56.0", Some(76560)),
/// Allows generic parameters and where-clauses on free & associated const items.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
| sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_mem_uninitialized_valid
| sym::breakpoint
| sym::size_of
| sym::min_align_of
| sym::needs_drop
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,8 @@ rustc_queries! {
}

/// Computes the tag (if any) for a given type and variant.
/// `None` means that the variant doesn't need a tag (because it is niched).
/// Will panic for uninhabited variants.
query tag_for_variant(
key: (Ty<'tcx>, abi::VariantIdx)
) -> Option<ty::ScalarInt> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/base/aix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::spec::{Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, cr
pub(crate) fn opts() -> TargetOptions {
TargetOptions {
abi: "vec-extabi".into(),
code_model: Some(CodeModel::Small),
code_model: Some(CodeModel::Large),
cpu: "pwr7".into(),
os: "aix".into(),
vendor: "ibm".into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,7 @@ pub fn dyn_compatibility_violations_for_assoc_item(
.collect(),
// Associated types can only be dyn-compatible if they have `Self: Sized` bounds.
ty::AssocKind::Type => {
if !tcx.features().generic_associated_types_extended()
&& !tcx.generics_of(item.def_id).is_own_empty()
&& !item.is_impl_trait_in_trait()
{
if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() {
vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)]
} else {
// We will permit associated types if they are explicitly mentioned in the trait object.
Expand Down
26 changes: 1 addition & 25 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::traits::select::OverflowError;
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::sym;
Expand Down Expand Up @@ -179,35 +179,11 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
) -> ProjectAndUnifyResult<'tcx> {
let infcx = selcx.infcx;
let r = infcx.commit_if_ok(|_snapshot| {
let old_universe = infcx.universe();
let placeholder_predicate = infcx.enter_forall_and_leak_universe(obligation.predicate);
let new_universe = infcx.universe();

let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
match project_and_unify_term(selcx, &placeholder_obligation) {
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
ProjectAndUnifyResult::Holds(obligations)
if old_universe != new_universe
&& selcx.tcx().features().generic_associated_types_extended() =>
{
// If the `generic_associated_types_extended` feature is active, then we ignore any
// obligations references lifetimes from any universe greater than or equal to the
// universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`,
// which isn't quite what we want. Ideally, we want either an implied
// `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we
// instantiate concrete regions. There is design work to be done here; until then,
// however, this allows experimenting potential GAT features without running into
// well-formedness issues.
let new_obligations = obligations
.into_iter()
.filter(|obligation| {
let mut visitor = MaxUniverse::new();
obligation.predicate.visit_with(&mut visitor);
visitor.max_universe() < new_universe
})
.collect();
Ok(ProjectAndUnifyResult::Holds(new_obligations))
}
other => Ok(other),
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
for assoc_type in assoc_types {
let defs: &ty::Generics = tcx.generics_of(assoc_type);

if !defs.own_params.is_empty() && !tcx.features().generic_associated_types_extended() {
if !defs.own_params.is_empty() {
tcx.dcx().span_delayed_bug(
obligation.cause.span,
"GATs in trait object shouldn't have been considered",
Expand Down
Loading

0 comments on commit 3b38264

Please sign in to comment.