diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 303607a47a528..152b396ce99ab 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1915,7 +1915,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { )); return; } - ty::Adt(adt, _) => { + ty::Adt(adt, _) | ty::View(adt, _, _) | ty::ViewInfer(adt, _, _) => { if !adt.is_box() { bug!("Adt should be a box type when Place is deref"); } @@ -1950,7 +1950,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { } }, ProjectionElem::Field(_, _) => match place_ty.ty.kind() { - ty::Adt(adt, _) => { + ty::Adt(adt, _) | ty::View(adt, _, _) | ty::ViewInfer(adt, _, _) => { if adt.has_dtor(tcx) { self.move_errors.push(MoveError::new( place, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 6e64fa7d04a93..10724db459c63 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -473,7 +473,7 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( // Some `Box` are newtyped pointers, make debuginfo aware of that. // Only works if the allocator argument is a 1-ZST and hence irrelevant for layout // (or if there is no allocator argument). - ty::Adt(def, args) + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) if def.is_box() && args.get(1).is_none_or(|arg| cx.layout_of(arg.expect_ty()).is_1zst()) => { @@ -483,7 +483,7 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id), ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id), ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id), - ty::Adt(def, ..) => match def.adt_kind() { + ty::Adt(def, ..) | ty::View(def, ..) | ty::ViewInfer(def, ..) => match def.adt_kind() { AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id, span), AdtKind::Union => build_union_type_di_node(cx, unique_type_id, span), AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span), diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 5ece363fcd8d9..b555b85043728 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -80,7 +80,7 @@ fn push_debuginfo_type_name<'tcx>( ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()), ty::Float(float_ty) => output.push_str(float_ty.name_str()), ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output), - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { // `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding. let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() { match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)) { diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 8f58e39d419ce..76034862ebb9b 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -102,7 +102,9 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } - ty::Adt(adt_def, generics) => { + ty::Adt(adt_def, generics) + | ty::View(adt_def, generics, _) + | ty::ViewInfer(adt_def, generics, _) => { self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)? } ty::Bool => { diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 7295df0ab2210..5cd5341f910b4 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -171,7 +171,7 @@ fn const_to_valtree_inner<'tcx>( branches(ecx, place, elem_tys.len(), None, num_nodes, visited, settled) } - ty::Adt(def, _) => { + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => { if def.is_union() { Err(ValTreeCreationError::NonSupportedType(ty)) } else if def.variants().is_empty() { @@ -326,7 +326,7 @@ pub fn valtree_to_const_value<'tcx>( ); op_to_const(&ecx, &imm.into(), /* for diagnostics */ false) } - ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => { + ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) | ty::View(..) | ty::ViewInfer(..) => { let layout = tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap(); if layout.is_zst() { // Fast path to avoid some allocations. diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 8001725c438b8..513ab9a5640fe 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -252,7 +252,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; let val = match ty.kind() { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - ty::Adt(adt, _) => { + ty::Adt(adt, _) | ty::View(adt, _, _) | ty::ViewInfer(adt, _, _) => { ConstValue::from_target_usize(adt.variants().len() as u64, &tcx) } ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => { diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index d291f1f6fdcbc..25e1d4faa4d87 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -527,7 +527,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ty::Pat(ty, ..) => is_very_trivially_sized(*ty), // We don't want to do any queries, so there is not much we can do with ADTs. - ty::Adt(..) => false, + ty::Adt(..) | ty::View(..) | ty::ViewInfer(..) => false, ty::UnsafeBinder(ty) => is_very_trivially_sized(ty.skip_binder()), diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 75a6753fe3d0e..fcd82e9a11da5 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -959,7 +959,9 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { | ty::Closure(..) | ty::Pat(..) | ty::CoroutineClosure(..) - | ty::Coroutine(..) => interp_ok(false), + | ty::Coroutine(..) + | ty::View(..) + | ty::ViewInfer(..) => interp_ok(false), // Some types only occur during typechecking, they have no layout. // We should not see them here and we could not check them anyway. ty::Error(_) diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index b46bd86f0497a..7c4e158178f0c 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -60,7 +60,13 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> { ) | ty::Closure(def_id, args) | ty::CoroutineClosure(def_id, args) - | ty::Coroutine(def_id, args) => self.print_def_path(def_id, args), + | ty::Coroutine(def_id, args) + | ty::View(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args, _) + | ty::ViewInfer( + ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), + args, + _, + ) => self.print_def_path(def_id, args), ty::Foreign(def_id) => self.print_def_path(def_id, &[]), ty::FnDef(def_id, args) => self.print_def_path(def_id, args.no_bound_vars().unwrap()), diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 4e3aa41942845..657c07a43cc89 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -180,7 +180,9 @@ impl<'tcx> InherentCollect<'tcx> { self_ty = base; } match *self_ty.kind() { - ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => { + self.check_def_id(id, self_ty, def.did()) + } ty::Foreign(did) => self.check_def_id(id, self_ty, did), ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { self.check_def_id(id, self_ty, data.principal_def_id().unwrap()) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 1cf5da0522c2c..15af204bd9841 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -163,7 +163,7 @@ pub(crate) fn orphan_check_impl( let (local_impl, nonlocal_impl) = match self_ty.kind() { // struct Struct; // impl AutoTrait for Struct {} - ty::Adt(self_def, _) => ( + ty::Adt(self_def, _) | ty::View(self_def, _, _) | ty::ViewInfer(self_def, _, _) => ( LocalImpl::Allow, if self_def.did().is_local() { NonlocalImpl::Allow diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 497ff02c9b407..eaa1cf2f076bc 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -3453,7 +3453,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let dcx = self.dcx(); let tcx = self.tcx(); match ty.kind() { - ty::Adt(def, _) => { + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => { let base_did = def.did(); let kind_name = tcx.def_descr(base_did); let (variant_idx, variant) = if def.is_enum() { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index a2e3883b0684e..6843861cd6a03 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -256,7 +256,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } } - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { self.add_constraints_from_args(current, def.did(), args, variance); } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 4cbeaa6278049..a829ed76fb7ba 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -106,13 +106,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(match *t.kind() { ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Dynamic(tty, _) => Some(PointerKind::VTable(tty)), - ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() { - None => Some(PointerKind::Thin), - Some(f) => { - let field_ty = self.field_ty(span, f, args); - self.pointer_kind(field_ty, span)? + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) + if def.is_struct() => + { + match def.non_enum_variant().tail_opt() { + None => Some(PointerKind::Thin), + Some(f) => { + let field_ty = self.field_ty(span, f, args); + self.pointer_kind(field_ty, span)? + } } - }, + } ty::Tuple(fields) => match fields.last() { None => Some(PointerKind::Thin), Some(&f) => self.pointer_kind(f, span)?, @@ -144,6 +148,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::Adt(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::Never | ty::Error(_) => { let guar = self diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index dfb4647b5e6e2..bb9c58ba6b0c0 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -904,7 +904,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.assemble_inherent_impl_candidates_for_type(p.def_id(), receiver_steps); self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps); } - ty::Adt(def, _) => { + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => { let def_id = def.did(); self.assemble_inherent_impl_candidates_for_type(def_id, receiver_steps); self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps); diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index d3bca32b9976c..eb24047691eb6 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -420,7 +420,9 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { | ty::Alias(..) | ty::Foreign(..) | ty::Pat(..) - | ty::Param(..) => { + | ty::Param(..) + | ty::View(..) + | ty::ViewInfer(..) => { if t.flags().intersects(self.needs_canonical_flags) { t.super_fold_with(self) } else { diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 0c34d9da66f1d..20c6378cd6b47 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -751,7 +751,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } match *ty.kind() { - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { if let Some(inner_ty) = ty.boxed_ty() { return self.visit_indirection(state, ty, inner_ty, IndirectionKind::Box); } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 841efe4793b8e..86947840e1eae 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -402,7 +402,9 @@ impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) { /// deeply nested tuples that have no DefId. fn def_id_of_type_cached<'a>(ty: Ty<'a>, visited: &mut SsoHashSet>) -> Option { match *ty.kind() { - ty::Adt(adt_def, _) => Some(adt_def.did()), + ty::Adt(adt_def, _) | ty::View(adt_def, _, _) | ty::ViewInfer(adt_def, _, _) => { + Some(adt_def.did()) + } ty::Dynamic(data, ..) => data.principal_def_id(), diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 5f76467ed7db2..980a950a09885 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -486,6 +486,7 @@ impl_decodable_via_ref! { &'tcx ty::List>, &'tcx ty::ListWithCachedTypeInfo>, &'tcx ty::List>, + &'tcx ty::List, } #[macro_export] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4ae165cb015bd..db69901948403 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1836,7 +1836,9 @@ impl<'tcx> TyCtxt<'tcx> { Infer, Alias, Pat, - Foreign + Foreign, + View, + ViewInfer )?; writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?; diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 26bed229f4d5a..16863b3b42781 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -3,6 +3,7 @@ use std::ops::ControlFlow; use std::{debug_assert_matches, fmt}; +use rustc_abi::FieldIdx; use rustc_data_structures::Limit; use rustc_data_structures::intern::Interned; use rustc_errors::ErrorGuaranteed; @@ -111,6 +112,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Pat = Pattern<'tcx>; type PatList = &'tcx List>; type Safety = hir::Safety; + type FieldSet = &'tcx List; + type Field = FieldIdx; type Const = ty::Const<'tcx>; type Consts = &'tcx List; @@ -592,6 +595,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { | ty::Coroutine(_, _) | ty::Never | ty::Tuple(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::UnsafeBinder(_) => { if let Some(simp) = ty::fast_reject::simplify_type( tcx, diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index a16352e45564e..f93e67a4931b9 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -195,7 +195,8 @@ impl<'tcx> Ty<'tcx> { | ty::Str | ty::Never => "type".into(), ty::Tuple(tys) if tys.is_empty() => "unit type".into(), - ty::Adt(def, _) => def.descr().into(), + // FIXME(view_types): we can probably do better than that. + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => def.descr().into(), ty::Foreign(_) => "extern type".into(), ty::Array(..) => "array".into(), ty::Pat(..) => "pattern type".into(), diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 42485a17f1011..621232421b491 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -311,7 +311,7 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> { let base = tcx.instantiate_bound_regions_with_erased((*base).into()); self.is_inhabited_ty(base) } - ty::Adt(..) => self.is_inhabited_adt_ty(ty), + ty::Adt(..) | ty::View(..) | ty::ViewInfer(..) => self.is_inhabited_adt_ty(ty), ty::Error(_error_guaranteed) => { // We have a token proving there was an error, so we can return a dummy value. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 3fb35d48513ad..1a26b1353edf9 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -988,7 +988,7 @@ where ty::Tuple(tys) => TyMaybeWithLayout::Ty(tys[i]), // ADTs. - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { match this.variants { Variants::Single { index } => { let field = &def.variant(index).fields[FieldIdx::from_usize(i)]; diff --git a/compiler/rustc_middle/src/ty/offload_meta.rs b/compiler/rustc_middle/src/ty/offload_meta.rs index a58e517e05f61..59e713fc35a7b 100644 --- a/compiler/rustc_middle/src/ty/offload_meta.rs +++ b/compiler/rustc_middle/src/ty/offload_meta.rs @@ -120,9 +120,13 @@ impl MappingFlags { } // FIXME: This should not treat aliases this way. - ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Alias(_, _) | ty::Param(_) => { - MappingFlags::TO - } + ty::Adt(_, _) + | ty::Tuple(_) + | ty::Array(_, _) + | ty::Alias(_, _) + | ty::Param(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) => MappingFlags::TO, ty::RawPtr(_, Not) | ty::Ref(_, _, Not) => MappingFlags::TO, diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index ccdac57cc8dcd..1dc439cc5ae3b 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -303,7 +303,9 @@ fn characteristic_def_id_of_type_cached<'a>( visited: &mut SsoHashSet>, ) -> Option { match *ty.kind() { - ty::Adt(adt_def, _) => Some(adt_def.did()), + ty::Adt(adt_def, _) | ty::View(adt_def, _, _) | ty::ViewInfer(adt_def, _, _) => { + Some(adt_def.did()) + } ty::Dynamic(data, ..) => data.principal_def_id(), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3614a67b71045..11693568deb5d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3,7 +3,7 @@ use std::fmt::{self, Write as _}; use std::iter; use std::ops::{Deref, DerefMut}; -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::{ExternAbi, FIRST_VARIANT, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_data_structures::Limit; @@ -760,6 +760,30 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty.print(self)?; write!(self, ") is {pat:?}")?; } + ty::View(adt_def, args, fields) => { + self.print_def_path(adt_def.did(), args)?; + write!(self, ".{{")?; + if !fields.is_empty() { + write!(self, " ")?; + let struct_fields = &adt_def.variant(FIRST_VARIANT).fields; + let mut first = true; + for field in fields { + if !first { + write!(self, ", ")?; + } else { + first = false; + } + let ident = struct_fields[field].ident(self.tcx()); + write!(self, "{ident}")?; + } + write!(self, " ")?; + } + write!(self, "}}")?; + } + ty::ViewInfer(adt_def, args, fields) => { + self.print_def_path(adt_def.did(), args)?; + write!(self, ".{{ {fields:?} }}")?; + } ty::RawPtr(ty, mutbl) => { write!(self, "*{} ", mutbl.ptr_str())?; ty.print(self)?; diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs index c5b50163fbbb1..0f9055265ce58 100644 --- a/compiler/rustc_middle/src/ty/significant_drop_order.rs +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -142,7 +142,7 @@ pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { | ty::Array(_, _) | ty::UnsafeBinder(_) => None, - ty::Adt(adt_def, _) => { + ty::Adt(adt_def, _) | ty::View(adt_def, _, _) | ty::ViewInfer(adt_def, _, _) => { if let Some(dtor) = tcx.adt_destructor(adt_def.did()) { Some(tcx.def_span(tcx.parent(dtor.did))) } else { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 68de7805a52e6..cfcb83e199ce8 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -355,6 +355,10 @@ impl<'tcx> TypeSuperFoldable> for Ty<'tcx> { ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?), ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?), ty::Adt(tid, args) => ty::Adt(tid, args.try_fold_with(folder)?), + ty::View(tid, args, fields) => ty::View(tid, args.try_fold_with(folder)?, fields), + ty::ViewInfer(tid, args, fields) => { + ty::ViewInfer(tid, args.try_fold_with(folder)?, fields) + } ty::Dynamic(trait_ty, region) => { ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?) } @@ -400,6 +404,8 @@ impl<'tcx> TypeSuperFoldable> for Ty<'tcx> { ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)), ty::Slice(typ) => ty::Slice(typ.fold_with(folder)), ty::Adt(tid, args) => ty::Adt(tid, args.fold_with(folder)), + ty::View(tid, args, fields) => ty::View(tid, args.fold_with(folder), fields), + ty::ViewInfer(tid, args, fields) => ty::ViewInfer(tid, args.fold_with(folder), fields), ty::Dynamic(trait_ty, region) => { ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)) } @@ -444,6 +450,8 @@ impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { } ty::Slice(typ) => typ.visit_with(visitor), ty::Adt(_, args) => args.visit_with(visitor), + ty::View(_, args, _) => args.visit_with(visitor), + ty::ViewInfer(_, args, _) => args.visit_with(visitor), ty::Dynamic(trait_ty, reg) => { try_visit!(trait_ty.visit_with(visitor)); reg.visit_with(visitor) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ff787c0ede7f7..8cbda9a6fe361 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1716,6 +1716,7 @@ impl<'tcx> Ty<'tcx> { /// Returns the type of the discriminant of this type. pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self.kind() { + // It is somewhat guaranteed that view types ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx), ty::Coroutine(_, args) => args.as_coroutine().discr_ty(tcx), @@ -1756,6 +1757,8 @@ impl<'tcx> Ty<'tcx> { | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8, @@ -1798,7 +1801,8 @@ impl<'tcx> Ty<'tcx> { ty::Foreign(..) => Ok(tcx.types.unit), // If returned by `struct_tail_raw` this is a unit struct // without any fields, or not a struct, and therefore is Sized. - ty::Adt(..) => Ok(tcx.types.unit), + // FIXME(scrabsha): try to update comment above. + ty::Adt(..) | ty::View(..) | ty::ViewInfer(..) => Ok(tcx.types.unit), // If returned by `struct_tail_raw` this is the empty tuple, // a.k.a. unit type, which is Sized ty::Tuple(..) => Ok(tcx.types.unit), @@ -1998,9 +2002,11 @@ impl<'tcx> Ty<'tcx> { ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness)), - ty::Adt(def, args) => def.sizedness_constraint(tcx, sizedness).is_none_or(|ty| { - ty.instantiate(tcx, args).skip_norm_wip().has_trivial_sizedness(tcx, sizedness) - }), + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { + def.sizedness_constraint(tcx, sizedness).is_none_or(|ty| { + ty.instantiate(tcx, args).skip_norm_wip().has_trivial_sizedness(tcx, sizedness) + }) + } ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, @@ -2058,7 +2064,11 @@ impl<'tcx> Ty<'tcx> { ty::Coroutine(..) | ty::CoroutineWitness(..) => false, // Might be, but not "trivial" so just giving the safe answer. - ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) => false, + ty::Adt(..) + | ty::View(..) + | ty::ViewInfer(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) => false, ty::UnsafeBinder(_) => false, @@ -2113,6 +2123,8 @@ impl<'tcx> Ty<'tcx> { | ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Alias(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::Error(_) => false, } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 8e84ee6ab03e1..1d5fdb87da7ef 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1215,6 +1215,8 @@ impl<'tcx> Ty<'tcx> { | ty::Infer(_) | ty::Alias(..) | ty::Param(_) + | ty::View(..) + | ty::ViewInfer(..) | ty::Placeholder(_) => false, } } @@ -1265,6 +1267,8 @@ impl<'tcx> Ty<'tcx> { | ty::Infer(_) | ty::Alias(..) | ty::Param(_) + | ty::View(..) + | ty::ViewInfer(..) | ty::Placeholder(_) => false, } } @@ -1319,6 +1323,8 @@ impl<'tcx> Ty<'tcx> { | ty::Infer(_) | ty::Alias(..) | ty::Param(_) + | ty::View(..) + | ty::ViewInfer(..) | ty::Placeholder(_) => false, } } @@ -1456,6 +1462,11 @@ impl<'tcx> Ty<'tcx> { // Look for an impl of `StructuralPartialEq`. ty::Adt(..) => tcx.has_structural_eq_impl(self), + // FIXME(scrabsha): ????? + // Like, `false` is probably the wrong thing to do, but also: what is the right thing + // to do? + ty::View(..) | ty::ViewInfer(..) => false, + // Primitive types that satisfy `Eq`. ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Str | ty::Never => true, @@ -1593,6 +1604,8 @@ pub fn needs_drop_components_with_async<'tcx>( | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::UnsafeBinder(_) => Ok(smallvec![ty]), } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 74aaa19bf2373..2519541e11fb2 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -169,13 +169,15 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | ty::Param(_) | ty::Bound(_, _) | ty::Infer(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) | ty::Placeholder(_) => { bug!("When Place is Deref it's type shouldn't be {place_ty:#?}") } }, MoveSubPath::Field(_) => match place_ty.kind() { - ty::Adt(adt, _) => { + ty::Adt(adt, _) | ty::View(adt, _, _) | ty::ViewInfer(adt, _, _) => { if adt.has_dtor(tcx) { return; } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 98153da199d19..8e2db2a747f8e 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -874,7 +874,7 @@ fn try_write_constant<'tcx>( } } - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _)| ty::ViewInfer(def, args, _) => { if def.is_union() { throw_machine_stop_str!("cannot propagate unions") } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index f00dd3fde5aac..40dd3c8c8cd29 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1719,7 +1719,9 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => { ty_may_have_ref_inner(tcx, *ty, depth) } - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) + | ty::View(adt_def, args, _) + | ty::ViewInfer(adt_def, args, _) => { adt_def.has_param() || adt_def.has_aliases() || adt_def.all_fields().any(|field| { diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 0ff7248ff4246..198e032f0d89a 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -393,6 +393,8 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { | ty::Tuple(_) | ty::Alias(_, _) | ty::Bound(_, _) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) => { return ensure_sufficient_stack(|| t.super_fold_with(self)); } diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index 22fe960f0790d..c686b15b579e1 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -408,7 +408,9 @@ where // For fundamental types, we just look inside of them. ty::Ref(_, ty, _) => ty.visit_with(self), - ty::Adt(def, args) => { + ty::Adt(def, args) + | ty::View(def, args, _) + | ty::ViewInfer(def, args, _) => { if self.def_id_is_local(def.def_id()) { ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) } else if def.is_fundamental() { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 040f98de7bcfd..29d02670682c1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -781,6 +781,8 @@ where | ty::Param(_) | ty::Placeholder(..) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) => return Ok(()), ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => { panic!("unexpected self type for `{goal:?}`") @@ -925,6 +927,8 @@ where | ty::Param(_) | ty::Placeholder(..) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) => return, ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => panic!("unexpected self type for `{goal:?}`"), diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 406e5a172c96d..bb77201b7675e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -98,12 +98,14 @@ where // For `PhantomData`, we pass `T`. ty::Adt(def, args) if def.is_phantom_data() => Ok(ty::Binder::dummy(vec![args.type_at(0)])), - ty::Adt(def, args) => Ok(ty::Binder::dummy( - def.all_field_tys(cx) - .iter_instantiated(cx, args) - .map(Unnormalized::skip_norm_wip) - .collect(), - )), + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { + Ok(ty::Binder::dummy( + def.all_field_tys(cx) + .iter_instantiated(cx, args) + .map(Unnormalized::skip_norm_wip) + .collect(), + )) + } ty::Alias(ty::IsRigid::Yes, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => { // We can resolve the `impl Trait` to its concrete type, @@ -185,7 +187,7 @@ where // In this case, the builtin impl will have no nested subgoals. This is a // "best effort" optimization and `{meta,pointee,}sized_constraint` may return `Some`, // even if the ADT is {meta,pointee,}sized for all possible args. - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { if let Some(crit) = def.sizedness_constraint(ecx.cx(), sizedness) { Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args).skip_norm_wip()])) } else { @@ -232,6 +234,8 @@ where | ty::Adt(_, _) | ty::Alias(ty::IsRigid::Yes, _) | ty::Param(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Placeholder(..) => Err(NoSolution), // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone @@ -409,6 +413,8 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable Err(NoSolution), ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) @@ -585,6 +591,8 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable Err(NoSolution), ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) @@ -755,6 +763,8 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable( | ty::Param(_) | ty::Placeholder(..) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) | ty::UnsafeBinder(_) => return Err(NoSolution), @@ -766,6 +776,7 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable( } } +// FIXME(scrabsha): comment below. // NOTE: Keep this in sync with `evaluate_host_effect_for_destruct_goal` in // the old solver, for as long as that exists. pub(in crate::solve) fn const_conditions_for_destruct( @@ -780,7 +791,7 @@ pub(in crate::solve) fn const_conditions_for_destruct( // An ADT is `[const] Destruct` only if all of the fields are, // *and* if there is a `Drop` impl, that `Drop` impl is also `[const]`. - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) | ty::View(adt_def, args, _) | ty::ViewInfer(adt_def, args, _) => { let mut const_conditions: Vec<_> = adt_def .all_field_tys(cx) .iter_instantiated(cx, args) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 069102f3db50b..bd93486f0b231 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -764,16 +764,20 @@ where }); } - ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { - None => Ty::new_unit(cx), - Some(tail_ty) => Ty::new_projection( - cx, - ty::IsRigid::No, - metadata_def_id, - [tail_ty.instantiate(cx, args).skip_norm_wip()], - ), - }, - ty::Adt(_, _) => Ty::new_unit(cx), + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) + if def.is_struct() => + { + match def.struct_tail_ty(cx) { + None => Ty::new_unit(cx), + Some(tail_ty) => Ty::new_projection( + cx, + ty::IsRigid::No, + metadata_def_id, + [tail_ty.instantiate(cx, args).skip_norm_wip()], + ), + } + } + ty::Adt(_, _) | ty::View(_, _, _) | ty::ViewInfer(_, _, _) => Ty::new_unit(cx), ty::Tuple(elements) => match elements.last() { None => Ty::new_unit(cx), @@ -1002,6 +1006,8 @@ where | ty::Slice(_) | ty::Dynamic(_, _) | ty::Tuple(_) + | ty::View(..) + | ty::ViewInfer(..) | ty::Error(_) => self_ty.discriminant_ty(ecx.cx()), ty::UnsafeBinder(_) => { diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f29df578cd97b..97554af650dd6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -735,7 +735,8 @@ where // `&mut T` and `&T` always implement `BikeshedGuaranteedNoDrop`. ty::Ref(..) => {} // `ManuallyDrop` always implements `BikeshedGuaranteedNoDrop`. - ty::Adt(def, _) if def.is_manually_drop() => {} + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) + if def.is_manually_drop() => {} // Arrays and tuples implement `BikeshedGuaranteedNoDrop` only if // their constituent types implement `BikeshedGuaranteedNoDrop`. ty::Tuple(tys) => { @@ -779,6 +780,8 @@ where | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::UnsafeBinder(_) | ty::CoroutineWitness(..) => { ecx.add_goal( @@ -1389,6 +1392,8 @@ where | ty::Never | ty::Tuple(_) | ty::Adt(_, _) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::UnsafeBinder(_) => check_impls(), ty::Error(_) => None, diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index 411aad0717959..777a79d250d82 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -273,7 +273,7 @@ impl<'tcx, 'a> TypeVisitor> for ExportableItemsChecker<'tcx, 'a> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { match ty.kind() { - ty::Adt(adt_def, _) => { + ty::Adt(adt_def, _) | ty::View(adt_def, _, _) | ty::ViewInfer(adt_def, _, _) => { let did = adt_def.did(); let exportable = if did.is_local() { self.exportable_items.contains(&did) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index c3b3d14848982..f233f98c95203 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -369,7 +369,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { subtype_is_empty: cx.is_uninhabited(*sub_ty), } } - ty::Adt(def, args) if def.is_enum() => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) + if def.is_enum() => + { let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(ty); if def.variants().is_empty() && !is_declared_nonexhaustive { ConstructorSet::NoConstructors @@ -407,8 +409,10 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ConstructorSet::Variants { variants, non_exhaustive: is_declared_nonexhaustive } } } - ty::Adt(def, _) if def.is_union() => ConstructorSet::Union, - ty::Adt(..) | ty::Tuple(..) => { + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) if def.is_union() => { + ConstructorSet::Union + } + ty::Adt(..) | ty::Tuple(..) | ty::View(..) | ty::ViewInfer(..) => { ConstructorSet::Struct { empty: cx.is_uninhabited(ty.inner()) } } ty::Ref(..) => ConstructorSet::Ref, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 29ee27bc102f9..330615f1934b5 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -185,7 +185,9 @@ where | ty::FnDef(def_id, ..) | ty::Closure(def_id, ..) | ty::CoroutineClosure(def_id, ..) - | ty::Coroutine(def_id, ..) => { + | ty::Coroutine(def_id, ..) + | ty::View(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..) + | ty::ViewInfer(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..) => { try_visit!(self.def_id_visitor.visit_def_id(def_id, "type", &ty)); if V::SHALLOW { return V::Result::output(); diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 17edd29dcbb42..d9066c3022e85 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -437,7 +437,10 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables, cx))), ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables, cx))), ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables, cx))), - ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt( + ty::Adt(adt_def, generic_args) + // FIXME(scrabsha): lower view types to their own `rustc_public` type. + | ty::View(adt_def, generic_args, _) + | ty::ViewInfer(adt_def, generic_args, _) => TyKind::RigidTy(RigidTy::Adt( tables.adt_def(adt_def.did()), generic_args.stable(tables, cx), )), diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index f55ceb6ffa6f2..971082662103d 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -447,7 +447,7 @@ pub(crate) fn encode_ty<'tcx>( } // User-defined types - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) | ty::View(adt_def, args, _) | ty::ViewInfer(adt_def, args, _) => { let mut s = String::new(); let def_id = adt_def.did(); if let Some(encoding) = find_attr!(tcx, def_id, CfiEncoding { encoding } => encoding) { diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 6b3554331b420..b6043d6d0d6ec 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -131,9 +131,13 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { } } - ty::Adt(..) if t.is_c_void(self.tcx) => self.tcx.types.unit, + ty::Adt(..) | ty::View(..) | ty::ViewInfer(..) if t.is_c_void(self.tcx) => { + self.tcx.types.unit + } - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) + | ty::View(adt_def, args, _) + | ty::ViewInfer(adt_def, args, _) => { if adt_def.repr().transparent() && adt_def.is_struct() && !self.parents.contains(&t) { // Don't transform repr(transparent) types with an user-defined CFI encoding to diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 9f9c30abe2c1b..82ff407b01323 100644 --- a/compiler/rustc_symbol_mangling/src/export.rs +++ b/compiler/rustc_symbol_mangling/src/export.rs @@ -62,7 +62,9 @@ impl<'tcx> AbiStableHash<'tcx> for Ty<'tcx> { ty::Uint(uint_ty) => uint_ty.name_str().abi_stable_hash(tcx, hasher), ty::Float(float_ty) => float_ty.name_str().abi_stable_hash(tcx, hasher), - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) + | ty::View(adt_def, args, _) + | ty::ViewInfer(adt_def, args, _) => { adt_def.is_struct().abi_stable_hash(tcx, hasher); adt_def.is_enum().abi_stable_hash(tcx, hasher); adt_def.is_union().abi_stable_hash(tcx, hasher); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 6294b3272d497..d4355a28ab2b3 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -584,7 +584,10 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args) | ty::Closure(def_id, args) | ty::CoroutineClosure(def_id, args) - | ty::Coroutine(def_id, args) => { + | ty::Coroutine(def_id, args) + // FIXME(scrabsha): do we need some custom mangling for view types? + | ty::View(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args, _) + | ty::ViewInfer(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args, _) => { self.print_def_path(def_id, args)?; } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 8af061168a865..a10b7fc4511cc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1909,7 +1909,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::Bool => Some(0), ty::Char => Some(1), ty::Str => Some(2), - ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => Some(2), + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) + if tcx.is_lang_item(def.did(), LangItem::String) => + { + Some(2) + } ty::Int(..) | ty::Uint(..) | ty::Float(..) @@ -1933,7 +1937,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::CoroutineClosure(..) => Some(21), ty::Pat(..) => Some(22), ty::UnsafeBinder(..) => Some(23), - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None, + ty::View(..) => Some(24), + ty::Placeholder(..) + | ty::Bound(..) + | ty::Infer(..) + | ty::ViewInfer(..) + | ty::Error(_) => None, } } diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 567845a34bd8b..fc2d553f2971f 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -380,6 +380,8 @@ fn evaluate_host_effect_for_copy_clone_goal<'tcx>( | ty::Adt(_, _) | ty::Alias(_, _) | ty::Param(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Placeholder(..) => Err(EvaluationFailure::NoSolution), ty::Bound(..) @@ -452,11 +454,15 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( let const_conditions = match *self_ty.kind() { // `ManuallyDrop` is trivially `[const] Destruct` as we do not run any drop glue on it. - ty::Adt(adt_def, _) if adt_def.is_manually_drop() => thin_vec![], + ty::Adt(adt_def, _) | ty::View(adt_def, _, _) | ty::ViewInfer(adt_def, _, _) + if adt_def.is_manually_drop() => + { + thin_vec![] + } // An ADT is `[const] Destruct` only if all of the fields are, // *and* if there is a `Drop` impl, that `Drop` impl is also `[const]`. - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) | ty::View(adt_def, args, _) | ty::ViewInfer(adt_def, args, _) => { let mut const_conditions: ThinVec<_> = adt_def .all_fields() .map(|field| { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 79b531afbe2ae..eeafd31e600b6 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1078,6 +1078,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(..) + | ty::View(..) + | ty::ViewInfer(..) // Integers and floats always have `u8` as their discriminant. | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, @@ -1136,7 +1138,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Foreign(_) // If returned by `struct_tail` this is a unit struct // without any fields, or not a struct, and therefore is Sized. - | ty::Adt(..) + | ty::Adt(..) | ty::View(..) | ty::ViewInfer(_, _, _) // If returned by `struct_tail` this is the empty tuple. | ty::Tuple(..) // Integers and floats are always Sized, and so have unit type metadata. diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index a9ed6126ea752..aa90a719d0cc0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -64,7 +64,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { trivial_dropck_outlives(tcx, args.as_coroutine_closure().tupled_upvars_ty()) } - ty::Adt(def, _) => { + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => { if def.is_manually_drop() { // `ManuallyDrop` never has a dtor. true @@ -383,7 +383,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( } } - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { let DropckConstraint { dtorck_types, outlives, overflows } = tcx.at(span).adt_dtorck_constraint(def.did()); // FIXME: we can try to recursively `dtorck_constraint_on_ty` diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index d4027fcf388b1..aedad5fd06e0c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -712,6 +712,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Error(_) => return true, // FIXME: Function definitions could actually implement `FnPtr` by // casting the ZST function def to a function pointer. @@ -892,6 +894,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Never | ty::Tuple(_) + | ty::View(..) + | ty::ViewInfer(..) | ty::UnsafeBinder(_) => { // Only consider auto impls of unsafe traits when there are // no unsafe fields. @@ -1231,7 +1235,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // Fallback to whatever user-defined impls or param-env clauses exist in this case. - ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {} + ty::Adt(..) + | ty::Alias(..) + | ty::Param(..) + | ty::Placeholder(..) + | ty::View(..) + | ty::ViewInfer(..) => {} ty::Infer(ty::TyVar(_)) => { candidates.ambiguous = true; @@ -1287,7 +1296,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // Conditionally `Sized`. - ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => { + ty::Tuple(..) + | ty::Pat(..) + | ty::Adt(..) + | ty::UnsafeBinder(_) + | ty::View(..) + | ty::ViewInfer(..) => { candidates.vec.push(SizedCandidate); } @@ -1363,6 +1377,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Alias(..) | ty::Param(_) | ty::Bound(_, _) + | ty::View(..) + | ty::ViewInfer(..) | ty::Error(_) | ty::Infer(_) | ty::Placeholder(_) => {} @@ -1402,6 +1418,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Never | ty::Tuple(..) | ty::Alias(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::Param(..) | ty::Bound(..) | ty::Error(_) @@ -1449,6 +1467,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::UnsafeBinder(_) | ty::CoroutineWitness(..) | ty::Bound(..) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 49c277b39289b..7e9730200a720 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1243,7 +1243,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `&mut T` and `&T` always implement `BikeshedGuaranteedNoDrop`. ty::Ref(..) => {} // `ManuallyDrop` always implements `BikeshedGuaranteedNoDrop`. - ty::Adt(def, _) if def.is_manually_drop() => {} + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) + if def.is_manually_drop() => {} // Arrays and tuples implement `BikeshedGuaranteedNoDrop` only if // their constituent types implement `BikeshedGuaranteedNoDrop`. ty::Tuple(tys) => { @@ -1297,6 +1298,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Coroutine(..) | ty::UnsafeBinder(_) | ty::CoroutineWitness(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::Bound(..) => { obligations.push(obligation.with( tcx, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 58f2d0c7f33ac..0d878fe0424a8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2211,7 +2211,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Pat(ty, _) => ty::Binder::dummy(vec![*ty]), - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) { ty::Binder::dummy(vec![crit.instantiate(self.tcx(), args).skip_norm_wip()]) } else { @@ -2300,6 +2300,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::Dynamic(..) | ty::Adt(..) | ty::Alias(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::Param(..) | ty::Placeholder(..) | ty::Bound(..) @@ -2428,17 +2430,24 @@ impl<'tcx> SelectionContext<'_, 'tcx> { }), // For `PhantomData`, we pass `T`. - ty::Adt(def, args) if def.is_phantom_data() => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) + if def.is_phantom_data() => + { ty::Binder::dummy(AutoImplConstituents { types: args.types().collect(), assumptions: vec![], }) } - ty::Adt(def, args) => ty::Binder::dummy(AutoImplConstituents { - types: def.all_fields().map(|f| f.ty(self.tcx(), args).skip_norm_wip()).collect(), - assumptions: vec![], - }), + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { + ty::Binder::dummy(AutoImplConstituents { + types: def + .all_fields() + .map(|f| f.ty(self.tcx(), args).skip_norm_wip()) + .collect(), + assumptions: vec![], + }) + } ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => { if self.infcx.can_define_opaque_ty(def_id) { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 95043385cf17a..70d9a05bed9f8 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -817,7 +817,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { return; // Subtree handled by compute_inherent_projection. } - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { // WfNominalType let obligations = self.nominal_obligations(def.did(), args); self.out.extend(obligations); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 7a53fe1e0cfc8..c6c0a9caf2aca 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -625,7 +625,9 @@ fn layout_of_uncached<'tcx>( // #[rustc_scalable_vector] // struct svuint32x2_t(svuint32_t, svuint32_t); // ``` - ty::Adt(def, _args) if def.repr().scalable() => { + ty::Adt(def, _args) | ty::View(def, _args, _) | ty::ViewInfer(def, _args, _) + if def.repr().scalable() => + { let Some((element_count, element_ty, number_of_vectors)) = ty.scalable_vector_parts(tcx) else { @@ -644,7 +646,9 @@ fn layout_of_uncached<'tcx>( } // SIMD vector types. - ty::Adt(def, args) if def.repr().simd() => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) + if def.repr().simd() => + { // Supported SIMD vectors are ADTs with a single array field: // // * #[repr(simd)] struct S([T; 4]) @@ -687,7 +691,7 @@ fn layout_of_uncached<'tcx>( } // ADTs. - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { // Cache the field layouts. let variants = def .variants() diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index ec51304104745..d5ac385f6b0cb 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -258,7 +258,9 @@ where // Check for a `Drop` impl and whether this is a union or // `ManuallyDrop`. If it's a struct or enum without a `Drop` // impl then check whether the field types need `Drop`. - ty::Adt(adt_def, args) => { + ty::Adt(adt_def, args) + | ty::View(adt_def, args, _) + | ty::ViewInfer(adt_def, args, _) => { let tys = match (self.adt_components)(adt_def, args) { Err(AlwaysRequiresDrop) => { return Some(self.always_drop_component(ty)); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 8e67b97c4f21c..4acee984d0924 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -67,10 +67,12 @@ fn sizedness_constraint_for_ty<'tcx>( tys.last().and_then(|&ty| sizedness_constraint_for_ty(tcx, sizedness, ty)) } - ty::Adt(adt, args) => adt.sizedness_constraint(tcx, sizedness).and_then(|intermediate| { - let ty = intermediate.instantiate(tcx, args).skip_norm_wip(); - sizedness_constraint_for_ty(tcx, sizedness, ty) - }), + ty::Adt(adt, args) | ty::View(adt, args, _) | ty::ViewInfer(adt, args, _) => { + adt.sizedness_constraint(tcx, sizedness).and_then(|intermediate| { + let ty = intermediate.instantiate(tcx, args).skip_norm_wip(); + sizedness_constraint_for_ty(tcx, sizedness, ty) + }) + } ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { bug!("unexpected type `{ty:?}` in `sizedness_constraint_for_ty`") @@ -390,6 +392,8 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) | ty::Never | ty::Tuple(_) | ty::Alias(_, _) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Param(_) | ty::Bound(_, _) | ty::Placeholder(_) diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 9b50657b6b8b1..91bd6f3d066c9 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -102,7 +102,9 @@ pub fn simplify_type( ty::Int(int_type) => Some(SimplifiedType::Int(int_type)), ty::Uint(uint_type) => Some(SimplifiedType::Uint(uint_type)), ty::Float(float_type) => Some(SimplifiedType::Float(float_type)), - ty::Adt(def, _) => Some(SimplifiedType::Adt(def.def_id().into())), + ty::Adt(def, _) | ty::View(def, _, _) | ty::ViewInfer(def, _, _) => { + Some(SimplifiedType::Adt(def.def_id().into())) + } ty::Str => Some(SimplifiedType::Str), ty::Array(..) => Some(SimplifiedType::Array), ty::Slice(..) => Some(SimplifiedType::Slice), @@ -295,6 +297,8 @@ impl {} }; @@ -468,6 +472,31 @@ impl match rhs.kind() { + ty::View(rhs_def, rhs_args, rhs_fields) => { + lhs_def == rhs_def + && self.args_may_unify_inner(lhs_args, rhs_args, depth) + // FIXME(scrabsha): should we try harder here? and have a call to + // `self.viewed_fields_may_unify_inner?` + && lhs_fields == rhs_fields + } + ty::ViewInfer(rhs_def, rhs_args, _) => { + lhs_def == rhs_def && self.args_may_unify_inner(lhs_args, rhs_args, depth) + // FIXME(scrabsha): should we try harder here? and have a call to + // `self.viewed_fields_may_unify_inner?` + } + _ => false, + }, + + ty::ViewInfer(lhs_def, lhs_args, _) => match rhs.kind() { + ty::View(rhs_def, rhs_args, _) | ty::ViewInfer(rhs_def, rhs_args, _) => { + // FIXME(scrabsha): should we try harder here? and have a call to + // `self.viewed_fields_may_unify_inner?` + lhs_def == rhs_def && self.args_may_unify_inner(lhs_args, rhs_args, depth) + } + _ => false, + }, + ty::UnsafeBinder(lhs_ty) => match rhs.kind() { ty::UnsafeBinder(rhs_ty) => { self.types_may_unify(lhs_ty.skip_binder(), rhs_ty.skip_binder()) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index adcda752632e7..bc5c93d265fad 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -303,7 +303,7 @@ impl FlagComputation { } }, - ty::Adt(_, args) => { + ty::Adt(_, args) | ty::View(_, args, _) | ty::ViewInfer(_, args, _) => { self.add_args(args.as_slice()); } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 4776771f5e7f8..0d0a2b4e95d04 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -197,6 +197,8 @@ pub trait Ty>: | ty::Alias(_, _) | ty::Param(_) | ty::Bound(_, _) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => false, diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 136a14ce8448a..8297a9ee32664 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -173,6 +173,8 @@ pub trait Interner: + TypeVisitable + SliceLike; type Safety: Safety; + type FieldSet: Copy + Eq + Hash + SliceLike; + type Field: Debug + Hash; // Kinds of consts type Const: Const; diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index 1494da29527c4..38017a079f83b 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -208,7 +208,9 @@ impl TypeVisitor for OutlivesCollector<'_, I> { | ty::FnPtr(..) | ty::UnsafeBinder(_) | ty::Dynamic(_, _) - | ty::Tuple(_) => { + | ty::Tuple(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) => { ty.super_visit_with(self); } } diff --git a/compiler/rustc_type_ir/src/ty/adt.rs b/compiler/rustc_type_ir/src/ty/adt.rs new file mode 100644 index 0000000000000..e1cdf1519f2fe --- /dev/null +++ b/compiler/rustc_type_ir/src/ty/adt.rs @@ -0,0 +1 @@ +// FIXME(scrabsha): remove this file diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 25868bc9377e2..5e014ba507c93 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -304,6 +304,13 @@ pub enum TyKind { /// A type parameter; for example, `T` in `fn f(x: T) {}`. Param(I::ParamTy), + /// A view over an ADT. The set of viewed fields has been computed. Refer to the + /// documentation of [`TyKind::Adt`] for more. + View(I::AdtDef, I::GenericArgs, I::FieldSet), + /// A view over an ADT. The set of viewed fields has not been computed yet. Refer to + /// the documentation of [`TyKind::Adt`] for more. + ViewInfer(I::AdtDef, I::GenericArgs, FieldSetVid), + /// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`. /// /// For canonical queries, we replace inference variables with bound variables, @@ -401,7 +408,9 @@ impl TyKind { | ty::Coroutine(_, _) | ty::CoroutineWitness(..) | ty::Never - | ty::Tuple(_) => true, + | ty::Tuple(_) + | ty::View(_, _, _) + | ty::ViewInfer(_, _, _) => true, ty::Error(_) | ty::Infer(_) @@ -422,21 +431,7 @@ impl fmt::Debug for TyKind { Int(i) => write!(f, "{i:?}"), Uint(u) => write!(f, "{u:?}"), Float(float) => write!(f, "{float:?}"), - Adt(d, s) => { - write!(f, "{d:?}")?; - let mut s = s.iter(); - let first = s.next(); - match first { - Some(first) => write!(f, "<{:?}", first)?, - None => return Ok(()), - }; - - for arg in s { - write!(f, ", {:?}", arg)?; - } - - write!(f, ">") - } + Adt(d, s) => debug_adt::(f, d, s), Foreign(d) => f.debug_tuple("Foreign").field(d).finish(), Str => write!(f, "str"), Array(t, c) => write!(f, "[{t:?}; {c:?}]"), @@ -473,6 +468,31 @@ impl fmt::Debug for TyKind { Alias(is_rigid, a) => f.debug_tuple("Alias").field(&is_rigid).field(&a).finish(), Param(p) => write!(f, "{p:?}"), Bound(d, b) => crate::debug_bound_var(f, *d, b), + View(d, s, t) => { + write!(f, "view_type!(")?; + debug_adt::(f, d, s)?; + write!(f, ".{{")?; + if !t.is_empty() { + write!(f, " ")?; + let mut first = true; + + for field in t.iter() { + if !first { + write!(f, ", ")?; + } else { + first = false; + } + write!(f, "{field:?}")?; + } + write!(f, " ")?; + } + write!(f, "}})") + } + ViewInfer(d, s, t) => { + write!(f, "view_type!(")?; + debug_adt::(f, d, s)?; + write!(f, ".{{ {t:?} }}") + } Placeholder(p) => write!(f, "{p:?}"), Infer(t) => write!(f, "{:?}", t), TyKind::Error(_) => write!(f, "{{type error}}"), @@ -480,6 +500,29 @@ impl fmt::Debug for TyKind { } } +fn debug_adt( + f: &mut fmt::Formatter<'_>, + d: &::AdtDef, + s: &I::GenericArgs, +) -> fmt::Result +where + I: Interner, +{ + write!(f, "{d:?}")?; + let mut s = s.iter(); + let first = s.next(); + match first { + Some(first) => write!(f, "<{:?}", first)?, + None => return Ok(()), + }; + + for arg in s { + write!(f, ", {:?}", arg)?; + } + + write!(f, ">") +} + impl AliasTy { pub fn new_from_args(interner: I, kind: AliasTyKind, args: I::GenericArgs) -> AliasTy { if cfg!(debug_assertions) { @@ -731,6 +774,23 @@ rustc_index::newtype_index! { pub struct FloatVid {} } +rustc_index::newtype_index! { + /// A **field set** **v**ariable **ID**. + #[encodable] + #[orderable] + #[debug_format = "?{}"] + #[gate_rustc_only] + #[derive(GenericTypeVisitable)] + pub struct FieldSetVid {} +} + +#[cfg(feature = "nightly")] +impl StableHash for FieldSetVid { + fn stable_hash(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { + panic!("field set variables should not be hashed: {self:?}") + } +} + /// A placeholder for a type that hasn't been inferred yet. /// /// E.g., if we have an empty array (`[]`), then we create a fresh diff --git a/compiler/rustc_type_ir/src/walk.rs b/compiler/rustc_type_ir/src/walk.rs index 11c81c47b4cf5..b85a71596bec8 100644 --- a/compiler/rustc_type_ir/src/walk.rs +++ b/compiler/rustc_type_ir/src/walk.rs @@ -135,7 +135,9 @@ fn push_inner(stack: &mut TypeWalkerStack, parent: I::GenericArg | ty::Closure(_, args) | ty::CoroutineClosure(_, args) | ty::Coroutine(_, args) - | ty::CoroutineWitness(_, args) => { + | ty::CoroutineWitness(_, args) + | ty::View(_, args, _) + | ty::ViewInfer(_, args, _) => { stack.extend(args.iter().rev()); } ty::FnDef(_, args) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a81d56e708173..11accc9e3530e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2195,7 +2195,7 @@ pub(crate) fn clean_middle_ty<'tcx>( let ty = clean_middle_ty(inner.into(), cx, None, None); UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, ty })) } - ty::Adt(def, args) => { + ty::Adt(def, args) | ty::View(def, args, _) | ty::ViewInfer(def, args, _) => { let did = def.did(); let kind = match def.adt_kind() { AdtKind::Struct => ItemType::Struct, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 56a73955abce0..35e8bfe4be010 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1782,6 +1782,8 @@ impl PrimitiveType { | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::UnsafeBinder(..) => None, } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ce191aaf445d5..042b2dde1adf3 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -559,6 +559,8 @@ fn ty_to_res<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) + | ty::View(..) + | ty::ViewInfer(..) | ty::Error(_) => return None, }) } diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 42d9270a0bcb9..3ed85785cbac7 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -905,7 +905,7 @@ impl TyCoercionStability { TyKind::View(ty, _) => { // FIXME(scrabsha): what are the semantics of view types here? Self::for_hir_ty(ty) - } + }, TyKind::UnsafeBinder(..) => Self::None, }; } @@ -956,7 +956,7 @@ impl TyCoercionStability { | ty::Placeholder(_) | ty::Dynamic(..) | ty::Param(_) => Self::Reborrow, - ty::Adt(_, args) + ty::Adt(_, args) | ty::View(_, args, _) | ty::ViewInfer(_, args, _) if ty.has_placeholders() || ty.has_opaque_types() || (!for_return && args.has_non_region_param()) => @@ -975,6 +975,8 @@ impl TyCoercionStability { | ty::Str | ty::Slice(..) | ty::Adt(..) + | ty::View(..) + | ty::ViewInfer(..) | ty::Foreign(_) | ty::FnDef(..) | ty::Coroutine(..)