Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2509,7 +2509,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
let span = cx.tcx.def_span(adt_def.did());
let mut potential_variants = adt_def.variants().iter().filter_map(|variant| {
let definitely_inhabited = match variant
.inhabited_predicate(cx.tcx, *adt_def)
.inhabited_predicate(cx.tcx)
.instantiate(cx.tcx, args)
.apply_any_module(cx.tcx, cx.typing_env())
{
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2210,7 +2210,7 @@ rustc_queries! {
feedable
}

query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
query inhabited_predicate_for_def(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
desc { "computing the uninhabited predicate of `{:?}`", key }
}

Expand Down
97 changes: 58 additions & 39 deletions compiler/rustc_middle/src/ty/inhabitedness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,23 @@
use std::assert_matches;

use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::DefKind;
use rustc_span::def_id::LocalModId;
use rustc_type_ir::TyKind::*;
use tracing::instrument;

use crate::query::Providers;
use crate::ty::{self, DefId, Ty, TyCtxt, TypeVisitableExt, TypingEnv, VariantDef, Visibility};
use crate::ty::{
self, AdtDef, DefId, Ty, TyCtxt, TypeVisitableExt, TypingEnv, VariantDef, Visibility,
};

pub mod inhabited_predicate;

pub use inhabited_predicate::InhabitedPredicate;

pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
inhabited_predicate_adt,
inhabited_predicate_for_def,
inhabited_predicate_type,
is_opsem_inhabited_raw,
..*providers
Expand All @@ -68,48 +71,64 @@ pub(crate) fn provide(providers: &mut Providers) {

/// Returns an `InhabitedPredicate` that is generic over type parameters and
/// requires calling [`InhabitedPredicate::instantiate`]
fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
if let Some(def_id) = def_id.as_local() {
tcx.ensure_ok().check_representability(def_id);
fn inhabited_predicate_for_def(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
match tcx.def_kind(def_id) {
DefKind::Enum => {
if let Some(def_id) = def_id.as_local() {
tcx.ensure_ok().check_representability(def_id);
}
let adt = tcx.adt_def(def_id);
InhabitedPredicate::any(tcx, adt.variants().iter().map(|v| v.inhabited_predicate(tcx)))
}
DefKind::Struct => {
if let Some(def_id) = def_id.as_local() {
tcx.ensure_ok().check_representability(def_id);
}
let adt = tcx.adt_def(def_id);
variant_inhabited_predicate(tcx, adt, adt.non_enum_variant())
}
DefKind::Variant => {
let adt = tcx.adt_def(tcx.parent(def_id));
let variant = adt.variant_with_id(def_id);
variant_inhabited_predicate(tcx, adt, variant)
}
def_kind => bug!("unexpected DefKind: {def_kind:?}"),
}

let adt = tcx.adt_def(def_id);
InhabitedPredicate::any(
tcx,
adt.variants().iter().map(|variant| variant.inhabited_predicate(tcx, adt)),
)
}

impl<'tcx> VariantDef {
/// Calculates the forest of `DefId`s from which this variant is visibly uninhabited.
pub fn inhabited_predicate(
&self,
tcx: TyCtxt<'tcx>,
adt: ty::AdtDef<'_>,
) -> InhabitedPredicate<'tcx> {
debug_assert!(!adt.is_union());
InhabitedPredicate::all(
tcx,
self.fields.iter().map(|field| {
let pred = tcx
.type_of(field.did)
.instantiate_identity()
.skip_norm_wip()
.inhabited_predicate(tcx);
if adt.is_enum() {
return pred;
}
match field.vis {
Visibility::Public => pred,
Visibility::Restricted(from) => {
InhabitedPredicate::NotInModule(from).or(tcx, pred)
}
}
}),
)
impl VariantDef {
pub fn inhabited_predicate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> InhabitedPredicate<'tcx> {
if self.fields.is_empty() {
return InhabitedPredicate::True;
}
tcx.inhabited_predicate_for_def(self.def_id)
}
}

fn variant_inhabited_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
adt: AdtDef<'tcx>,
variant: &VariantDef,
) -> InhabitedPredicate<'tcx> {
InhabitedPredicate::all(
tcx,
variant.fields.iter().map(|field| {
let pred = tcx
.type_of(field.did)
.instantiate_identity()
.skip_norm_wip()
.inhabited_predicate(tcx);
if adt.is_enum() {
return pred;
}
match field.vis {
Visibility::Public => pred,
Visibility::Restricted(from) => InhabitedPredicate::NotInModule(from).or(tcx, pred),
}
}),
)
}

impl<'tcx> Ty<'tcx> {
#[instrument(level = "debug", skip(tcx), ret)]
pub fn inhabited_predicate(self, tcx: TyCtxt<'tcx>) -> InhabitedPredicate<'tcx> {
Expand Down Expand Up @@ -228,7 +247,7 @@ impl<'tcx> Ty<'tcx> {
/// N.B. this query should only be called through `Ty::inhabited_predicate`
fn inhabited_predicate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> InhabitedPredicate<'tcx> {
match *ty.kind() {
Adt(adt, args) => tcx.inhabited_predicate_adt(adt.did()).instantiate(tcx, args),
Adt(adt, args) => tcx.inhabited_predicate_for_def(adt.did()).instantiate(tcx, args),

Tuple(tys) => {
InhabitedPredicate::all(tcx, tys.iter().map(|ty| ty.inhabited_predicate(tcx)))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
{
let variant_inhabited = adt
.variant(*variant_index)
.inhabited_predicate(self.tcx, *adt)
.inhabited_predicate(self.tcx)
.instantiate(self.tcx, args);
variant_inhabited.apply(self.tcx, cx.typing_env, cx.module)
&& !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
let variant_def_id = def.variant(idx).def_id;
// Visibly uninhabited variants.
let is_inhabited = v
.inhabited_predicate(cx.tcx, *def)
.inhabited_predicate(cx.tcx)
.instantiate(cx.tcx, args)
.apply_revealing_opaque(cx.tcx, cx.typing_env, cx.module, &|key| {
cx.reveal_opaque_key(key)
Expand Down
29 changes: 29 additions & 0 deletions src/etc/lldb_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,29 @@ class LLDBFeature(Flag):
Float128 = auto()
"""Added in LLDB 22.1. Adds builtin support for Float 128's, including an `eBasicTypeFloat128`,
a formatter, and handlers in `TypeSystemClang`"""
GetParent = auto()
"""Added in LLDB 23.1. Adds `SBValue.GetParent`, which retrieves the `SBValue` that the caller
originates from. Useful when a child object must be modified/styled based on information only
available to is parent e.g. unsized array types that must determine their length via the parent
wide pointer value."""
ProviderDecorator = auto()
"""Added in LLDB 23.1. Adds `@lldb.summary` and `@lldb.synthetic`, which can automatically
register decorated providers. At time of writing, we do not use this feature for the following
reasons:

1. backwards compatibility
2. to maintain more strict control over the order in which providers are loaded"""
PerObjectSynthetics = auto()
"""Currently only available in prerelease. Adds:

* `SBValue.SetTypeSynthetic` - allows synthetic providers to override their children's synthetic
provider without overriding the synthetic provider of all objects with that share a type name.
* `SBValue.GetTypeSyntheticImplementation` - retrieves the *instance* of the synthetic provider
associated with that variable. This allows us to easily inspect the state of a parent/child
and use it to make decisions about the current object without needing to redo work. It is worth
noting that this can be achieved backwards-compatibly (though less elegantly) by using a global
`weakref.WeakValueDictionary`, with the keys being `SBValue.GetID()` (which are unique per
session) and the values being the provider instance."""


def detect_features() -> LLDBFeature:
Expand All @@ -93,6 +116,12 @@ def detect_features() -> LLDBFeature:
features |= LLDBFeature.TypeRecognizers
if getattr(lldb, "eBasicTypeFloat128", None) is not None:
features |= LLDBFeature.Float128
if getattr(lldb.SBValue, "GetParent", None) is not None:
features |= LLDBFeature.GetParent
if getattr(lldb, "summary", None) is not None:
features |= LLDBFeature.ProviderDecorator
if getattr(lldb.SBValue, "SetTypeSynthetic", None) is not None:
features |= LLDBFeature.PerObjectSynthetics

return features

Expand Down
5 changes: 0 additions & 5 deletions src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,6 @@ ui/consts/issue-28113.rs
ui/consts/issue-28822.rs
ui/consts/issue-29798.rs
ui/consts/issue-29914-2.rs
ui/consts/issue-29914-3.rs
ui/consts/issue-29914.rs
ui/consts/issue-29927-1.rs
ui/consts/issue-29927.rs
Expand Down Expand Up @@ -1915,7 +1914,6 @@ ui/parser/issues/issue-17718-parse-const.rs
ui/parser/issues/issue-17904-2.rs
ui/parser/issues/issue-17904.rs
ui/parser/issues/issue-1802-1.rs
ui/parser/issues/issue-1802-2.rs
ui/parser/issues/issue-19096.rs
ui/parser/issues/issue-19398.rs
ui/parser/issues/issue-20616-1.rs
Expand Down Expand Up @@ -2764,7 +2762,6 @@ ui/type-alias-impl-trait/issue-57961.rs
ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs
ui/type-alias-impl-trait/issue-58662-simplified.rs
ui/type-alias-impl-trait/issue-58887.rs
ui/type-alias-impl-trait/issue-58951-2.rs
ui/type-alias-impl-trait/issue-58951.rs
ui/type-alias-impl-trait/issue-60371.rs
ui/type-alias-impl-trait/issue-60407.rs
Expand All @@ -2790,7 +2787,6 @@ ui/type-alias-impl-trait/issue-70121.rs
ui/type-alias-impl-trait/issue-72793.rs
ui/type-alias-impl-trait/issue-74244.rs
ui/type-alias-impl-trait/issue-74280.rs
ui/type-alias-impl-trait/issue-74761-2.rs
ui/type-alias-impl-trait/issue-74761.rs
ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
ui/type-alias-impl-trait/issue-77179.rs
Expand Down Expand Up @@ -2955,7 +2951,6 @@ ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs
ui/unsafe/issue-47412.rs
ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs
ui/unsafe/issue-87414-query-cycle.rs
ui/unsized-locals/issue-30276-feature-flagged.rs
ui/unsized-locals/issue-30276.rs
ui/unsized-locals/issue-50940-with-feature.rs
ui/unsized-locals/issue-50940.rs
Expand Down
20 changes: 20 additions & 0 deletions tests/assembly-llvm/x86-vendor-intrinsics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ only-x86_64
//@ assembly-output: emit-asm
//@ compile-flags: -Ctarget-feature=-sse3 -C opt-level=3

// Regression test for various cases where we used to compile x86 vendor intrinsics in a suboptimal
// way.

#![crate_type = "lib"]

use std::arch::x86_64::*;

// CHECK-LABEL: test_packus_epi16:
#[unsafe(no_mangle)]
#[target_feature(enable = "sse2")]
extern "C" fn test_packus_epi16(a: __m128i, b: __m128i) -> __m128i {
// CHECK: .cfi_startproc
// CHECK-NEXT: packuswb
// CHECK-NEXT: ret
_mm_packus_epi16(a, b)
}
1 change: 1 addition & 0 deletions tests/debuginfo/associated-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl TraitWithAssocType for i32 {
fn get_value(&self) -> i64 { *self as i64 }
}

#[repr(C)]
struct Struct<T: TraitWithAssocType> {
b: T,
b1: T::Type,
Expand Down
2 changes: 2 additions & 0 deletions tests/debuginfo/boxed-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@

#![allow(unused_variables)]

#[repr(C)]
struct StructWithSomePadding {
x: i16,
y: i32,
z: i32,
w: i64
}

#[repr(C)]
struct StructWithDestructor {
x: i16,
y: i32,
Expand Down
6 changes: 5 additions & 1 deletion tests/debuginfo/c-style-enum-in-composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,21 @@
use self::AnEnum::{OneHundred, OneThousand, OneMillion};
use self::AnotherEnum::{MountainView, Toronto, Vienna};

#[repr(u32)]
enum AnEnum {
OneHundred = 100,
OneThousand = 1000,
OneMillion = 1000000
}

#[repr(u8)]
enum AnotherEnum {
MountainView,
Toronto,
Vienna
}

#[repr(C)]
struct PaddedStruct {
a: i16,
b: AnEnum,
Expand All @@ -77,7 +80,7 @@ struct PaddedStruct {
e: i16
}

#[repr(packed)]
#[repr(C, packed)]
struct PackedStruct {
a: i16,
b: AnEnum,
Expand All @@ -86,6 +89,7 @@ struct PackedStruct {
e: i16
}

#[repr(C)]
struct NonPaddedStruct {
a: AnEnum,
b: AnotherEnum,
Expand Down
3 changes: 3 additions & 0 deletions tests/debuginfo/destructured-for-loop-variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
// === LLDB TESTS ==================================================================================

//@ lldb-command:type format add --format hex char
// MSVC uses signed char
//@ lldb-command:type format add --format hex 'signed char'
//@ lldb-command:type format add --format hex 'unsigned char'

//@ lldb-command:run
Expand Down Expand Up @@ -144,6 +146,7 @@
#![allow(unused_variables)]
#![feature(deref_patterns)]

#[repr(C)]
struct Struct {
x: i16,
y: f32,
Expand Down
4 changes: 4 additions & 0 deletions tests/debuginfo/evec-in-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,20 @@

#![allow(unused_variables)]

#[repr(C)]
struct NoPadding1 {
x: [u32; 3],
y: i32,
z: [f32; 2]
}

#[repr(C)]
struct NoPadding2 {
x: [u32; 3],
y: [[u32; 2]; 2]
}

#[repr(C)]
struct StructInternalPadding {
x: [i16; 2],
y: [i64; 2]
Expand All @@ -61,6 +64,7 @@ struct SingleVec {
x: [i16; 5]
}

#[repr(C)]
struct StructPaddedAtEnd {
x: [i64; 2],
y: [i16; 2]
Expand Down
Loading
Loading