diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 54858b52008f9..343f27326ad60 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -43,7 +43,7 @@ pub trait LayoutCalculator { .max_by_key(|niche| niche.available(dl)); LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Arbitrary { offsets: vec![Size::ZERO, b_offset], memory_index: vec![0, 1], @@ -264,7 +264,7 @@ pub trait LayoutCalculator { abi = Abi::Uninhabited; } Some(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Arbitrary { offsets, memory_index }, abi, largest_niche, @@ -277,7 +277,7 @@ pub trait LayoutCalculator { let dl = self.current_data_layout(); let dl = dl.borrow(); LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Primitive, abi: Abi::Uninhabited, largest_niche: None, @@ -331,7 +331,7 @@ pub trait LayoutCalculator { } // If it's a struct, still compute a layout so that we can still compute the // field offsets. - None => VariantIdx::new(0), + None => FIRST_VARIANT, }; let is_struct = !is_enum || @@ -467,7 +467,7 @@ pub trait LayoutCalculator { .max_by_key(|(_i, layout)| layout.size.bytes()) .map(|(i, _layout)| i)?; - let all_indices = (0..=variants.len() - 1).map(VariantIdx::new); + let all_indices = variants.indices(); let needs_disc = |index: VariantIdx| index != largest_variant_index && !absent(&variants[index]); let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap().index() @@ -896,8 +896,8 @@ pub trait LayoutCalculator { let optimize = !repr.inhibit_union_abi_opt(); let mut size = Size::ZERO; let mut abi = Abi::Aggregate { sized: true }; - let index = VariantIdx::new(0); - for field in &variants[index] { + let only_variant = &variants[FIRST_VARIANT]; + for field in only_variant { assert!(field.0.is_sized()); align = align.max(field.align()); @@ -930,8 +930,8 @@ pub trait LayoutCalculator { } Some(LayoutS { - variants: Variants::Single { index }, - fields: FieldsShape::Union(NonZeroUsize::new(variants[index].len())?), + variants: Variants::Single { index: FIRST_VARIANT }, + fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?), abi, largest_niche: None, align, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 39574ca558f8b..6740001c38be1 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1380,8 +1380,21 @@ impl Niche { } rustc_index::newtype_index! { + /// The *source-order* index of a variant in a type. + /// + /// For enums, these are always `0..variant_count`, regardless of any + /// custom discriminants that may have been defined, and including any + /// variants that may end up uninhabited due to field types. (Some of the + /// variants may not be present in a monomorphized ABI [`Variants`], but + /// those skipped variants are always counted when determining the *index*.) + /// + /// `struct`s, `tuples`, and `unions`s are considered to have a single variant + /// with variant index zero, aka [`FIRST_VARIANT`]. #[derive(HashStable_Generic)] - pub struct VariantIdx {} + pub struct VariantIdx { + /// Equivalent to `VariantIdx(0)`. + const FIRST_VARIANT = 0; + } } #[derive(PartialEq, Eq, Hash, Clone)] @@ -1422,7 +1435,7 @@ impl LayoutS { let size = scalar.size(cx); let align = scalar.align(cx); LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Primitive, abi: Abi::Scalar(scalar), largest_niche, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c2a426bea0929..4b27d24098517 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -14,7 +14,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; @@ -36,7 +36,7 @@ use rustc_middle::ty::{ }; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -812,7 +812,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }, PlaceTy { ty, variant_index: None } => match *ty.kind() { ty::Adt(adt_def, substs) if !adt_def.is_enum() => { - (adt_def.variant(VariantIdx::new(0)), substs) + (adt_def.variant(FIRST_VARIANT), substs) } ty::Closure(_, substs) => { return match substs diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 2107ae147e980..1825fb8cb2288 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -785,7 +785,7 @@ fn codegen_stmt<'tcx>( let variant_dest = lval.downcast_variant(fx, variant_index); (variant_index, variant_dest, active_field_index) } - _ => (VariantIdx::from_u32(0), lval, None), + _ => (FIRST_VARIANT, lval, None), }; if active_field_index.is_some() { assert_eq!(operands.len(), 1); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index bed79859f51ff..1bd03403f244b 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeVisitableExt, UintTy, }; - pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; + pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx, FIRST_VARIANT}; pub(crate) use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index ecf187a0b0fe6..93eefd92342d8 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -146,7 +146,7 @@ pub(crate) fn coerce_unsized_into<'tcx>( (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); - for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() { + for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { let src_f = src.value_field(fx, mir::Field::new(i)); let dst_f = dst.place_field(fx, mir::Field::new(i)); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index c3c8649dbff47..6c4ca8f7fb12d 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -24,7 +24,6 @@ use rustc_data_structures::sync::ParallelIterator; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::Idx; use rustc_metadata::EncodedMetadata; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols; @@ -40,7 +39,7 @@ use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::Symbol; use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType}; -use rustc_target::abi::{Align, VariantIdx}; +use rustc_target::abi::{Align, FIRST_VARIANT}; use std::collections::BTreeSet; use std::time::{Duration, Instant}; @@ -307,7 +306,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); - for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() { + for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { let src_f = src.project_field(bx, i); let dst_f = dst.project_field(bx, i); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 14f57b63e9700..4bc4fdab59e19 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; -use rustc_target::abi::{self, VariantIdx}; +use rustc_target::abi::{self, FIRST_VARIANT}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "trace", skip(self, bx))] @@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let variant_dest = dest.project_downcast(bx, variant_index); (variant_index, variant_dest, active_field_index) } - _ => (VariantIdx::from_u32(0), dest, None), + _ => (FIRST_VARIANT, dest, None), }; if active_field_index.is_some() { assert_eq!(operands.len(), 1); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index a73f778d4db20..8e4454d7cec28 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -8,7 +8,7 @@ use crate::interpret::{ use crate::interpret::{MPlaceTy, Value}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; -use rustc_target::abi::{Align, VariantIdx}; +use rustc_target::abi::{Align, VariantIdx, FIRST_VARIANT}; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -412,7 +412,7 @@ fn valtree_into_mplace<'tcx>( let inner_ty = match ty.kind() { ty::Adt(def, substs) => { - def.variant(VariantIdx::from_u32(0)).fields[i].ty(tcx, substs) + def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs) } ty::Tuple(inner_tys) => inner_tys[i], _ => bug!("unexpected unsized type {:?}", ty), diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index ff6db143ddfd9..a95bcaa3f9988 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -8,7 +8,7 @@ use rustc_ast::Mutability; use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, VariantIdx}; +use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, FIRST_VARIANT}; use super::{ alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, @@ -796,7 +796,7 @@ where let variant_dest = self.place_downcast(&dest, variant_index)?; (variant_index, variant_dest, active_field_index) } - _ => (VariantIdx::from_u32(0), dest.clone(), None), + _ => (FIRST_VARIANT, dest.clone(), None), }; if active_field_index.is_some() { assert_eq!(operands.len(), 1); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 66fc1c07e2029..2be385d551e8a 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; -use rustc_target::abi::{Size, VariantIdx}; +use rustc_target::abi::{Size, FIRST_VARIANT}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { @@ -359,7 +359,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { check_equal(self, location, *f_ty); } ty::Adt(adt_def, substs) => { - let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); + let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { fail_out_of_bounds(self, location); return; diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index c62c1553d6f72..5ca4087cdd3c4 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -14,12 +14,11 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::PatKind; -use rustc_index::vec::Idx; use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use ty::BorrowKind::ImmBorrow; use crate::mem_categorization as mc; @@ -549,7 +548,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { &*with_expr, with_place.clone(), with_field.ty(self.tcx(), substs), - ProjectionKind::Field(f_index as u32, VariantIdx::new(0)), + ProjectionKind::Field(f_index as u32, FIRST_VARIANT), ); self.delegate_consume(&field_place, field_place.hir_id); } diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 95e5483abf3bd..19c4146de8995 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -59,10 +59,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::PatKind; -use rustc_index::vec::Idx; use rustc_infer::infer::InferCtxt; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_trait_selection::infer::InferCtxtExt; pub(crate) trait HirNode { @@ -331,7 +330,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { expr, base, expr_ty, - ProjectionKind::Field(field_idx as u32, VariantIdx::new(0)), + ProjectionKind::Field(field_idx as u32, FIRST_VARIANT), )) } @@ -561,7 +560,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { // Structs and Unions have only have one variant. - Ok(VariantIdx::new(0)) + Ok(FIRST_VARIANT) } _ => bug!("expected ADT path, found={:?}", res), } @@ -675,7 +674,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = ProjectionKind::Field(i as u32, VariantIdx::new(0)); + let projection_kind = ProjectionKind::Field(i as u32, FIRST_VARIANT); let sub_place = self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); self.cat_pattern_(sub_place, subpat, op)?; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index eadc30a799b2a..8fe5a3cc78911 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -49,8 +49,7 @@ use rustc_span::{BytePos, Pos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_index::vec::Idx; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use std::iter; @@ -1406,7 +1405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProjectionKind::Field(..) )) ); - def.variants().get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any( + def.variants().get(FIRST_VARIANT).unwrap().fields.iter().enumerate().any( |(i, field)| { let paths_using_field = captured_by_move_projs .iter() diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 64c3ef451374e..c1b247e3d615a 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -58,7 +58,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; use rustc_hir::intravisit::FnKind as HirFnKind; use rustc_hir::{Body, FnDecl, ForeignItemKind, GenericParamKind, Node, PatKind, PredicateOrigin}; -use rustc_index::vec::Idx; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -69,7 +68,7 @@ use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, Span}; -use rustc_target::abi::{Abi, VariantIdx}; +use rustc_target::abi::{Abi, FIRST_VARIANT}; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy}; @@ -2788,7 +2787,7 @@ impl ClashingExternDeclarations { ); if is_transparent && !is_non_null { debug_assert_eq!(def.variants().len(), 1); - let v = &def.variant(VariantIdx::new(0)); + let v = &def.variant(FIRST_VARIANT); // continue with `ty`'s non-ZST field, // otherwise `ty` is a ZST and we can return if let Some(field) = transparent_newtype_field(tcx, v) { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index ec21030b3024d..50d7fb1813a57 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -10,11 +10,11 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; -use rustc_target::abi::{ReprOptions, VariantIdx}; +use rustc_target::abi::{ReprOptions, VariantIdx, FIRST_VARIANT}; use std::cell::RefCell; use std::cmp::Ordering; @@ -228,7 +228,7 @@ impl AdtDefData { AdtKind::Struct => AdtFlags::IS_STRUCT, }; - if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor.is_some() { + if kind == AdtKind::Struct && variants[FIRST_VARIANT].ctor.is_some() { flags |= AdtFlags::HAS_CTOR; } @@ -357,7 +357,7 @@ impl<'tcx> AdtDef<'tcx> { /// Asserts this is a struct or union and returns its unique variant. pub fn non_enum_variant(self) -> &'tcx VariantDef { assert!(self.is_struct() || self.is_union()); - &self.variant(VariantIdx::new(0)) + &self.variant(FIRST_VARIANT) } #[inline] @@ -493,7 +493,7 @@ impl<'tcx> AdtDef<'tcx> { #[inline] pub fn variant_range(self) -> Range { - VariantIdx::new(0)..VariantIdx::new(self.variants().len()) + FIRST_VARIANT..self.variants().next_index() } /// Computes the discriminant value used by a specific variant. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e3cd5cca785aa..c6a56df5a5eee 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -653,8 +653,8 @@ pub enum AliasRelationDirection { impl std::fmt::Display for AliasRelationDirection { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AliasRelationDirection::Equate => write!(f, " == "), - AliasRelationDirection::Subtype => write!(f, " <: "), + AliasRelationDirection::Equate => write!(f, "=="), + AliasRelationDirection::Subtype => write!(f, "<:"), } } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 35a581d314cd4..d03cc324e518f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -22,7 +22,7 @@ use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi::{self, Abi}; use std::borrow::Cow; use std::cmp::Ordering; @@ -517,8 +517,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { #[inline] pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR - let num_variants = tcx.generator_layout(def_id).unwrap().variant_fields.len(); - VariantIdx::new(0)..VariantIdx::new(num_variants) + FIRST_VARIANT..tcx.generator_layout(def_id).unwrap().variant_fields.next_index() } /// The discriminant for the given variant. Panics if the `variant_index` is diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 33200b80a572d..e112bf9829b68 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -13,9 +13,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::AdtDef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; - -use rustc_index::vec::Idx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use std::assert_matches::assert_matches; use std::iter; @@ -91,7 +89,7 @@ fn convert_to_hir_projections_and_truncate_for_capture( let hir_projection = match mir_projection { ProjectionElem::Deref => HirProjectionKind::Deref, ProjectionElem::Field(field, _) => { - let variant = variant.unwrap_or(VariantIdx::new(0)); + let variant = variant.unwrap_or(FIRST_VARIANT); HirProjectionKind::Field(field.index() as u32, variant) } ProjectionElem::Downcast(.., idx) => { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 6fd9b9dbb5755..04e9273fc46c9 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; use rustc_span::{sym, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; impl<'tcx> Cx<'tcx> { pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId { @@ -357,7 +357,7 @@ impl<'tcx> Cx<'tcx> { Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => { Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))) } - Res::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))), + Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)), _ => None, }) } else { @@ -510,7 +510,7 @@ impl<'tcx> Cx<'tcx> { debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty); ExprKind::Adt(Box::new(AdtExpr { adt_def: *adt, - variant_index: VariantIdx::new(0), + variant_index: FIRST_VARIANT, substs, user_ty, fields: self.field_refs(fields), @@ -732,7 +732,7 @@ impl<'tcx> Cx<'tcx> { } hir::ExprKind::Field(ref source, ..) => ExprKind::Field { lhs: self.mirror_expr(source), - variant_index: VariantIdx::new(0), + variant_index: FIRST_VARIANT, name: Field::new(self.typeck_results.field_index(expr.hir_id)), }, hir::ExprKind::Cast(ref source, ref cast_ty) => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index e5b7d685c499b..8a7b1fce51db4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -60,7 +60,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue}; use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::{Integer, Size, VariantIdx}; +use rustc_target::abi::{Integer, Size, VariantIdx, FIRST_VARIANT}; use self::Constructor::*; use self::SliceKind::*; @@ -706,7 +706,7 @@ impl<'tcx> Constructor<'tcx> { Variant(idx) => idx, Single => { assert!(!adt.is_enum()); - VariantIdx::new(0) + FIRST_VARIANT } _ => bug!("bad constructor {:?} for adt {:?}", self, adt), } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 486275570bd11..fe6728fc76e4c 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -7,7 +7,7 @@ use rustc_middle::traits::Reveal; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use std::{fmt, iter}; /// The value of an inserted drop flag. @@ -468,7 +468,7 @@ where let fields = self.move_paths_for_fields( self.place, self.path, - &adt.variant(VariantIdx::new(0)), + &adt.variant(FIRST_VARIANT), substs, ); self.drop_ladder(fields, succ, unwind) @@ -894,7 +894,7 @@ where let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); let free_func = tcx.require_lang_item(LangItem::BoxFree, Some(self.source_info.span)); let args = adt - .variant(VariantIdx::new(0)) + .variant(FIRST_VARIANT) .fields .iter() .enumerate() diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 27fad8a655ed5..4e7f68437e77b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use rustc_target::spec::abi::Abi; use crate::simplify::{remove_dead_blocks, CfgSimplifier}; @@ -904,7 +904,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { check_equal(self, *f_ty); } ty::Adt(adt_def, substs) => { - let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); + let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { self.validation = Err("malformed MIR"); return; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index ebe63d6cb7e33..970a0a8d4bf50 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_index::vec::{Idx, IndexVec}; @@ -816,11 +816,8 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let source_info = SourceInfo::outermost(span); - let variant_index = if adt_def.is_enum() { - adt_def.variant_index_with_ctor_id(ctor_id) - } else { - VariantIdx::new(0) - }; + let variant_index = + if adt_def.is_enum() { adt_def.variant_index_with_ctor_id(ctor_id) } else { FIRST_VARIANT }; // Generate the following MIR: // diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 525b3105538d0..14c5b83c6ca72 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -174,7 +174,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal.predicate.def_id(), impl_def_id )? else { - return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); + return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); }; if !assoc_def.item.defaultness(tcx).has_value() { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 4d0fd260de2fe..b67607a4db63e 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::abstract_const::CastKind; use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitableExt}; use rustc_middle::{mir, thir}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use std::iter; @@ -44,7 +44,7 @@ pub(crate) fn destructure_const<'tcx>( let (head, rest) = branches.split_first().unwrap(); (VariantIdx::from_u32(head.unwrap_leaf().try_to_u32().unwrap()), rest) } else { - (VariantIdx::from_u32(0), branches) + (FIRST_VARIANT, branches) }; let fields = &def.variant(variant_idx).fields; let mut field_consts = Vec::with_capacity(fields.len()); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1788f544a7f9a..380931742e389 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,7 +1,7 @@ use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal}; use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, @@ -227,7 +227,7 @@ fn layout_of_uncached<'tcx>( let largest_niche = if count != 0 { element.largest_niche } else { None }; tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count }, abi, largest_niche, @@ -238,7 +238,7 @@ fn layout_of_uncached<'tcx>( ty::Slice(element) => { let element = cx.layout_of(element)?; tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count: 0 }, abi: Abi::Aggregate { sized: false }, largest_niche: None, @@ -247,7 +247,7 @@ fn layout_of_uncached<'tcx>( }) } ty::Str => tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, abi: Abi::Aggregate { sized: false }, largest_niche: None, @@ -399,7 +399,7 @@ fn layout_of_uncached<'tcx>( }; tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields, abi: Abi::Vector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index ee13dae60b198..a205565773a71 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -228,7 +228,7 @@ pub fn spin_loop() { /// This _immediately_ precludes any direct use of this function for cryptographic or security /// purposes. /// -/// While not suitable in those mission-critical cases, `back_box`'s functionality can generally be +/// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be /// relied upon for benchmarking, and should be used there. It will try to ensure that the /// compiler doesn't optimize away part of the intended test code based on context. For /// example: diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md index e1e09aa4a8ada..cf1e6a8d3ca49 100644 --- a/src/doc/rustdoc/src/write-documentation/what-to-include.md +++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md @@ -39,7 +39,7 @@ warning: 1 warning emitted As a library author, adding the lint `#![deny(missing_docs)]` is a great way to ensure the project does not drift away from being documented well, and `#![warn(missing_docs)]` is a good way to move towards comprehensive -documentation. In addition to docs, `#![deny(missing_doc_code_examples)]` +documentation. In addition to docs, `#![deny(rustdoc::missing_doc_code_examples)]` ensures each function contains a usage example. In our example above, the warning is resolved by adding crate level documentation. diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 579b5a9c7231b..674cd0d62d49a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1234,7 +1234,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w.write_str(",\n"); } - if variants_stripped { + if variants_stripped && !it.is_non_exhaustive() { w.write_str(" // some variants omitted\n"); } if toggle { diff --git a/tests/rustdoc-gui/auto-hide-trait-implementations.goml b/tests/rustdoc-gui/auto-hide-trait-implementations.goml deleted file mode 100644 index 0a619c3524a66..0000000000000 --- a/tests/rustdoc-gui/auto-hide-trait-implementations.goml +++ /dev/null @@ -1,13 +0,0 @@ -// Checks that the setting "auto hide trait implementations" is working as expected. -goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" - -// By default, the trait implementations are not collapsed. -assert-attribute: ("#trait-implementations-list > details", {"open": ""}, ALL) - -// We now set the setting to auto hide all trait implementations. -local-storage: {"rustdoc-auto-hide-trait-implementations": "true" } -// We reload to ensure the trait implementations are collapsed as expected. -reload: - -// We now check that all matching elements don't have the open attributes. -assert-attribute-false: ("#trait-implementations-list > details", {"open": ""}, ALL) diff --git a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml new file mode 100644 index 0000000000000..7355dddd39d41 --- /dev/null +++ b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml @@ -0,0 +1,47 @@ +// Checks that the setting "auto hide trait implementations" is working as expected. + +define-function: ( + "check-setting", + (storage_value, setting_attribute_value, toggle_attribute_value), + block { + assert-local-storage: {"rustdoc-auto-hide-trait-implementations": |storage_value|} + click: "#settings-menu" + wait-for: "#settings" + assert-property: ("#auto-hide-trait-implementations", {"checked": |setting_attribute_value|}) + assert-attribute: ("#trait-implementations-list > details", {"open": |toggle_attribute_value|}, ALL) + } +) + +goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" + +// By default, the trait implementations are not collapsed. +call-function: ("check-setting", { + "storage_value": null, + "setting_attribute_value": "false", + "toggle_attribute_value": "", +}) + +// Now we change its value. +click: "#auto-hide-trait-implementations" +assert-local-storage: {"rustdoc-auto-hide-trait-implementations": "true"} + +// We check that the changes were applied as expected. +reload: + +call-function: ("check-setting", { + "storage_value": "true", + "setting_attribute_value": "true", + "toggle_attribute_value": null, +}) + +// And now we re-disable the setting. +click: "#auto-hide-trait-implementations" +assert-local-storage: {"rustdoc-auto-hide-trait-implementations": "false"} + +// And we check everything is back the way it was before. +reload: +call-function: ("check-setting", { + "storage_value": "false", + "setting_attribute_value": "false", + "toggle_attribute_value": "", +}) diff --git a/tests/rustdoc/issue-108925.rs b/tests/rustdoc/issue-108925.rs new file mode 100644 index 0000000000000..88aeb3c7f754d --- /dev/null +++ b/tests/rustdoc/issue-108925.rs @@ -0,0 +1,11 @@ +// @has issue_108925/enum.MyThing.html +// @has - '//code' 'Shown' +// @!has - '//code' 'NotShown' +// @!has - '//code' '// some variants omitted' +#[non_exhaustive] +pub enum MyThing { + Shown, + #[doc(hidden)] + NotShown, +} + diff --git a/tests/ui/traits/new-solver/specialization-transmute.rs b/tests/ui/traits/new-solver/specialization-transmute.rs new file mode 100644 index 0000000000000..a54701df4ef7e --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-transmute.rs @@ -0,0 +1,30 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +trait Default { + type Id; + + fn intu(&self) -> &Self::Id; +} + +impl Default for T { + default type Id = T; + + fn intu(&self) -> &Self::Id { + self + //~^ ERROR cannot satisfy `T <: ::Id` + } +} + +fn transmute, U: Copy>(t: T) -> U { + *t.intu() +} + +use std::num::NonZeroU8; +fn main() { + let s = transmute::>(0); + //~^ ERROR cannot satisfy `::Id == Option + assert_eq!(s, None); +} diff --git a/tests/ui/traits/new-solver/specialization-transmute.stderr b/tests/ui/traits/new-solver/specialization-transmute.stderr new file mode 100644 index 0000000000000..e67c56afc0d0c --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-transmute.stderr @@ -0,0 +1,31 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-transmute.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0284]: type annotations needed: cannot satisfy `T <: ::Id` + --> $DIR/specialization-transmute.rs:16:9 + | +LL | self + | ^^^^ cannot satisfy `T <: ::Id` + +error[E0284]: type annotations needed: cannot satisfy `::Id == Option` + --> $DIR/specialization-transmute.rs:27:13 + | +LL | let s = transmute::>(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Id == Option` + | +note: required by a bound in `transmute` + --> $DIR/specialization-transmute.rs:21:25 + | +LL | fn transmute, U: Copy>(t: T) -> U { + | ^^^^^^ required by this bound in `transmute` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.rs b/tests/ui/traits/new-solver/specialization-unconstrained.rs new file mode 100644 index 0000000000000..02150689ee5c3 --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-unconstrained.rs @@ -0,0 +1,22 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +// Do not treat the RHS of a projection-goal as an unconstrained `Certainty::Yes` response +// if the impl is still further specializable. + +trait Default { + type Id; +} + +impl Default for T { + default type Id = T; +} + +fn test, U>() {} + +fn main() { + test::(); + //~^ ERROR cannot satisfy `::Id == ()` +} diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/new-solver/specialization-unconstrained.stderr new file mode 100644 index 0000000000000..910925cbaeb0d --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-unconstrained.stderr @@ -0,0 +1,25 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-unconstrained.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0284]: type annotations needed: cannot satisfy `::Id == ()` + --> $DIR/specialization-unconstrained.rs:20:5 + | +LL | test::(); + | ^^^^^^^^^^^^^^^ cannot satisfy `::Id == ()` + | +note: required by a bound in `test` + --> $DIR/specialization-unconstrained.rs:17:20 + | +LL | fn test, U>() {} + | ^^^^^^ required by this bound in `test` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0284`.