Skip to content

Rollup of 7 pull requests #133818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Dec 4, 2024
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -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",
]
@@ -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"
30 changes: 24 additions & 6 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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.
@@ -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:?}"),
}
}
@@ -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
@@ -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,
},
}
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
@@ -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;
@@ -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};
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
@@ -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))?;
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
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
@@ -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
@@ -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
@@ -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")),
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
@@ -497,8 +497,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.
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -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> {
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/base/aix.rs
Original file line number Diff line number Diff line change
@@ -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(),
Original file line number Diff line number Diff line change
@@ -329,10 +329,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.
26 changes: 1 addition & 25 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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),
}
});
Original file line number Diff line number Diff line change
@@ -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",
Loading