]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #94862 - pierwill:bootstrap-useless, r=Dylan-DPC
authorbors <bors@rust-lang.org>
Sun, 13 Mar 2022 05:37:56 +0000 (05:37 +0000)
committerbors <bors@rust-lang.org>
Sun, 13 Mar 2022 05:37:56 +0000 (05:37 +0000)
Remove unneeded conversions in bootstrapping code

Fixes warnings from `clippy::useless_conversion` in `src/bootstrap`.

233 files changed:
Cargo.lock
compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
compiler/rustc_borrowck/src/diagnostics/mod.rs
compiler/rustc_borrowck/src/diagnostics/move_errors.rs
compiler/rustc_borrowck/src/diagnostics/region_errors.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_codegen_cranelift/src/common.rs
compiler/rustc_codegen_cranelift/src/unsize.rs
compiler/rustc_codegen_cranelift/src/value_and_place.rs
compiler/rustc_codegen_gcc/src/type_of.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
compiler/rustc_codegen_llvm/src/type_of.rs
compiler/rustc_codegen_ssa/src/base.rs
compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
compiler/rustc_codegen_ssa/src/glue.rs
compiler/rustc_codegen_ssa/src/mir/operand.rs
compiler/rustc_codegen_ssa/src/mir/place.rs
compiler/rustc_const_eval/src/const_eval/mod.rs
compiler/rustc_const_eval/src/interpret/intern.rs
compiler/rustc_const_eval/src/interpret/intrinsics.rs
compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
compiler/rustc_const_eval/src/interpret/memory.rs
compiler/rustc_const_eval/src/interpret/operand.rs
compiler/rustc_const_eval/src/interpret/validity.rs
compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
compiler/rustc_const_eval/src/util/alignment.rs
compiler/rustc_const_eval/src/util/call_kind.rs
compiler/rustc_expand/src/mbe/macro_parser.rs
compiler/rustc_expand/src/mbe/transcribe.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
compiler/rustc_lint/src/builtin.rs
compiler/rustc_lint/src/context.rs
compiler/rustc_lint/src/internal.rs
compiler/rustc_lint/src/methods.rs
compiler/rustc_lint/src/non_fmt_panic.rs
compiler/rustc_lint/src/pass_by_value.rs
compiler/rustc_lint/src/types.rs
compiler/rustc_lint/src/unused.rs
compiler/rustc_metadata/src/rmeta/decoder.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_middle/src/arena.rs
compiler/rustc_middle/src/middle/region.rs
compiler/rustc_middle/src/mir/interpret/error.rs
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/tcx.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/thir.rs
compiler/rustc_middle/src/traits/chalk.rs
compiler/rustc_middle/src/ty/adt.rs
compiler/rustc_middle/src/ty/closure.rs
compiler/rustc_middle/src/ty/codec.rs
compiler/rustc_middle/src/ty/context.rs
compiler/rustc_middle/src/ty/diagnostics.rs
compiler/rustc_middle/src/ty/error.rs
compiler/rustc_middle/src/ty/fast_reject.rs
compiler/rustc_middle/src/ty/inhabitedness/mod.rs
compiler/rustc_middle/src/ty/layout.rs
compiler/rustc_middle/src/ty/print/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/relate.rs
compiler/rustc_middle/src/ty/structural_impls.rs
compiler/rustc_middle/src/ty/sty.rs
compiler/rustc_middle/src/ty/util.rs
compiler/rustc_mir_build/src/build/expr/as_place.rs
compiler/rustc_mir_build/src/build/expr/into.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/simplify.rs
compiler/rustc_mir_build/src/build/matches/test.rs
compiler/rustc_mir_build/src/check_unsafety.rs
compiler/rustc_mir_build/src/thir/cx/expr.rs
compiler/rustc_mir_build/src/thir/pattern/check_match.rs
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_build/src/thir/pattern/mod.rs
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
compiler/rustc_mir_build/src/thir/util.rs
compiler/rustc_mir_dataflow/src/elaborate_drops.rs
compiler/rustc_mir_dataflow/src/impls/mod.rs
compiler/rustc_mir_transform/src/check_unsafety.rs
compiler/rustc_mir_transform/src/generator.rs
compiler/rustc_mir_transform/src/remove_uninit_drops.rs
compiler/rustc_mir_transform/src/shim.rs
compiler/rustc_mir_transform/src/simplify_try.rs
compiler/rustc_parse/src/parser/diagnostics.rs
compiler/rustc_parse/src/parser/item.rs
compiler/rustc_passes/src/dead.rs
compiler/rustc_passes/src/intrinsicck.rs
compiler/rustc_privacy/src/lib.rs
compiler/rustc_save_analysis/src/lib.rs
compiler/rustc_symbol_mangling/src/v0.rs
compiler/rustc_trait_selection/src/traits/coherence.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/misc.rs
compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
compiler/rustc_trait_selection/src/traits/structural_match.rs
compiler/rustc_trait_selection/src/traits/wf.rs
compiler/rustc_traits/src/chalk/db.rs
compiler/rustc_traits/src/dropck_outlives.rs
compiler/rustc_ty_utils/src/needs_drop.rs
compiler/rustc_ty_utils/src/representability.rs
compiler/rustc_ty_utils/src/ty.rs
compiler/rustc_typeck/src/astconv/mod.rs
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/demand.rs
compiler/rustc_typeck/src/check/dropck.rs
compiler/rustc_typeck/src/check/expr.rs
compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
compiler/rustc_typeck/src/check/generator_interior.rs
compiler/rustc_typeck/src/check/method/mod.rs
compiler/rustc_typeck/src/check/method/prelude2021.rs
compiler/rustc_typeck/src/check/method/probe.rs
compiler/rustc_typeck/src/check/method/suggest.rs
compiler/rustc_typeck/src/check/mod.rs
compiler/rustc_typeck/src/check/op.rs
compiler/rustc_typeck/src/check/pat.rs
compiler/rustc_typeck/src/check/place_op.rs
compiler/rustc_typeck/src/check/upvar.rs
compiler/rustc_typeck/src/check/wfcheck.rs
compiler/rustc_typeck/src/coherence/builtin.rs
compiler/rustc_typeck/src/coherence/inherent_impls.rs
compiler/rustc_typeck/src/coherence/orphan.rs
compiler/rustc_typeck/src/collect.rs
compiler/rustc_typeck/src/collect/type_of.rs
compiler/rustc_typeck/src/expr_use_visitor.rs
compiler/rustc_typeck/src/mem_categorization.rs
compiler/rustc_typeck/src/outlives/implicit_infer.rs
compiler/rustc_typeck/src/variance/constraints.rs
library/alloc/src/collections/vec_deque/iter.rs
library/alloc/src/collections/vec_deque/mod.rs
library/core/src/char/convert.rs
library/core/src/future/into_future.rs
library/core/src/num/dec2flt/mod.rs
src/bootstrap/setup.rs
src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/json/conversions.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/rustdoc-json-types/lib.rs
src/test/rustdoc-gui/toggle-docs.goml
src/test/rustdoc-json/fns/generics.rs [new file with mode: 0644]
src/test/ui/async-await/await-into-future.rs
src/test/ui/box/large-allocator-ice.rs
src/test/ui/consts/offset_from_ub.rs
src/test/ui/consts/offset_from_ub.stderr
src/test/ui/consts/offset_ub.stderr
src/test/ui/generics/single-colon-path-not-const-generics.rs [new file with mode: 0644]
src/test/ui/generics/single-colon-path-not-const-generics.stderr [new file with mode: 0644]
src/test/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs [new file with mode: 0644]
src/test/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs
src/test/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs [new file with mode: 0644]
src/test/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs [new file with mode: 0644]
src/test/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr [new file with mode: 0644]
src/test/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs
src/test/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
src/test/ui/methods/issues/issue-84495.rs [new file with mode: 0644]
src/test/ui/methods/issues/issue-84495.stderr [new file with mode: 0644]
src/test/ui/mismatched_types/issue-36053-2.rs
src/test/ui/mismatched_types/issue-36053-2.stderr
src/test/ui/pattern/usefulness/auxiliary/hidden.rs
src/test/ui/pattern/usefulness/auxiliary/unstable.rs
src/test/ui/pattern/usefulness/doc-hidden-fields.rs [new file with mode: 0644]
src/test/ui/pattern/usefulness/doc-hidden-fields.stderr [new file with mode: 0644]
src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs
src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
src/test/ui/pattern/usefulness/stable-gated-fields.rs [new file with mode: 0644]
src/test/ui/pattern/usefulness/stable-gated-fields.stderr [new file with mode: 0644]
src/test/ui/pattern/usefulness/stable-gated-patterns.rs
src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
src/test/ui/pattern/usefulness/unstable-gated-fields.rs [new file with mode: 0644]
src/test/ui/pattern/usefulness/unstable-gated-fields.stderr [new file with mode: 0644]
src/test/ui/pattern/usefulness/unstable-gated-patterns.rs
src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
src/test/ui/rfc-2008-non-exhaustive/auxiliary/unstable.rs
src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.rs
src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.rs
src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
src/test/ui/suggestions/constrain-suggest-ice.rs [new file with mode: 0644]
src/test/ui/suggestions/constrain-suggest-ice.stderr [new file with mode: 0644]
src/test/ui/suggestions/struct-field-type-including-single-colon.rs [new file with mode: 0644]
src/test/ui/suggestions/struct-field-type-including-single-colon.stderr [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
src/tools/clippy/clippy_lints/src/casts/utils.rs
src/tools/clippy/clippy_lints/src/default.rs
src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
src/tools/clippy/clippy_lints/src/derivable_impls.rs
src/tools/clippy/clippy_lints/src/derive.rs
src/tools/clippy/clippy_lints/src/empty_enum.rs
src/tools/clippy/clippy_lints/src/enum_clike.rs
src/tools/clippy/clippy_lints/src/eq_op.rs
src/tools/clippy/clippy_lints/src/eta_reduction.rs
src/tools/clippy/clippy_lints/src/format.rs
src/tools/clippy/clippy_lints/src/functions/must_use.rs
src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
src/tools/clippy/clippy_lints/src/large_enum_variant.rs
src/tools/clippy/clippy_lints/src/len_zero.rs
src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
src/tools/clippy/clippy_lints/src/methods/filter_map.rs
src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
src/tools/clippy/clippy_lints/src/mut_key.rs
src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
src/tools/clippy/clippy_lints/src/needless_update.rs
src/tools/clippy/clippy_lints/src/new_without_default.rs
src/tools/clippy/clippy_lints/src/non_copy_const.rs
src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
src/tools/clippy/clippy_lints/src/ptr.rs
src/tools/clippy/clippy_lints/src/self_named_constructors.rs
src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
src/tools/clippy/clippy_lints/src/try_err.rs
src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/clippy_utils/src/ty.rs
src/tools/miri

index 4d7b62e9c559fb65ed536d392a425c67becddbd9..5d9edc5157d94b5673e6a47c1b860953dd834b3e 100644 (file)
@@ -2327,7 +2327,6 @@ dependencies = [
  "compiletest_rs",
  "env_logger 0.9.0",
  "getrandom 0.2.0",
- "hex 0.4.2",
  "libc",
  "log",
  "measureme 9.1.2",
index 2217c0e14b2aae0d4ad4930b241f6e5de30008f9..ffea15bdc33ebd4593b8dd76e868c9862e615108 100644 (file)
@@ -138,7 +138,7 @@ pub(crate) fn add_explanation_to_diagnostic<'tcx>(
                 let mut ty = local_decl.ty;
                 if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
                     if let ty::Adt(adt, substs) = local_decl.ty.kind() {
-                        if tcx.is_diagnostic_item(sym::Option, adt.did) {
+                        if tcx.is_diagnostic_item(sym::Option, adt.did()) {
                             // in for loop desugaring, only look at the `Some(..)` inner type
                             ty = substs.type_at(0);
                         }
@@ -148,7 +148,7 @@ pub(crate) fn add_explanation_to_diagnostic<'tcx>(
                     // If type is an ADT that implements Drop, then
                     // simplify output by reporting just the ADT name.
                     ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => {
-                        ("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did)))
+                        ("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
                     }
 
                     // Otherwise, just report the whole type (and use
index 164ebfed0f7959306de31dc8a6f2373d4502701f..c2b5c16517af56312d4a41aaf99992da200e8f18 100644 (file)
@@ -370,7 +370,7 @@ fn describe_field_from_ty(
                 ty::Adt(def, _) => {
                     let variant = if let Some(idx) = variant_index {
                         assert!(def.is_enum());
-                        &def.variants[idx]
+                        &def.variant(idx)
                     } else {
                         def.non_enum_variant()
                     };
@@ -701,7 +701,7 @@ pub(super) fn describe_for_unnamed_place(&self, tcx: TyCtxt<'_>) -> String {
             BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
             BorrowedContentSource::OverloadedDeref(ty) => ty
                 .ty_adt_def()
-                .and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
+                .and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
                     name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
                     _ => None,
                 })
@@ -731,7 +731,7 @@ pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> String {
             }
             BorrowedContentSource::OverloadedDeref(ty) => ty
                 .ty_adt_def()
-                .and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
+                .and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
                     name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
                     _ => None,
                 })
index f76ec031aa9e258e6dc5b8ae35a826d050596d1a..48a70abc0b6046f5bec488f79f5134f7f52044c5 100644 (file)
@@ -388,7 +388,7 @@ fn report_cannot_move_from_borrowed_content(
         };
         let ty = move_place.ty(self.body, self.infcx.tcx).ty;
         let def_id = match *ty.kind() {
-            ty::Adt(self_def, _) => self_def.did,
+            ty::Adt(self_def, _) => self_def.did(),
             ty::Foreign(def_id)
             | ty::FnDef(def_id, _)
             | ty::Closure(def_id, _)
index 38b16fedd3a49ba4f234b4073e1768622980541b..1df7e826343bda8cb7313d9419aa8194b57eaab3 100644 (file)
@@ -345,8 +345,8 @@ pub(crate) fn report_region_error(
                     ty::Adt(adt, substs) => {
                         let generic_arg = substs[param_index as usize];
                         let identity_substs =
-                            InternalSubsts::identity_for_item(self.infcx.tcx, adt.did);
-                        let base_ty = self.infcx.tcx.mk_adt(adt, identity_substs);
+                            InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
+                        let base_ty = self.infcx.tcx.mk_adt(*adt, identity_substs);
                         let base_generic_arg = identity_substs[param_index as usize];
                         let adt_desc = adt.descr();
 
@@ -410,7 +410,7 @@ fn report_fnmut_error(
                 "returns a closure that contains a reference to a captured variable, which then \
                  escapes the closure body"
             }
-            ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did) => {
+            ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => {
                 "returns an `async` block that contains a reference to a captured variable, which then \
                  escapes the closure body"
             }
index 95018e51b0e7a551480a4936f9fe8da197ef9122..a7cf25d43d2301d67aa18f67d3fdab696d9e7514 100644 (file)
@@ -736,13 +736,13 @@ fn sanitize_projection(
             }
             ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
                 ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
-                    if index.as_usize() >= adt_def.variants.len() {
+                    if index.as_usize() >= adt_def.variants().len() {
                         PlaceTy::from_ty(span_mirbug_and_err!(
                             self,
                             place,
                             "cast to variant #{:?} but enum only has {:?}",
                             index,
-                            adt_def.variants.len()
+                            adt_def.variants().len()
                         ))
                     } else {
                         PlaceTy { ty: base_ty, variant_index: Some(index) }
@@ -816,7 +816,7 @@ fn field_ty(
 
         let (variant, substs) = match base_ty {
             PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
-                ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
+                ty::Adt(adt_def, substs) => (adt_def.variant(variant_index), substs),
                 ty::Generator(def_id, substs, _) => {
                     let mut variants = substs.as_generator().state_tys(def_id, tcx);
                     let Some(mut variant) = variants.nth(variant_index.into()) else {
@@ -835,7 +835,7 @@ fn field_ty(
             },
             PlaceTy { ty, variant_index: None } => match *ty.kind() {
                 ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
-                    (&adt_def.variants[VariantIdx::new(0)], substs)
+                    (adt_def.variant(VariantIdx::new(0)), substs)
                 }
                 ty::Closure(_, substs) => {
                     return match substs
@@ -1449,7 +1449,7 @@ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Lo
                         );
                     }
                 };
-                if variant_index.as_usize() >= adt.variants.len() {
+                if variant_index.as_usize() >= adt.variants().len() {
                     span_bug!(
                         stmt.source_info.span,
                         "bad set discriminant ({:?} = {:?}): value of of range",
@@ -1928,7 +1928,7 @@ fn aggregate_field_ty(
         match *ak {
             AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
                 let def = tcx.adt_def(adt_did);
-                let variant = &def.variants[variant_index];
+                let variant = &def.variant(variant_index);
                 let adj_field_index = active_field_index.unwrap_or(field_index);
                 if let Some(field) = variant.fields.get(adj_field_index) {
                     Ok(self.normalize(field.ty(tcx, substs), location))
index d3e36be3244f1da891df8b93f97b1d6113c50b76..89fd0bfa8bbfa2f7fe4b99415d35a8b0efd94c28 100644 (file)
@@ -67,7 +67,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
                 pointer_ty(tcx)
             }
         }
-        ty::Adt(adt_def, _) if adt_def.repr.simd() => {
+        ty::Adt(adt_def, _) if adt_def.repr().simd() => {
             let (element, count) = match &tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().abi
             {
                 Abi::Vector { element, count } => (element.clone(), *count),
index 8cae506e0cb62362eb56b626d02814f3d69395b2..fd63c3ecddbdfd9cdb2365ca0aec9bca6bc18d5e 100644 (file)
@@ -127,7 +127,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.variants[VariantIdx::new(0)].fields.len() {
+            for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() {
                 let src_f = src.value_field(fx, mir::Field::new(i));
                 let dst_f = dst.place_field(fx, mir::Field::new(i));
 
@@ -200,7 +200,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
 
             // Packed types ignore the alignment of their fields.
             if let ty::Adt(def, _) = layout.ty.kind() {
-                if def.repr.packed() {
+                if def.repr().packed() {
                     unsized_align = sized_align;
                 }
             }
index b016af5174e018630eddbb3b1ef5ae9bac8398ab..afe8797a0300969ef7901b36142a2f9841a8b640 100644 (file)
@@ -24,7 +24,7 @@ fn codegen_field<'tcx>(
         }
         match field_layout.ty.kind() {
             ty::Slice(..) | ty::Str | ty::Foreign(..) => simple(fx),
-            ty::Adt(def, _) if def.repr.packed() => {
+            ty::Adt(def, _) if def.repr().packed() => {
                 assert_eq!(layout.align.abi.bytes(), 1);
                 simple(fx)
             }
@@ -816,7 +816,7 @@ pub(crate) fn assert_assignable<'tcx>(
             // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
         }
         (&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
-            if adt_def_a.did == adt_def_b.did =>
+            if adt_def_a.did() == adt_def_b.did() =>
         {
             let mut types_a = substs_a.types();
             let mut types_b = substs_b.types();
index 0ada20cad2c3be3c3931a58151832a6c0d79a75b..649ffc16249a68c13a03e73977299e0ea7633b1a 100644 (file)
@@ -56,8 +56,8 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa
             if let (&ty::Adt(def, _), &Variants::Single { index }) =
                 (layout.ty.kind(), &layout.variants)
             {
-                if def.is_enum() && !def.variants.is_empty() {
-                    write!(&mut name, "::{}", def.variants[index].name).unwrap();
+                if def.is_enum() && !def.variants().is_empty() {
+                    write!(&mut name, "::{}", def.variant(index).name).unwrap();
                 }
             }
             if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
index a6e4878e5b3615abc7aaa897a46c0a07770d5632..f16a903ad2c5b9d00d147f231f8cac3ed12c3ff7 100644 (file)
@@ -641,7 +641,7 @@ pub fn type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll
             AdtKind::Struct => prepare_struct_metadata(cx, t, unique_type_id).finalize(cx),
             AdtKind::Union => prepare_union_metadata(cx, t, unique_type_id).finalize(cx),
             AdtKind::Enum => {
-                prepare_enum_metadata(cx, t, def.did, unique_type_id, vec![]).finalize(cx)
+                prepare_enum_metadata(cx, t, def.did(), unique_type_id, vec![]).finalize(cx)
             }
         },
         ty::Tuple(tys) => {
@@ -1209,7 +1209,7 @@ fn prepare_struct_metadata<'ll, 'tcx>(
     let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
 
     let (struct_def_id, variant) = match struct_type.kind() {
-        ty::Adt(def, _) => (def.did, def.non_enum_variant()),
+        ty::Adt(def, _) => (def.did(), def.non_enum_variant()),
         _ => bug!("prepare_struct_metadata on a non-ADT"),
     };
 
@@ -1386,7 +1386,7 @@ fn prepare_union_metadata<'ll, 'tcx>(
     let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
 
     let (union_def_id, variant) = match union_type.kind() {
-        ty::Adt(def, _) => (def.did, def.non_enum_variant()),
+        ty::Adt(def, _) => (def.did(), def.non_enum_variant()),
         _ => bug!("prepare_union_metadata on a non-ADT"),
     };
 
@@ -1468,7 +1468,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDes
         };
 
         let variant_info_for = |index: VariantIdx| match *self.enum_type.kind() {
-            ty::Adt(adt, _) => VariantInfo::Adt(&adt.variants[index], index),
+            ty::Adt(adt, _) => VariantInfo::Adt(&adt.variant(index), index),
             ty::Generator(def_id, _, _) => {
                 let (generator_layout, generator_saved_local_names) =
                     generator_variant_info_data.as_ref().unwrap();
@@ -1492,7 +1492,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDes
         match self.layout.variants {
             Variants::Single { index } => {
                 if let ty::Adt(adt, _) = self.enum_type.kind() {
-                    if adt.variants.is_empty() {
+                    if adt.variants().is_empty() {
                         return vec![];
                     }
                 }
@@ -1942,7 +1942,7 @@ fn prepare_enum_metadata<'ll, 'tcx>(
 
     let discriminant_type_metadata = |discr: Primitive| {
         let enumerators_metadata: Vec<_> = match enum_type.kind() {
-            ty::Adt(def, _) => iter::zip(def.discriminants(tcx), &def.variants)
+            ty::Adt(def, _) => iter::zip(def.discriminants(tcx), def.variants())
                 .map(|((_, discr), v)| {
                     let name = v.name.as_str();
                     let is_unsigned = match discr.ty.kind() {
@@ -2313,7 +2313,7 @@ fn set_members_of_composite_type<'ll, 'tcx>(
 fn compute_type_parameters<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIArray {
     if let ty::Adt(def, substs) = *ty.kind() {
         if substs.types().next().is_some() {
-            let generics = cx.tcx.generics_of(def.did);
+            let generics = cx.tcx.generics_of(def.did());
             let names = get_parameter_names(cx, generics);
             let template_params: Vec<_> = iter::zip(substs, names)
                 .filter_map(|(kind, name)| {
index 1b4a193dbf1852d8cb193dc3c75272808215889e..34013b5f737c94cbc66d3c666eec608425e55cbb 100644 (file)
@@ -524,7 +524,7 @@ fn get_containing_scope<'ll, 'tcx>(
                             {
                                 Some(type_metadata(cx, impl_self_ty))
                             } else {
-                                Some(namespace::item_namespace(cx, def.did))
+                                Some(namespace::item_namespace(cx, def.did()))
                             }
                         }
                         _ => None,
index da378dc649352603f54d38a390d44ee1c076f9d6..757aa9a10116702f60ead8aee71abe46c22abc0f 100644 (file)
@@ -53,8 +53,8 @@ fn uncached_llvm_type<'a, 'tcx>(
             if let (&ty::Adt(def, _), &Variants::Single { index }) =
                 (layout.ty.kind(), &layout.variants)
             {
-                if def.is_enum() && !def.variants.is_empty() {
-                    write!(&mut name, "::{}", def.variants[index].name).unwrap();
+                if def.is_enum() && !def.variants().is_empty() {
+                    write!(&mut name, "::{}", def.variant(index).name).unwrap();
                 }
             }
             if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
index 11f32d92e44cd0bf45181e8f8fbd2ee925e702ea..0b31e4b558261b52e4efb4a86297b92f0839b61a 100644 (file)
@@ -255,7 +255,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.variants[VariantIdx::new(0)].fields.len() {
+            for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() {
                 let src_f = src.project_field(bx, i);
                 let dst_f = dst.project_field(bx, i);
 
index 62a297937d40c66c2856fa5746f67f6123e64cb2..67df64e9b1baa6352bf1bd5d1e2f8428932dccd1 100644 (file)
@@ -74,7 +74,7 @@ fn push_debuginfo_type_name<'tcx>(
             if def.is_enum() && cpp_like_debuginfo {
                 msvc_enum_fallback(tcx, t, def, substs, output, visited);
             } else {
-                push_item_name(tcx, def.did, qualified, output);
+                push_item_name(tcx, def.did(), qualified, output);
                 push_generic_params_internal(tcx, substs, output, visited);
             }
         }
@@ -405,15 +405,15 @@ fn push_debuginfo_type_name<'tcx>(
     fn msvc_enum_fallback<'tcx>(
         tcx: TyCtxt<'tcx>,
         ty: Ty<'tcx>,
-        def: &AdtDef,
+        def: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         output: &mut String,
         visited: &mut FxHashSet<Ty<'tcx>>,
     ) {
-        let layout = tcx.layout_of(tcx.param_env(def.did).and(ty)).expect("layout error");
+        let layout = tcx.layout_of(tcx.param_env(def.did()).and(ty)).expect("layout error");
 
         output.push_str("enum$<");
-        push_item_name(tcx, def.did, true, output);
+        push_item_name(tcx, def.did(), true, output);
         push_generic_params_internal(tcx, substs, output, visited);
 
         if let Variants::Multiple {
@@ -435,14 +435,14 @@ fn msvc_enum_fallback<'tcx>(
             let max = dataful_discriminant_range.end;
             let max = tag.value.size(&tcx).truncate(max);
 
-            let dataful_variant_name = def.variants[*dataful_variant].name.as_str();
+            let dataful_variant_name = def.variant(*dataful_variant).name.as_str();
 
             output.push_str(&format!(", {}, {}, {}", min, max, dataful_variant_name));
         } else if let Variants::Single { index: variant_idx } = &layout.variants {
             // Uninhabited enums can't be constructed and should never need to be visualized so
             // skip this step for them.
-            if def.variants.len() != 0 {
-                let variant = def.variants[*variant_idx].name.as_str();
+            if def.variants().len() != 0 {
+                let variant = def.variant(*variant_idx).name.as_str();
 
                 output.push_str(&format!(", {}", variant));
             }
index 2c4e6bbe9a5c1b5ea27bba5732f8652f671ab5b4..694f5434e9afd029edf4624ff1da99989cac3e33 100644 (file)
@@ -74,7 +74,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             // Packed types ignore the alignment of their fields.
             if let ty::Adt(def, _) = t.kind() {
-                if def.repr.packed() {
+                if def.repr().packed() {
                     unsized_align = sized_align;
                 }
             }
index 66be58cf62ca03ac6abbb5778a6225e39909543f..858f71ebc3933b9a70befcbe4e6ad65294fa574a 100644 (file)
@@ -126,7 +126,14 @@ pub fn deref<Cx: LayoutTypeMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
             .ty;
         let (llptr, llextra) = match self.val {
             OperandValue::Immediate(llptr) => (llptr, None),
-            OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)),
+            OperandValue::Pair(llptr, llextra) => {
+                // if the box's allocator isn't a ZST, then "llextra" is actually the allocator
+                if self.layout.ty.is_box() && !self.layout.field(cx, 1).is_zst() {
+                    (llptr, None)
+                } else {
+                    (llptr, Some(llextra))
+                }
+            }
             OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self),
         };
         let layout = cx.layout_of(projected_ty);
index 809d64479084a389bd617c55846d2918f785227d..2b8fa3be56dd5c9f574fd9e5daeee8125f0c9afc 100644 (file)
@@ -149,7 +149,7 @@ pub fn project_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
             _ if !field.is_unsized() => return simple(),
             ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
             ty::Adt(def, _) => {
-                if def.repr.packed() {
+                if def.repr().packed() {
                     // FIXME(eddyb) generalize the adjustment when we
                     // start supporting packing to larger alignments.
                     assert_eq!(self.layout.align.abi.bytes(), 1);
index c49c5ecac267607290081dee62f6264761fcba78..6fd7f707e7e5d4813805e892f394e16a33cc73be 100644 (file)
@@ -105,13 +105,13 @@ fn const_to_valtree_inner<'tcx>(
         ty::Array(_, len) => branches(usize::try_from(len.eval_usize(ecx.tcx.tcx, ecx.param_env)).unwrap(), None),
 
         ty::Adt(def, _) => {
-            if def.variants.is_empty() {
+            if def.variants().is_empty() {
                 bug!("uninhabited types should have errored and never gotten converted to valtree")
             }
 
             let variant = ecx.read_discriminant(&place.into()).unwrap().1;
 
-            branches(def.variants[variant].fields.len(), def.is_enum().then_some(variant))
+            branches(def.variant(variant).fields.len(), def.is_enum().then_some(variant))
         }
 
         ty::Never
@@ -150,11 +150,11 @@ pub(crate) fn try_destructure_const<'tcx>(
         // Checks if we have any variants, to avoid downcasting to a non-existing variant (when
         // there are no variants `read_discriminant` successfully returns a non-existing variant
         // index).
-        ty::Adt(def, _) if def.variants.is_empty() => throw_ub!(Unreachable),
+        ty::Adt(def, _) if def.variants().is_empty() => throw_ub!(Unreachable),
         ty::Adt(def, _) => {
             let variant = ecx.read_discriminant(&op)?.1;
             let down = ecx.operand_downcast(&op, variant)?;
-            (def.variants[variant].fields.len(), Some(variant), down)
+            (def.variant(variant).fields.len(), Some(variant), down)
         }
         ty::Tuple(substs) => (substs.len(), None, op),
         _ => bug!("cannot destructure constant {:?}", val),
index fa8151a1f3c3df9d0623b910f01d8a28d5f36892..9f507bface221766697db7bdf426e4a18099ecfa 100644 (file)
@@ -174,7 +174,7 @@ fn visit_aggregate(
         }
 
         if let Some(def) = mplace.layout.ty.ty_adt_def() {
-            if Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() {
+            if Some(def.did()) == self.ecx.tcx.lang_items().unsafe_cell_type() {
                 // We are crossing over an `UnsafeCell`, we can mutate again. This means that
                 // References we encounter inside here are interned as pointing to mutable
                 // allocations.
index 715b174491bcbc524921d082b028a17b3b1cb487..5eff7d693c5a6dfe2bdc5c40aadca9f6159835f7 100644 (file)
@@ -73,7 +73,9 @@ fn numeric_intrinsic<Tag>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<T
         }
         sym::variant_count => match tp_ty.kind() {
             // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
-            ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
+            ty::Adt(ref adt, _) => {
+                ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx)
+            }
             ty::Projection(_)
             | ty::Opaque(_, _)
             | ty::Param(_)
@@ -307,53 +309,57 @@ pub fn emulate_intrinsic(
                 self.write_pointer(offset_ptr, dest)?;
             }
             sym::ptr_offset_from => {
-                let a = self.read_immediate(&args[0])?.to_scalar()?;
-                let b = self.read_immediate(&args[1])?.to_scalar()?;
+                let a = self.read_pointer(&args[0])?;
+                let b = self.read_pointer(&args[1])?;
 
                 // Special case: if both scalars are *equal integers*
                 // and not null, we pretend there is an allocation of size 0 right there,
                 // and their offset is 0. (There's never a valid object at null, making it an
                 // exception from the exception.)
                 // This is the dual to the special exception for offset-by-0
-                // in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`).
-                //
-                // Control flow is weird because we cannot early-return (to reach the
-                // `go_to_block` at the end).
-                let done = if let (Ok(a), Ok(b)) = (a.try_to_int(), b.try_to_int()) {
-                    let a = a.try_to_machine_usize(*self.tcx).unwrap();
-                    let b = b.try_to_machine_usize(*self.tcx).unwrap();
-                    if a == b && a != 0 {
+                // in the inbounds pointer offset operation (see `ptr_offset_inbounds` below).
+                match (self.memory.ptr_try_get_alloc(a), self.memory.ptr_try_get_alloc(b)) {
+                    (Err(a), Err(b)) if a == b && a != 0 => {
+                        // Both are the same non-null integer.
                         self.write_scalar(Scalar::from_machine_isize(0, self), dest)?;
-                        true
-                    } else {
-                        false
                     }
-                } else {
-                    false
-                };
-
-                if !done {
-                    // General case: we need two pointers.
-                    let a = self.scalar_to_ptr(a);
-                    let b = self.scalar_to_ptr(b);
-                    let (a_alloc_id, a_offset, _) = self.memory.ptr_get_alloc(a)?;
-                    let (b_alloc_id, b_offset, _) = self.memory.ptr_get_alloc(b)?;
-                    if a_alloc_id != b_alloc_id {
-                        throw_ub_format!(
-                            "ptr_offset_from cannot compute offset of pointers into different \
-                            allocations.",
-                        );
+                    (Err(offset), _) | (_, Err(offset)) => {
+                        throw_ub!(DanglingIntPointer(offset, CheckInAllocMsg::OffsetFromTest));
+                    }
+                    (Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => {
+                        // Both are pointers. They must be into the same allocation.
+                        if a_alloc_id != b_alloc_id {
+                            throw_ub_format!(
+                                "ptr_offset_from cannot compute offset of pointers into different \
+                                allocations.",
+                            );
+                        }
+                        // And they must both be valid for zero-sized accesses ("in-bounds or one past the end").
+                        self.memory.check_ptr_access_align(
+                            a,
+                            Size::ZERO,
+                            Align::ONE,
+                            CheckInAllocMsg::OffsetFromTest,
+                        )?;
+                        self.memory.check_ptr_access_align(
+                            b,
+                            Size::ZERO,
+                            Align::ONE,
+                            CheckInAllocMsg::OffsetFromTest,
+                        )?;
+
+                        // Compute offset.
+                        let usize_layout = self.layout_of(self.tcx.types.usize)?;
+                        let isize_layout = self.layout_of(self.tcx.types.isize)?;
+                        let a_offset = ImmTy::from_uint(a_offset.bytes(), usize_layout);
+                        let b_offset = ImmTy::from_uint(b_offset.bytes(), usize_layout);
+                        let (val, _overflowed, _ty) =
+                            self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
+                        let pointee_layout = self.layout_of(substs.type_at(0))?;
+                        let val = ImmTy::from_scalar(val, isize_layout);
+                        let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
+                        self.exact_div(&val, &size, dest)?;
                     }
-                    let usize_layout = self.layout_of(self.tcx.types.usize)?;
-                    let isize_layout = self.layout_of(self.tcx.types.isize)?;
-                    let a_offset = ImmTy::from_uint(a_offset.bytes(), usize_layout);
-                    let b_offset = ImmTy::from_uint(b_offset.bytes(), usize_layout);
-                    let (val, _overflowed, _ty) =
-                        self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
-                    let pointee_layout = self.layout_of(substs.type_at(0))?;
-                    let val = ImmTy::from_scalar(val, isize_layout);
-                    let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
-                    self.exact_div(&val, &size, dest)?;
                 }
             }
 
index dfc1a6e4d38e12828791fd4c39c8b7b51cf69537..447797f915caf87759028a4f16f1adec031cd0c2 100644 (file)
@@ -1,3 +1,4 @@
+use rustc_data_structures::intern::Interned;
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::DisambiguatedDefPathData;
 use rustc_middle::mir::interpret::{Allocation, ConstAllocation};
@@ -56,7 +57,7 @@ fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
             }
 
             // Types with identity (print the module path).
-            ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
             | ty::FnDef(def_id, substs)
             | ty::Opaque(def_id, substs)
             | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
index 5fe4672f17e5b2a8daa9f88273d3e10dcd650c51..6397fcaaf8d10844823f6990034488f4eeb25173 100644 (file)
@@ -388,9 +388,9 @@ pub fn check_ptr_access_align(
                 CheckInAllocMsg::DerefTest | CheckInAllocMsg::MemoryAccessTest => {
                     AllocCheck::Dereferenceable
                 }
-                CheckInAllocMsg::PointerArithmeticTest | CheckInAllocMsg::InboundsTest => {
-                    AllocCheck::Live
-                }
+                CheckInAllocMsg::PointerArithmeticTest
+                | CheckInAllocMsg::OffsetFromTest
+                | CheckInAllocMsg::InboundsTest => AllocCheck::Live,
             };
             let (size, align) = self.get_size_and_align(alloc_id, check)?;
             Ok((size, align, ()))
index fb4fe41bdbc4c31981b3007ab59cd9faf8c7a02d..2fae53bb9bdf5bc8c8db5966197c2f54e48974e6 100644 (file)
@@ -759,7 +759,7 @@ pub fn read_discriminant(
                                 .ty
                                 .ty_adt_def()
                                 .expect("tagged layout for non adt")
-                                .variants
+                                .variants()
                                 .len();
                             assert!(usize::try_from(variant_index).unwrap() < variants_len);
                             VariantIdx::from_u32(variant_index)
index 5cacab823866ad81dc7804e103ae69a625e2b183..8fad5e63baf2671c51030fb80821865cd78ea4e9 100644 (file)
@@ -267,7 +267,7 @@ fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize)
                 match layout.variants {
                     Variants::Single { index } => {
                         // Inside a variant
-                        PathElem::Field(def.variants[index].fields[field].name)
+                        PathElem::Field(def.variant(index).fields[field].name)
                     }
                     Variants::Multiple { .. } => bug!("we handled variants above"),
                 }
@@ -734,7 +734,7 @@ fn visit_variant(
         new_op: &OpTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
         let name = match old_op.layout.ty.kind() {
-            ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].name),
+            ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name),
             // Generators also have variants
             ty::Generator(..) => PathElem::GeneratorState(variant_id),
             _ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
@@ -771,7 +771,7 @@ fn visit_value(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
         // Special check preventing `UnsafeCell` in the inner part of constants
         if let Some(def) = op.layout.ty.ty_adt_def() {
             if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. }))
-                && Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type()
+                && Some(def.did()) == self.ecx.tcx.lang_items().unsafe_cell_type()
             {
                 throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
             }
index 6421ba9df0f16915ff6b3b70abe24b0234f7d2b8..4ea21b4d06d4bcd646864c1da9a3f58946c756fc 100644 (file)
@@ -71,7 +71,7 @@ pub trait Qualif {
     /// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> bool;
 }
@@ -96,12 +96,12 @@ fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         _: SubstsRef<'tcx>,
     ) -> bool {
         // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
         // It arises structurally for all other types.
-        Some(adt.did) == cx.tcx.lang_items().unsafe_cell_type()
+        Some(adt.did()) == cx.tcx.lang_items().unsafe_cell_type()
     }
 }
 
@@ -126,7 +126,7 @@ fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         _: SubstsRef<'tcx>,
     ) -> bool {
         adt.has_dtor(cx.tcx)
@@ -205,7 +205,7 @@ fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         _: SubstsRef<'tcx>,
     ) -> bool {
         adt.has_non_const_dtor(cx.tcx)
@@ -233,7 +233,7 @@ fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> bool {
         let ty = cx.tcx.mk_ty(ty::Adt(adt, substs));
index e4528b68907838120b98a9909ce029bb42cda750..fe4a726fe12a0df8481ff4f389685b2d65c83a76 100644 (file)
@@ -55,7 +55,7 @@ fn is_within_packed<'tcx, L>(
             ProjectionElem::Field(..) => {
                 let ty = place_base.ty(local_decls, tcx).ty;
                 match ty.kind() {
-                    ty::Adt(def, _) => return def.repr.pack,
+                    ty::Adt(def, _) => return def.repr().pack,
                     _ => {}
                 }
             }
index 11bb9508a1f8626ac347f33f45d7fb9ab9232630..2165989b39808e551292f3800ac5318c6e63b539 100644 (file)
@@ -132,7 +132,7 @@ pub fn call_kind<'tcx>(
             .parent(method_did)
             .filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl)
             .and_then(|did| match tcx.type_of(did).kind() {
-                ty::Adt(def, ..) => Some(def.did),
+                ty::Adt(def, ..) => Some(def.did()),
                 _ => None,
             });
         let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
index 04137086088ddef368c3844091ccebd9c90782c7..dedfd779bb416d7af3459540a860919a7b7244e9 100644 (file)
@@ -122,7 +122,7 @@ fn get_tt(&self, index: usize) -> TokenTree {
 
 /// An unzipping of `TokenTree`s... see the `stack` field of `MatcherPos`.
 ///
-/// This is used by `inner_parse_loop` to keep track of delimited submatchers that we have
+/// This is used by `parse_tt_inner` to keep track of delimited submatchers that we have
 /// descended into.
 #[derive(Clone)]
 struct MatcherTtFrame<'tt> {
@@ -439,9 +439,8 @@ fn n_rec<I: Iterator<Item = NamedMatch>>(
                 }
                 Occupied(..) => return Err((sp, format!("duplicated bind name: {}", bind_name))),
             },
-            // FIXME(c410-f3r) MetaVar and MetaVarExpr should be handled instead of being ignored
-            // https://github.com/rust-lang/rust/issues/9390
-            TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) | TokenTree::Token(..) => {}
+            TokenTree::Token(..) => (),
+            TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) => unreachable!(),
         }
 
         Ok(())
@@ -481,21 +480,24 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
 ///   successful execution of this function.
 /// - `next_items`: the set of newly generated items. These are used to replenish `cur_items` in
 ///   the function `parse`.
-/// - `eof_items`: the set of items that would be valid if this was the EOF.
 /// - `bb_items`: the set of items that are waiting for the black-box parser.
 /// - `token`: the current token of the parser.
 ///
 /// # Returns
 ///
-/// A `ParseResult`. Note that matches are kept track of through the items generated.
-fn inner_parse_loop<'root, 'tt>(
+/// `Some(result)` if everything is finished, `None` otherwise. Note that matches are kept track of
+/// through the items generated.
+fn parse_tt_inner<'root, 'tt>(
     sess: &ParseSess,
+    ms: &[TokenTree],
     cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
-    next_items: &mut Vec<MatcherPosHandle<'root, 'tt>>,
+    next_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
     bb_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
-    eof_items: &mut EofItems<'root, 'tt>,
     token: &Token,
-) -> Result<(), (rustc_span::Span, String)> {
+) -> Option<NamedParseResult> {
+    // Matcher positions that would be valid if the macro invocation was over now
+    let mut eof_items = EofItems::None;
+
     // Pop items from `cur_items` until it is empty.
     while let Some(mut item) = cur_items.pop() {
         // When unzipped trees end, remove them. This corresponds to backtracking out of a
@@ -522,6 +524,8 @@ fn inner_parse_loop<'root, 'tt>(
             // then we could be at the end of a sequence or at the beginning of the next
             // repetition.
             if let Some(repetition) = &item.repetition {
+                debug_assert!(matches!(item.top_elts, Tt(TokenTree::Sequence(..))));
+
                 // At this point, regardless of whether there is a separator, we should add all
                 // matches from the complete repetition of the sequence to the shared, top-level
                 // `matches` list (actually, `up.matches`, which could itself not be the top-level,
@@ -565,7 +569,7 @@ fn inner_parse_loop<'root, 'tt>(
             } else {
                 // If we are not in a repetition, then being at the end of a matcher means that we
                 // have reached the potential end of the input.
-                *eof_items = match eof_items {
+                eof_items = match eof_items {
                     EofItems::None => EofItems::One(item),
                     EofItems::One(_) | EofItems::Multiple => EofItems::Multiple,
                 }
@@ -613,7 +617,7 @@ fn inner_parse_loop<'root, 'tt>(
                 // We need to match a metavar (but the identifier is invalid)... this is an error
                 TokenTree::MetaVarDecl(span, _, None) => {
                     if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
-                        return Err((span, "missing fragment specifier".to_string()));
+                        return Some(Error(span, "missing fragment specifier".to_string()));
                     }
                 }
 
@@ -655,13 +659,36 @@ fn inner_parse_loop<'root, 'tt>(
                 // rules. NOTE that this is not necessarily an error unless _all_ items in
                 // `cur_items` end up doing this. There may still be some other matchers that do
                 // end up working out.
-                TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) => {}
+                TokenTree::Token(..) => {}
+
+                TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) => unreachable!(),
             }
         }
     }
 
-    // Yay a successful parse (so far)!
-    Ok(())
+    // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
+    // either the parse is ambiguous (which should never happen) or there is a syntax error.
+    if *token == token::Eof {
+        Some(match eof_items {
+            EofItems::One(mut eof_item) => {
+                let matches =
+                    eof_item.matches.iter_mut().map(|dv| Lrc::make_mut(dv).pop().unwrap());
+                nameize(sess, ms, matches)
+            }
+            EofItems::Multiple => {
+                Error(token.span, "ambiguity: multiple successful parses".to_string())
+            }
+            EofItems::None => Failure(
+                Token::new(
+                    token::Eof,
+                    if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() },
+                ),
+                "missing tokens in macro arguments",
+            ),
+        })
+    } else {
+        None
+    }
 }
 
 /// Use the given sequence of token trees (`ms`) as a matcher. Match the token
@@ -672,7 +699,7 @@ pub(super) fn parse_tt(
     macro_name: Ident,
 ) -> NamedParseResult {
     // A queue of possible matcher positions. We initialize it with the matcher position in which
-    // the "dot" is before the first token of the first token tree in `ms`. `inner_parse_loop` then
+    // the "dot" is before the first token of the first token tree in `ms`. `parse_tt_inner` then
     // processes all of these possible matcher positions and produces possible next positions into
     // `next_items`. After some post-processing, the contents of `next_items` replenish `cur_items`
     // and we start over again.
@@ -681,135 +708,118 @@ pub(super) fn parse_tt(
     // there are frequently *no* others! -- are allocated on the heap.
     let mut initial = MatcherPos::new(ms);
     let mut cur_items = smallvec![MatcherPosHandle::Ref(&mut initial)];
-    let mut next_items = Vec::new();
 
     loop {
-        assert!(next_items.is_empty());
+        let mut next_items = SmallVec::new();
 
         // Matcher positions black-box parsed by parser.rs (`parser`)
         let mut bb_items = SmallVec::new();
 
-        // Matcher positions that would be valid if the macro invocation was over now
-        let mut eof_items = EofItems::None;
-
         // Process `cur_items` until either we have finished the input or we need to get some
         // parsing from the black-box parser done. The result is that `next_items` will contain a
         // bunch of possible next matcher positions in `next_items`.
-        match inner_parse_loop(
+        if let Some(result) = parse_tt_inner(
             parser.sess,
+            ms,
             &mut cur_items,
             &mut next_items,
             &mut bb_items,
-            &mut eof_items,
             &parser.token,
         ) {
-            Ok(()) => {}
-            Err((sp, msg)) => return Error(sp, msg),
+            return result;
         }
 
-        // inner parse loop handled all cur_items, so it's empty
+        // `parse_tt_inner` handled all cur_items, so it's empty.
         assert!(cur_items.is_empty());
 
-        // We need to do some post processing after the `inner_parse_loop`.
+        // We need to do some post processing after the `parse_tt_inner`.
         //
         // Error messages here could be improved with links to original rules.
 
-        // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
-        // either the parse is ambiguous (which should never happen) or there is a syntax error.
-        if parser.token == token::Eof {
-            return match eof_items {
-                EofItems::One(mut eof_item) => {
-                    let matches =
-                        eof_item.matches.iter_mut().map(|dv| Lrc::make_mut(dv).pop().unwrap());
-                    nameize(parser.sess, ms, matches)
-                }
-                EofItems::Multiple => {
-                    Error(parser.token.span, "ambiguity: multiple successful parses".to_string())
-                }
-                EofItems::None => Failure(
-                    Token::new(
-                        token::Eof,
-                        if parser.token.span.is_dummy() {
-                            parser.token.span
-                        } else {
-                            parser.token.span.shrink_to_hi()
-                        },
-                    ),
-                    "missing tokens in macro arguments",
-                ),
-            };
-        }
-        // Performance hack: `eof_items` may share matchers via `Rc` with other things that we want
-        // to modify. Dropping `eof_items` now may drop these refcounts to 1, preventing an
-        // unnecessary implicit clone later in `Rc::make_mut`.
-        drop(eof_items);
-
-        // If there are no possible next positions AND we aren't waiting for the black-box parser,
-        // then there is a syntax error.
-        if bb_items.is_empty() && next_items.is_empty() {
-            return Failure(parser.token.clone(), "no rules expected this token in macro call");
-        }
+        match (next_items.len(), bb_items.len()) {
+            (0, 0) => {
+                // There are no possible next positions AND we aren't waiting for the black-box
+                // parser: syntax error.
+                return Failure(parser.token.clone(), "no rules expected this token in macro call");
+            }
 
-        if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 {
-            // We need to call out to parse some rust nonterminal (black-box) parser. But something
-            // is wrong, because there is not EXACTLY ONE of these.
-            let nts = bb_items
-                .iter()
-                .map(|item| match item.top_elts.get_tt(item.idx) {
-                    TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind),
-                    _ => panic!(),
-                })
-                .collect::<Vec<String>>()
-                .join(" or ");
-
-            return Error(
-                parser.token.span,
-                format!(
-                    "local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}",
-                    match next_items.len() {
-                        0 => format!("built-in NTs {}.", nts),
-                        1 => format!("built-in NTs {} or 1 other option.", nts),
-                        n => format!("built-in NTs {} or {} other options.", nts, n),
-                    }
-                ),
-            );
-        }
+            (_, 0) => {
+                // Dump all possible `next_items` into `cur_items` for the next iteration. Then
+                // process the next token.
+                cur_items.extend(next_items.drain(..));
+                parser.to_mut().bump();
+            }
 
-        if !next_items.is_empty() {
-            // Dump all possible `next_items` into `cur_items` for the next iteration. Then process
-            // the next token.
-            cur_items.extend(next_items.drain(..));
-            parser.to_mut().bump();
-        } else {
-            // Finally, we have the case where we need to call the black-box parser to get some
-            // nonterminal.
-            assert_eq!(bb_items.len(), 1);
-
-            let mut item = bb_items.pop().unwrap();
-            if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) {
-                let match_cur = item.match_cur;
-                // We use the span of the metavariable declaration to determine any
-                // edition-specific matching behavior for non-terminals.
-                let nt = match parser.to_mut().parse_nonterminal(kind) {
-                    Err(mut err) => {
-                        err.span_label(
-                            span,
-                            format!("while parsing argument for this `{}` macro fragment", kind),
-                        )
-                        .emit();
-                        return ErrorReported;
-                    }
-                    Ok(nt) => nt,
-                };
-                item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
-                item.idx += 1;
-                item.match_cur += 1;
-            } else {
-                unreachable!()
+            (0, 1) => {
+                // We need to call the black-box parser to get some nonterminal.
+                let mut item = bb_items.pop().unwrap();
+                if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx)
+                {
+                    let match_cur = item.match_cur;
+                    // We use the span of the metavariable declaration to determine any
+                    // edition-specific matching behavior for non-terminals.
+                    let nt = match parser.to_mut().parse_nonterminal(kind) {
+                        Err(mut err) => {
+                            err.span_label(
+                                span,
+                                format!("while parsing argument for this `{kind}` macro fragment"),
+                            )
+                            .emit();
+                            return ErrorReported;
+                        }
+                        Ok(nt) => nt,
+                    };
+                    item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
+                    item.idx += 1;
+                    item.match_cur += 1;
+                } else {
+                    unreachable!()
+                }
+                cur_items.push(item);
+            }
+
+            (_, _) => {
+                // We need to call the black-box parser to get some nonterminal, but something is
+                // wrong.
+                return bb_items_ambiguity_error(
+                    macro_name,
+                    next_items,
+                    bb_items,
+                    parser.token.span,
+                );
             }
-            cur_items.push(item);
         }
 
         assert!(!cur_items.is_empty());
     }
 }
+
+fn bb_items_ambiguity_error<'root, 'tt>(
+    macro_name: Ident,
+    next_items: SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
+    bb_items: SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
+    token_span: rustc_span::Span,
+) -> NamedParseResult {
+    let nts = bb_items
+        .iter()
+        .map(|item| match item.top_elts.get_tt(item.idx) {
+            TokenTree::MetaVarDecl(_, bind, Some(kind)) => {
+                format!("{} ('{}')", kind, bind)
+            }
+            _ => panic!(),
+        })
+        .collect::<Vec<String>>()
+        .join(" or ");
+
+    Error(
+        token_span,
+        format!(
+            "local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}",
+            match next_items.len() {
+                0 => format!("built-in NTs {}.", nts),
+                1 => format!("built-in NTs {} or 1 other option.", nts),
+                n => format!("built-in NTs {} or {} other options.", nts, n),
+            }
+        ),
+    )
+}
index b8d8394754134ca6f63417e0d35229ed039da1ff..387d5895e24d728299a40110d099c021fc035450 100644 (file)
@@ -1,15 +1,15 @@
 use crate::base::ExtCtxt;
-use crate::mbe;
 use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
-
+use crate::mbe::{self, MetaVarExpr};
 use rustc_ast::mut_visit::{self, MutVisitor};
-use rustc_ast::token::{self, NtTT, Token};
+use rustc_ast::token::{self, NtTT, Token, TokenKind};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndSpacing};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{pluralize, PResult};
+use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
 use rustc_span::hygiene::{LocalExpnId, Transparency};
-use rustc_span::symbol::MacroRulesNormalizedIdent;
+use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
 use rustc_span::Span;
 
 use smallvec::{smallvec, SmallVec};
@@ -411,13 +411,150 @@ fn lockstep_iter_size(
     }
 }
 
+/// Used solely by the `count` meta-variable expression, counts the outer-most repetitions at a
+/// given optional nested depth.
+///
+/// For example, a macro parameter of `$( { $( $foo:ident ),* } )*` called with `{ a, b } { c }`:
+///
+/// * `[ $( ${count(foo)} ),* ]` will return [2, 1] with a, b = 2 and c = 1
+/// * `[ $( ${count(foo, 0)} ),* ]` will be the same as `[ $( ${count(foo)} ),* ]`
+/// * `[ $( ${count(foo, 1)} ),* ]` will return an error because `${count(foo, 1)}` is
+///   declared inside a single repetition and the index `1` implies two nested repetitions.
+fn count_repetitions<'a>(
+    cx: &ExtCtxt<'a>,
+    depth_opt: Option<usize>,
+    mut matched: &NamedMatch,
+    repeats: &[(usize, usize)],
+    sp: &DelimSpan,
+) -> PResult<'a, usize> {
+    // Recursively count the number of matches in `matched` at given depth
+    // (or at the top-level of `matched` if no depth is given).
+    fn count<'a>(
+        cx: &ExtCtxt<'a>,
+        declared_lhs_depth: usize,
+        depth_opt: Option<usize>,
+        matched: &NamedMatch,
+        sp: &DelimSpan,
+    ) -> PResult<'a, usize> {
+        match matched {
+            MatchedNonterminal(_) => {
+                if declared_lhs_depth == 0 {
+                    return Err(cx.struct_span_err(
+                        sp.entire(),
+                        "`count` can not be placed inside the inner-most repetition",
+                    ));
+                }
+                match depth_opt {
+                    None => Ok(1),
+                    Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")),
+                }
+            }
+            MatchedSeq(ref named_matches) => {
+                let new_declared_lhs_depth = declared_lhs_depth + 1;
+                match depth_opt {
+                    None => named_matches
+                        .iter()
+                        .map(|elem| count(cx, new_declared_lhs_depth, None, elem, sp))
+                        .sum(),
+                    Some(0) => Ok(named_matches.len()),
+                    Some(depth) => named_matches
+                        .iter()
+                        .map(|elem| count(cx, new_declared_lhs_depth, Some(depth - 1), elem, sp))
+                        .sum(),
+                }
+            }
+        }
+    }
+    // `repeats` records all of the nested levels at which we are currently
+    // matching meta-variables. The meta-var-expr `count($x)` only counts
+    // matches that occur in this "subtree" of the `NamedMatch` where we
+    // are currently transcribing, so we need to descend to that subtree
+    // before we start counting. `matched` contains the various levels of the
+    // tree as we descend, and its final value is the subtree we are currently at.
+    for &(idx, _) in repeats {
+        if let MatchedSeq(ref ads) = matched {
+            matched = &ads[idx];
+        }
+    }
+    count(cx, 0, depth_opt, matched, sp)
+}
+
+/// Returns a `NamedMatch` item declared on the RHS given an arbitrary [Ident]
+fn matched_from_ident<'ctx, 'interp, 'rslt>(
+    cx: &ExtCtxt<'ctx>,
+    ident: Ident,
+    interp: &'interp FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
+) -> PResult<'ctx, &'rslt NamedMatch>
+where
+    'interp: 'rslt,
+{
+    let span = ident.span;
+    let key = MacroRulesNormalizedIdent::new(ident);
+    interp.get(&key).ok_or_else(|| {
+        cx.struct_span_err(
+            span,
+            &format!("variable `{}` is not recognized in meta-variable expression", key),
+        )
+    })
+}
+
+/// Used by meta-variable expressions when an user input is out of the actual declared bounds. For
+/// example, index(999999) in an repetition of only three elements.
+fn out_of_bounds_err<'a>(
+    cx: &ExtCtxt<'a>,
+    max: usize,
+    span: Span,
+    ty: &str,
+) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+    cx.struct_span_err(span, &format!("{ty} depth must be less than {max}"))
+}
+
 fn transcribe_metavar_expr<'a>(
-    _cx: &ExtCtxt<'a>,
-    _expr: mbe::MetaVarExpr,
-    _interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
-    _repeats: &[(usize, usize)],
-    _result: &mut Vec<TreeAndSpacing>,
-    _sp: &DelimSpan,
+    cx: &ExtCtxt<'a>,
+    expr: MetaVarExpr,
+    interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
+    repeats: &[(usize, usize)],
+    result: &mut Vec<TreeAndSpacing>,
+    sp: &DelimSpan,
 ) -> PResult<'a, ()> {
+    match expr {
+        MetaVarExpr::Count(original_ident, depth_opt) => {
+            let matched = matched_from_ident(cx, original_ident, interp)?;
+            let count = count_repetitions(cx, depth_opt, matched, &repeats, sp)?;
+            let tt = TokenTree::token(
+                TokenKind::lit(token::Integer, sym::integer(count), None),
+                sp.entire(),
+            );
+            result.push(tt.into());
+        }
+        MetaVarExpr::Ignore(original_ident) => {
+            // Used to ensure that `original_ident` is present in the LHS
+            let _ = matched_from_ident(cx, original_ident, interp)?;
+        }
+        MetaVarExpr::Index(depth) => match repeats.iter().nth_back(depth) {
+            Some((index, _)) => {
+                result.push(
+                    TokenTree::token(
+                        TokenKind::lit(token::Integer, sym::integer(*index), None),
+                        sp.entire(),
+                    )
+                    .into(),
+                );
+            }
+            None => return Err(out_of_bounds_err(cx, repeats.len(), sp.entire(), "index")),
+        },
+        MetaVarExpr::Length(depth) => match repeats.iter().nth_back(depth) {
+            Some((_, length)) => {
+                result.push(
+                    TokenTree::token(
+                        TokenKind::lit(token::Integer, sym::integer(*length), None),
+                        sp.entire(),
+                    )
+                    .into(),
+                );
+            }
+            None => return Err(out_of_bounds_err(cx, repeats.len(), sp.entire(), "length")),
+        },
+    }
     Ok(())
 }
index bf4882d4595730537318ffde91e49cdb1d86e048..abc25d51776f396ff54c43b1626e44d8b57ff9de 100644 (file)
@@ -582,7 +582,7 @@ fn path_generic_args(
                 if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) =
                     (exp_found.expected.kind(), exp_found.found.kind())
                 {
-                    report_path_match(err, exp_adt.did, found_adt.did);
+                    report_path_match(err, exp_adt.did(), found_adt.did());
                 }
             }
             TypeError::Traits(ref exp_found) => {
@@ -914,7 +914,7 @@ fn cmp_type_arg(
                 return Some(());
             }
             if let ty::Adt(def, _) = ta.kind() {
-                let path_ = self.tcx.def_path_str(def.did);
+                let path_ = self.tcx.def_path_str(def.did());
                 if path_ == other_path {
                     self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
                     return Some(());
@@ -1126,12 +1126,14 @@ fn push_ty_ref<'tcx>(
         // process starts here
         match (t1.kind(), t2.kind()) {
             (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
-                let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1);
-                let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2);
+                let did1 = def1.did();
+                let did2 = def2.did();
+                let sub_no_defaults_1 = self.strip_generic_default_params(did1, sub1);
+                let sub_no_defaults_2 = self.strip_generic_default_params(did2, sub2);
                 let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
-                let path1 = self.tcx.def_path_str(def1.did);
-                let path2 = self.tcx.def_path_str(def2.did);
-                if def1.did == def2.did {
+                let path1 = self.tcx.def_path_str(did1);
+                let path2 = self.tcx.def_path_str(did2);
+                if did1 == did2 {
                     // Easy case. Replace same types with `_` to shorten the output and highlight
                     // the differing ones.
                     //     let x: Foo<Bar, Qux> = y::<Foo<Quz, Qux>>();
index 16f7504cbbe588a8ab07ef707d3af7d7fcff4acd..a9a92fdbd6448c9cb7c92c3f1bbe8e026acb256c 100644 (file)
@@ -958,7 +958,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         let t = match t.kind() {
             // We'll hide this type only if all its type params are hidden as well.
             ty::Adt(def, substs) => {
-                let generics = self.tcx().generics_of(def.did);
+                let generics = self.tcx().generics_of(def.did());
                 // Account for params with default values, like `Vec`, where we
                 // want to show `Vec<T>`, not `Vec<T, _>`. If we replaced that
                 // subst, then we'd get the incorrect output, so we passthrough.
@@ -985,7 +985,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
                 };
                 if self.level == 1 || substs.iter().any(should_keep) {
                     let substs = self.tcx().intern_substs(&substs[..]);
-                    self.tcx().mk_ty(ty::Adt(def, substs))
+                    self.tcx().mk_ty(ty::Adt(*def, substs))
                 } else {
                     self.tcx().ty_error()
                 }
index b6b73ba45391ea1d3d19e3b999bdbf634b8855e6..53ad837434985719f9c8565fedbec1baddfa6993 100644 (file)
@@ -658,7 +658,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_
             let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
             let impl_ty = cx.tcx.type_of(parent);
             let outerdef = match impl_ty.kind() {
-                ty::Adt(def, _) => Some(def.did),
+                ty::Adt(def, _) => Some(def.did()),
                 ty::Foreign(def_id) => Some(*def_id),
                 _ => None,
             };
@@ -841,7 +841,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
             let mut impls = LocalDefIdSet::default();
             cx.tcx.for_each_impl(debug, |d| {
                 if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
-                    if let Some(def_id) = ty_def.did.as_local() {
+                    if let Some(def_id) = ty_def.did().as_local() {
                         impls.insert(def_id);
                     }
                 }
@@ -2535,9 +2535,9 @@ fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<InitK
 
         /// Test if this enum has several actually "existing" variants.
         /// Zero-sized uninhabited variants do not always have a tag assigned and thus do not "exist".
-        fn is_multi_variant(adt: &ty::AdtDef) -> bool {
+        fn is_multi_variant<'tcx>(adt: ty::AdtDef<'tcx>) -> bool {
             // As an approximation, we only count dataless variants. Those are definitely inhabited.
-            let existing_variants = adt.variants.iter().filter(|v| v.fields.is_empty()).count();
+            let existing_variants = adt.variants().iter().filter(|v| v.fields.is_empty()).count();
             existing_variants > 1
         }
 
@@ -2571,7 +2571,7 @@ fn ty_find_init_error<'tcx>(
                 Adt(adt_def, substs) if !adt_def.is_union() => {
                     // First check if this ADT has a layout attribute (like `NonNull` and friends).
                     use std::ops::Bound;
-                    match tcx.layout_scalar_valid_range(adt_def.did) {
+                    match tcx.layout_scalar_valid_range(adt_def.did()) {
                         // We exploit here that `layout_scalar_valid_range` will never
                         // return `Bound::Excluded`.  (And we have tests checking that we
                         // handle the attribute correctly.)
@@ -2592,12 +2592,12 @@ fn ty_find_init_error<'tcx>(
                         _ => {}
                     }
                     // Now, recurse.
-                    match adt_def.variants.len() {
+                    match adt_def.variants().len() {
                         0 => Some(("enums with no variants have no valid value".to_string(), None)),
                         1 => {
                             // Struct, or enum with exactly one variant.
                             // Proceed recursively, check all fields.
-                            let variant = &adt_def.variants[VariantIdx::from_u32(0)];
+                            let variant = &adt_def.variant(VariantIdx::from_u32(0));
                             variant.fields.iter().find_map(|field| {
                                 ty_find_init_error(tcx, field.ty(tcx, substs), init).map(
                                     |(mut msg, span)| {
@@ -2622,8 +2622,8 @@ fn ty_find_init_error<'tcx>(
                         }
                         // Multi-variant enum.
                         _ => {
-                            if init == InitKind::Uninit && is_multi_variant(adt_def) {
-                                let span = tcx.def_span(adt_def.did);
+                            if init == InitKind::Uninit && is_multi_variant(*adt_def) {
+                                let span = tcx.def_span(adt_def.did());
                                 Some((
                                     "enums have to be initialized to a variant".to_string(),
                                     Some(span),
@@ -2819,15 +2819,15 @@ fn structurally_same_type_impl<'tcx>(
                 let mut ty = ty;
                 loop {
                     if let ty::Adt(def, substs) = *ty.kind() {
-                        let is_transparent = def.subst(tcx, substs).repr.transparent();
-                        let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, &def);
+                        let is_transparent = def.subst(tcx, substs).repr().transparent();
+                        let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, def);
                         debug!(
                             "non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
                             ty, is_transparent, is_non_null
                         );
                         if is_transparent && !is_non_null {
-                            debug_assert!(def.variants.len() == 1);
-                            let v = &def.variants[VariantIdx::new(0)];
+                            debug_assert!(def.variants().len() == 1);
+                            let v = &def.variant(VariantIdx::new(0));
                             ty = transparent_newtype_field(tcx, v)
                                 .expect(
                                     "single-variant transparent structure with zero-sized field",
@@ -2892,8 +2892,8 @@ fn structurally_same_type_impl<'tcx>(
                             }
 
                             // Grab a flattened representation of all fields.
-                            let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());
-                            let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());
+                            let a_fields = a_def.variants().iter().flat_map(|v| v.fields.iter());
+                            let b_fields = b_def.variants().iter().flat_map(|v| v.fields.iter());
 
                             // Perform a structural comparison for each field.
                             a_fields.eq_by(
index b892e520d3bdeb4194fef8342496f676752d3330..d3c019ad70e3cf598f319ebb52c464134cde2b2b 100644 (file)
@@ -1050,7 +1050,7 @@ fn path_qualified(
             ) -> Result<Self::Path, Self::Error> {
                 if trait_ref.is_none() {
                     if let ty::Adt(def, substs) = self_ty.kind() {
-                        return self.print_def_path(def.did, substs);
+                        return self.print_def_path(def.did(), substs);
                     }
                 }
 
index 5078c240ec753b635e13a1e87916e81334c68b12..27d44da6dfc389d6d211cc797e143f638c0eadfe 100644 (file)
@@ -202,7 +202,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
             Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
                     if let Some(name @ (sym::Ty | sym::TyCtxt)) =
-                        cx.tcx.get_diagnostic_name(adt.did)
+                        cx.tcx.get_diagnostic_name(adt.did())
                     {
                         // NOTE: This path is currently unreachable as `Ty<'tcx>` is
                         // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
index ae9368347543ad4270cdc1cb9a54c9575f9d7d3a..b6a45676a309373b8ff56ffd7d4800e01d42cbb4 100644 (file)
@@ -84,9 +84,9 @@ fn lint_cstring_as_ptr(
 ) {
     let source_type = cx.typeck_results().expr_ty(source);
     if let ty::Adt(def, substs) = source_type.kind() {
-        if cx.tcx.is_diagnostic_item(sym::Result, def.did) {
+        if cx.tcx.is_diagnostic_item(sym::Result, def.did()) {
             if let ty::Adt(adt, _) = substs.type_at(0).kind() {
-                if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did) {
+                if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) {
                     cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
                         let mut diag = diag
                             .build("getting the inner pointer of a temporary `CString`");
index 3130d57c2a9716233247f52df79fbd07dab29961..f21f25c35847eb0b6dc0209271ac5c5f27aa0c20 100644 (file)
@@ -149,7 +149,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 ty::Ref(_, r, _) if *r.kind() == ty::Str,
             ) || matches!(
                 ty.ty_adt_def(),
-                Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did),
+                Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did()),
             );
 
             let (suggest_display, suggest_debug) = cx.tcx.infer_ctxt().enter(|infcx| {
index c47fdc063a96544d22a4f2dbac7f0dcc1d4ab517..2c8b41d7214031459287c74e181eb42fcf310168 100644 (file)
@@ -57,8 +57,8 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
             }
             Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
-                    if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) {
-                        return Some(cx.tcx.def_path_str_with_substs(adt.did, substs));
+                    if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
+                        return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs));
                     }
                 }
             }
index d4dac640cc7e189d71de027375b15d318f2c8516..ed5578c754dd55c942e96f4e2db5bbc2dcef358b 100644 (file)
@@ -667,8 +667,8 @@ enum FfiResult<'tcx> {
     FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> },
 }
 
-crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: &ty::AdtDef) -> bool {
-    tcx.get_attrs(def.did).iter().any(|a| a.has_name(sym::rustc_nonnull_optimization_guaranteed))
+crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
+    tcx.get_attrs(def.did()).iter().any(|a| a.has_name(sym::rustc_nonnull_optimization_guaranteed))
 }
 
 /// `repr(transparent)` structs can have a single non-ZST field, this function returns that
@@ -692,8 +692,8 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
         ty::FnPtr(_) => true,
         ty::Ref(..) => true,
         ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
-        ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => {
-            let marked_non_null = nonnull_optimization_guaranteed(tcx, &def);
+        ty::Adt(def, substs) if def.repr().transparent() && !def.is_union() => {
+            let marked_non_null = nonnull_optimization_guaranteed(tcx, *def);
 
             if marked_non_null {
                 return true;
@@ -701,11 +701,11 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
 
             // Types with a `#[repr(no_niche)]` attribute have their niche hidden.
             // The attribute is used by the UnsafeCell for example (the only use so far).
-            if def.repr.hide_niche() {
+            if def.repr().hide_niche() {
                 return false;
             }
 
-            def.variants
+            def.variants()
                 .iter()
                 .filter_map(|variant| transparent_newtype_field(cx.tcx, variant))
                 .any(|field| ty_is_known_nonnull(cx, field.ty(tcx, substs), mode))
@@ -721,8 +721,10 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
     Some(match *ty.kind() {
         ty::Adt(field_def, field_substs) => {
             let inner_field_ty = {
-                let first_non_zst_ty =
-                    field_def.variants.iter().filter_map(|v| transparent_newtype_field(cx.tcx, v));
+                let first_non_zst_ty = field_def
+                    .variants()
+                    .iter()
+                    .filter_map(|v| transparent_newtype_field(cx.tcx, v));
                 debug_assert_eq!(
                     first_non_zst_ty.clone().count(),
                     1,
@@ -771,7 +773,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
 ) -> Option<Ty<'tcx>> {
     debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
     if let ty::Adt(ty_def, substs) = ty.kind() {
-        let field_ty = match &ty_def.variants.raw[..] {
+        let field_ty = match &ty_def.variants().raw[..] {
             [var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) {
                 ([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
                 _ => return None,
@@ -845,13 +847,13 @@ fn check_variant_for_ffi(
         &self,
         cache: &mut FxHashSet<Ty<'tcx>>,
         ty: Ty<'tcx>,
-        def: &ty::AdtDef,
+        def: ty::AdtDef<'tcx>,
         variant: &ty::VariantDef,
         substs: SubstsRef<'tcx>,
     ) -> FfiResult<'tcx> {
         use FfiResult::*;
 
-        if def.repr.transparent() {
+        if def.repr().transparent() {
             // Can assume that at most one field is not a ZST, so only check
             // that field's type for FFI-safety.
             if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
@@ -925,7 +927,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
                     AdtKind::Struct | AdtKind::Union => {
                         let kind = if def.is_struct() { "struct" } else { "union" };
 
-                        if !def.repr.c() && !def.repr.transparent() {
+                        if !def.repr().c() && !def.repr().transparent() {
                             return FfiUnsafe {
                                 ty,
                                 reason: format!("this {} has unspecified layout", kind),
@@ -939,7 +941,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
 
                         let is_non_exhaustive =
                             def.non_enum_variant().is_field_list_non_exhaustive();
-                        if is_non_exhaustive && !def.did.is_local() {
+                        if is_non_exhaustive && !def.did().is_local() {
                             return FfiUnsafe {
                                 ty,
                                 reason: format!("this {} is non-exhaustive", kind),
@@ -958,14 +960,15 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
                         self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), substs)
                     }
                     AdtKind::Enum => {
-                        if def.variants.is_empty() {
+                        if def.variants().is_empty() {
                             // Empty enums are okay... although sort of useless.
                             return FfiSafe;
                         }
 
                         // Check for a repr() attribute to specify the size of the
                         // discriminant.
-                        if !def.repr.c() && !def.repr.transparent() && def.repr.int.is_none() {
+                        if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none()
+                        {
                             // Special-case types like `Option<extern fn()>`.
                             if repr_nullable_ptr(self.cx, ty, self.mode).is_none() {
                                 return FfiUnsafe {
@@ -981,7 +984,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
                             }
                         }
 
-                        if def.is_variant_list_non_exhaustive() && !def.did.is_local() {
+                        if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
                             return FfiUnsafe {
                                 ty,
                                 reason: "this enum is non-exhaustive".into(),
@@ -990,7 +993,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
                         }
 
                         // Check the contained variants.
-                        for variant in &def.variants {
+                        for variant in def.variants() {
                             let is_non_exhaustive = variant.is_field_list_non_exhaustive();
                             if is_non_exhaustive && !variant.def_id.is_local() {
                                 return FfiUnsafe {
@@ -1161,7 +1164,7 @@ fn emit_ffi_unsafe_type_lint(
             }
             diag.note(note);
             if let ty::Adt(def, _) = ty.kind() {
-                if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
+                if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) {
                     diag.span_note(sp, "the type is defined here");
                 }
             }
@@ -1464,9 +1467,9 @@ fn inherent_atomic_method_call<'hir>(
             && let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def()
             // skip extension traits, only lint functions from the standard library
             && cx.tcx.trait_id_of_impl(impl_did).is_none()
-            && let Some(parent) = cx.tcx.parent(adt.did)
+            && let Some(parent) = cx.tcx.parent(adt.did())
             && cx.tcx.is_diagnostic_item(sym::atomic_mod, parent)
-            && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did))
+            && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did()))
         {
             return Some((method_path.ident.name, args));
         }
index 16d222f68a3211e3a56a1435bbb5aab94fdbd68f..abe34a8a39f1470699f3dcd23cc6625b59b5b9db 100644 (file)
@@ -202,7 +202,7 @@ fn check_must_use_ty<'tcx>(
                     let descr_pre = &format!("{}boxed ", descr_pre);
                     check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len)
                 }
-                ty::Adt(def, _) => check_must_use_def(cx, def.did, span, descr_pre, descr_post),
+                ty::Adt(def, _) => check_must_use_def(cx, def.did(), span, descr_pre, descr_post),
                 ty::Opaque(def, _) => {
                     let mut has_emitted = false;
                     for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
index e5e0cce198f46078eb208d511b947e04e575008f..2e6ce7b7040f9dbc4e3ab86a008d38ea1dddfb43 100644 (file)
@@ -979,7 +979,7 @@ fn get_variant(self, kind: &EntryKind, index: DefIndex, parent_did: DefId) -> ty
         )
     }
 
-    fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
+    fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
         let kind = self.kind(item_id);
         let did = self.local_def_id(item_id);
 
index 06f73c1c91600d4a955e39c5331dc4190b3efcce..924e5f921039e18b1139305fe2ecd17fb8882ae6 100644 (file)
@@ -1029,9 +1029,9 @@ fn encode_item_type(&mut self, def_id: DefId) {
         record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
     }
 
-    fn encode_enum_variant_info(&mut self, def: &ty::AdtDef, index: VariantIdx) {
+    fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
         let tcx = self.tcx;
-        let variant = &def.variants[index];
+        let variant = &def.variant(index);
         let def_id = variant.def_id;
         debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
 
@@ -1057,9 +1057,9 @@ fn encode_enum_variant_info(&mut self, def: &ty::AdtDef, index: VariantIdx) {
         }
     }
 
-    fn encode_enum_variant_ctor(&mut self, def: &ty::AdtDef, index: VariantIdx) {
+    fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
         let tcx = self.tcx;
-        let variant = &def.variants[index];
+        let variant = &def.variant(index);
         let def_id = variant.ctor_def_id.unwrap();
         debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
 
@@ -1122,11 +1122,11 @@ fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
 
     fn encode_field(
         &mut self,
-        adt_def: &ty::AdtDef,
+        adt_def: ty::AdtDef<'tcx>,
         variant_index: VariantIdx,
         field_index: usize,
     ) {
-        let variant = &adt_def.variants[variant_index];
+        let variant = &adt_def.variant(variant_index);
         let field = &variant.fields[field_index];
 
         let def_id = field.did;
@@ -1137,7 +1137,7 @@ fn encode_field(
         self.encode_item_type(def_id);
     }
 
-    fn encode_struct_ctor(&mut self, adt_def: &ty::AdtDef, def_id: DefId) {
+    fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
         debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
         let tcx = self.tcx;
         let variant = adt_def.non_enum_variant();
@@ -1149,7 +1149,7 @@ fn encode_struct_ctor(&mut self, adt_def: &ty::AdtDef, def_id: DefId) {
             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
         };
 
-        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
+        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr()));
         self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@@ -1414,7 +1414,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                 self.encode_explicit_item_bounds(def_id);
                 EntryKind::OpaqueTy
             }
-            hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr),
+            hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr()),
             hir::ItemKind::Struct(ref struct_def, _) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 let variant = adt_def.non_enum_variant();
@@ -1433,7 +1433,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                         ctor,
                         is_non_exhaustive: variant.is_field_list_non_exhaustive(),
                     }),
-                    adt_def.repr,
+                    adt_def.repr(),
                 )
             }
             hir::ItemKind::Union(..) => {
@@ -1447,7 +1447,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                         ctor: None,
                         is_non_exhaustive: variant.is_field_list_non_exhaustive(),
                     }),
-                    adt_def.repr,
+                    adt_def.repr(),
                 )
             }
             hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
@@ -1500,7 +1500,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
         // FIXME(eddyb) there should be a nicer way to do this.
         match item.kind {
             hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <-
-                self.tcx.adt_def(def_id).variants.iter().map(|v| {
+                self.tcx.adt_def(def_id).variants().iter().map(|v| {
                     assert!(v.def_id.is_local());
                     v.def_id.index
                 })
@@ -1926,8 +1926,8 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
 }
 
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
-    fn encode_fields(&mut self, adt_def: &ty::AdtDef) {
-        for (variant_index, variant) in adt_def.variants.iter_enumerated() {
+    fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
+        for (variant_index, variant) in adt_def.variants().iter_enumerated() {
             for (field_index, _field) in variant.fields.iter().enumerate() {
                 self.encode_field(adt_def, variant_index, field_index);
             }
@@ -1991,7 +1991,7 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
                 let def = self.tcx.adt_def(item.def_id.to_def_id());
                 self.encode_fields(def);
 
-                for (i, variant) in def.variants.iter_enumerated() {
+                for (i, variant) in def.variants().iter_enumerated() {
                     self.encode_enum_variant_info(def, i);
 
                     if let Some(_ctor_def_id) = variant.ctor_def_id {
index 825dc79129d267a2eb7342432c112106c8d85360..f6d8fc5b81f65fe182a0699e84b1a2928d4b4a43 100644 (file)
@@ -9,7 +9,7 @@ macro_rules! arena_types {
             [] layout: rustc_target::abi::LayoutS<'tcx>,
             [] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
             // AdtDef are interned and compared by address
-            [decode] adt_def: rustc_middle::ty::AdtDef,
+            [decode] adt_def: rustc_middle::ty::AdtDefData,
             [] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
             [] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
             [decode] mir: rustc_middle::mir::Body<'tcx>,
index 6124d1407026693a5755cb855478b526e11fd0ae..12fa5a13de885cdcd7037907891cce8def8271c9 100644 (file)
@@ -7,7 +7,7 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
 
 use crate::ty::TyCtxt;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir as hir;
 use rustc_hir::Node;
@@ -214,14 +214,14 @@ pub struct ScopeTree {
     /// conditional expression or repeating block. (Note that the
     /// enclosing scope ID for the block associated with a closure is
     /// the closure itself.)
-    pub parent_map: FxHashMap<Scope, (Scope, ScopeDepth)>,
+    pub parent_map: FxIndexMap<Scope, (Scope, ScopeDepth)>,
 
     /// Maps from a variable or binding ID to the block in which that
     /// variable is declared.
-    var_map: FxHashMap<hir::ItemLocalId, Scope>,
+    var_map: FxIndexMap<hir::ItemLocalId, Scope>,
 
     /// Maps from a `NodeId` to the associated destruction scope (if any).
-    destruction_scopes: FxHashMap<hir::ItemLocalId, Scope>,
+    destruction_scopes: FxIndexMap<hir::ItemLocalId, Scope>,
 
     /// `rvalue_scopes` includes entries for those expressions whose
     /// cleanup scope is larger than the default. The map goes from the
index e524625f96646b9de4ec0b13a384d89d7ca27a67..c97865904769820f5793b94e54b6f98a8e09d4dc 100644 (file)
@@ -184,6 +184,8 @@ pub enum CheckInAllocMsg {
     MemoryAccessTest,
     /// We are doing pointer arithmetic.
     PointerArithmeticTest,
+    /// We are doing pointer offset_from.
+    OffsetFromTest,
     /// None of the above -- generic/unspecific inbounds test.
     InboundsTest,
 }
@@ -199,6 +201,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 CheckInAllocMsg::DerefTest => "dereferencing pointer failed: ",
                 CheckInAllocMsg::MemoryAccessTest => "memory access failed: ",
                 CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic failed: ",
+                CheckInAllocMsg::OffsetFromTest => "out-of-bounds offset_from: ",
                 CheckInAllocMsg::InboundsTest => "",
             }
         )
@@ -358,6 +361,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => {
                 write!(f, "null pointer is not a valid pointer for this operation")
             }
+            DanglingIntPointer(0, msg) => {
+                write!(f, "{}null pointer is not a valid pointer", msg)
+            }
             DanglingIntPointer(i, msg) => {
                 write!(f, "{}0x{:x} is not a valid pointer", msg, i)
             }
index 18c2dd71ad3d0bf11c7e2080f0a7cdcf1eaf87d5..a5468b3f4f2020d85c92d3e8d46c87d82746338b 100644 (file)
@@ -2455,7 +2455,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
 
                     AggregateKind::Adt(adt_did, variant, substs, _user_ty, _) => {
                         ty::tls::with(|tcx| {
-                            let variant_def = &tcx.adt_def(adt_did).variants[variant];
+                            let variant_def = &tcx.adt_def(adt_did).variant(variant);
                             let substs = tcx.lift(substs).expect("could not lift for printing");
                             let name = FmtPrinter::new(tcx, Namespace::ValueNS)
                                 .print_def_path(variant_def.def_id, substs)?
@@ -2783,7 +2783,7 @@ pub fn leaf(self, field: Field) -> Self {
         self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
     }
 
-    pub fn variant(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx, field: Field) -> Self {
+    pub fn variant(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx, field: Field) -> Self {
         self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
     }
 }
@@ -2834,12 +2834,12 @@ pub(crate) fn leaf(mut self, field: Field) -> Self {
 
     pub(crate) fn variant(
         mut self,
-        adt_def: &AdtDef,
+        adt_def: AdtDef<'_>,
         variant_index: VariantIdx,
         field: Field,
     ) -> Self {
         self.projs.push(ProjectionElem::Downcast(
-            Some(adt_def.variants[variant_index].name),
+            Some(adt_def.variant(variant_index).name),
             variant_index,
         ));
         self.projs.push(ProjectionElem::Field(field, ()));
index 6f85854fc745cc47c413bf349d58f5c57661b717..51d8113840a930559accae6e1ac7884c08b2e909 100644 (file)
@@ -40,7 +40,7 @@ pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> {
                     None => adt_def.non_enum_variant(),
                     Some(variant_index) => {
                         assert!(adt_def.is_enum());
-                        &adt_def.variants[variant_index]
+                        &adt_def.variant(variant_index)
                     }
                 };
                 let field_def = &variant_def.fields[f.index()];
index 6b572690e21137b50907ca98f50be270fc53ef58..2acfede87aed01877b4885fc100585f4adc8bfd5 100644 (file)
         storage(ArenaCacheSelector<'tcx>)
         separate_provide_extern
     }
-    query adt_def(key: DefId) -> &'tcx ty::AdtDef {
+    query adt_def(key: DefId) -> ty::AdtDef<'tcx> {
         desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
index 04bc0c8b52114dccded115a8b98fa0c9a1ac94f1..785d3ee770985ff837c86ce13e9fb86b1e4dca84 100644 (file)
@@ -128,7 +128,7 @@ pub struct Block {
 #[derive(Debug, HashStable)]
 pub struct Adt<'tcx> {
     /// The ADT we're constructing.
-    pub adt_def: &'tcx AdtDef,
+    pub adt_def: AdtDef<'tcx>,
     /// The variant of the ADT.
     pub variant_index: VariantIdx,
     pub substs: SubstsRef<'tcx>,
@@ -617,7 +617,7 @@ pub enum PatKind<'tcx> {
     /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
     /// multiple variants.
     Variant {
-        adt_def: &'tcx AdtDef,
+        adt_def: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         variant_index: VariantIdx,
         subpatterns: Vec<FieldPat<'tcx>>,
@@ -714,7 +714,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
                 let variant = match *self.kind {
                     PatKind::Variant { adt_def, variant_index, .. } => {
-                        Some(&adt_def.variants[variant_index])
+                        Some(adt_def.variant(variant_index))
                     }
                     _ => self.ty.ty_adt_def().and_then(|adt| {
                         if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }
index 09a28249cce5ba18758bd34d9e609db4424c3201..015bdb5783f36ef657d13af3cbc7ae46d70c8306 100644 (file)
@@ -75,7 +75,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     type InternedVariances = Vec<chalk_ir::Variance>;
     type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
     type DefId = DefId;
-    type InternedAdtId = &'tcx AdtDef;
+    type InternedAdtId = AdtDef<'tcx>;
     type Identifier = ();
     type FnAbi = Abi;
 
index d5a8f5863616ccbf2a18f1b93019f025d5e6f530..cad77f6436ea26fe463beb7a34533ab043831b64 100644 (file)
@@ -4,6 +4,7 @@
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::HashingControls;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_errors::ErrorGuaranteed;
@@ -89,62 +90,62 @@ pub struct AdtFlags: u32 {
 /// where `x` here represents the `DefId` of `S.x`. Then, the `DefId`
 /// can be used with [`TyCtxt::type_of()`] to get the type of the field.
 #[derive(TyEncodable, TyDecodable)]
-pub struct AdtDef {
+pub struct AdtDefData {
     /// The `DefId` of the struct, enum or union item.
     pub did: DefId,
     /// Variants of the ADT. If this is a struct or union, then there will be a single variant.
-    pub variants: IndexVec<VariantIdx, VariantDef>,
+    variants: IndexVec<VariantIdx, VariantDef>,
     /// Flags of the ADT (e.g., is this a struct? is this non-exhaustive?).
     flags: AdtFlags,
     /// Repr options provided by the user.
-    pub repr: ReprOptions,
+    repr: ReprOptions,
 }
 
-impl PartialOrd for AdtDef {
-    fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> {
+impl PartialOrd for AdtDefData {
+    fn partial_cmp(&self, other: &AdtDefData) -> Option<Ordering> {
         Some(self.cmp(&other))
     }
 }
 
 /// There should be only one AdtDef for each `did`, therefore
 /// it is fine to implement `Ord` only based on `did`.
-impl Ord for AdtDef {
-    fn cmp(&self, other: &AdtDef) -> Ordering {
+impl Ord for AdtDefData {
+    fn cmp(&self, other: &AdtDefData) -> Ordering {
         self.did.cmp(&other.did)
     }
 }
 
 /// There should be only one AdtDef for each `did`, therefore
 /// it is fine to implement `PartialEq` only based on `did`.
-impl PartialEq for AdtDef {
+impl PartialEq for AdtDefData {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
         self.did == other.did
     }
 }
 
-impl Eq for AdtDef {}
+impl Eq for AdtDefData {}
 
 /// There should be only one AdtDef for each `did`, therefore
 /// it is fine to implement `Hash` only based on `did`.
-impl Hash for AdtDef {
+impl Hash for AdtDefData {
     #[inline]
     fn hash<H: Hasher>(&self, s: &mut H) {
         self.did.hash(s)
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
+impl<'a> HashStable<StableHashingContext<'a>> for AdtDefData {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         thread_local! {
             static CACHE: RefCell<FxHashMap<(usize, HashingControls), Fingerprint>> = Default::default();
         }
 
         let hash: Fingerprint = CACHE.with(|cache| {
-            let addr = self as *const AdtDef as usize;
+            let addr = self as *const AdtDefData as usize;
             let hashing_controls = hcx.hashing_controls();
             *cache.borrow_mut().entry((addr, hashing_controls)).or_insert_with(|| {
-                let ty::AdtDef { did, ref variants, ref flags, ref repr } = *self;
+                let ty::AdtDefData { did, ref variants, ref flags, ref repr } = *self;
 
                 let mut hasher = StableHasher::new();
                 did.hash_stable(hcx, &mut hasher);
@@ -160,6 +161,32 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
     }
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
+#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
+pub struct AdtDef<'tcx>(pub Interned<'tcx, AdtDefData>);
+
+impl<'tcx> AdtDef<'tcx> {
+    pub fn did(self) -> DefId {
+        self.0.0.did
+    }
+
+    pub fn variants(self) -> &'tcx IndexVec<VariantIdx, VariantDef> {
+        &self.0.0.variants
+    }
+
+    pub fn variant(self, idx: VariantIdx) -> &'tcx VariantDef {
+        &self.0.0.variants[idx]
+    }
+
+    pub fn flags(self) -> AdtFlags {
+        self.0.0.flags
+    }
+
+    pub fn repr(self) -> ReprOptions {
+        self.0.0.repr
+    }
+}
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
 pub enum AdtKind {
     Struct,
@@ -177,8 +204,8 @@ fn into(self) -> DataTypeKind {
     }
 }
 
-impl<'tcx> AdtDef {
-    /// Creates a new `AdtDef`.
+impl AdtDefData {
+    /// Creates a new `AdtDefData`.
     pub(super) fn new(
         tcx: TyCtxt<'_>,
         did: DefId,
@@ -218,36 +245,38 @@ pub(super) fn new(
             flags |= AdtFlags::IS_MANUALLY_DROP;
         }
 
-        AdtDef { did, variants, flags, repr }
+        AdtDefData { did, variants, flags, repr }
     }
+}
 
+impl<'tcx> AdtDef<'tcx> {
     /// Returns `true` if this is a struct.
     #[inline]
-    pub fn is_struct(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_STRUCT)
+    pub fn is_struct(self) -> bool {
+        self.flags().contains(AdtFlags::IS_STRUCT)
     }
 
     /// Returns `true` if this is a union.
     #[inline]
-    pub fn is_union(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_UNION)
+    pub fn is_union(self) -> bool {
+        self.flags().contains(AdtFlags::IS_UNION)
     }
 
     /// Returns `true` if this is an enum.
     #[inline]
-    pub fn is_enum(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_ENUM)
+    pub fn is_enum(self) -> bool {
+        self.flags().contains(AdtFlags::IS_ENUM)
     }
 
     /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
     #[inline]
-    pub fn is_variant_list_non_exhaustive(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
+    pub fn is_variant_list_non_exhaustive(self) -> bool {
+        self.flags().contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
     }
 
     /// Returns the kind of the ADT.
     #[inline]
-    pub fn adt_kind(&self) -> AdtKind {
+    pub fn adt_kind(self) -> AdtKind {
         if self.is_enum() {
             AdtKind::Enum
         } else if self.is_union() {
@@ -258,7 +287,7 @@ pub fn adt_kind(&self) -> AdtKind {
     }
 
     /// Returns a description of this abstract data type.
-    pub fn descr(&self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self.adt_kind() {
             AdtKind::Struct => "struct",
             AdtKind::Union => "union",
@@ -268,7 +297,7 @@ pub fn descr(&self) -> &'static str {
 
     /// Returns a description of a variant of this abstract data type.
     #[inline]
-    pub fn variant_descr(&self) -> &'static str {
+    pub fn variant_descr(self) -> &'static str {
         match self.adt_kind() {
             AdtKind::Struct => "struct",
             AdtKind::Union => "union",
@@ -278,65 +307,65 @@ pub fn variant_descr(&self) -> &'static str {
 
     /// If this function returns `true`, it implies that `is_struct` must return `true`.
     #[inline]
-    pub fn has_ctor(&self) -> bool {
-        self.flags.contains(AdtFlags::HAS_CTOR)
+    pub fn has_ctor(self) -> bool {
+        self.flags().contains(AdtFlags::HAS_CTOR)
     }
 
     /// Returns `true` if this type is `#[fundamental]` for the purposes
     /// of coherence checking.
     #[inline]
-    pub fn is_fundamental(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_FUNDAMENTAL)
+    pub fn is_fundamental(self) -> bool {
+        self.flags().contains(AdtFlags::IS_FUNDAMENTAL)
     }
 
     /// Returns `true` if this is `PhantomData<T>`.
     #[inline]
-    pub fn is_phantom_data(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
+    pub fn is_phantom_data(self) -> bool {
+        self.flags().contains(AdtFlags::IS_PHANTOM_DATA)
     }
 
     /// Returns `true` if this is Box<T>.
     #[inline]
-    pub fn is_box(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_BOX)
+    pub fn is_box(self) -> bool {
+        self.flags().contains(AdtFlags::IS_BOX)
     }
 
     /// Returns `true` if this is `ManuallyDrop<T>`.
     #[inline]
-    pub fn is_manually_drop(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_MANUALLY_DROP)
+    pub fn is_manually_drop(self) -> bool {
+        self.flags().contains(AdtFlags::IS_MANUALLY_DROP)
     }
 
     /// Returns `true` if this type has a destructor.
-    pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
+    pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool {
         self.destructor(tcx).is_some()
     }
 
-    pub fn has_non_const_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
+    pub fn has_non_const_dtor(self, tcx: TyCtxt<'tcx>) -> bool {
         matches!(self.destructor(tcx), Some(Destructor { constness: hir::Constness::NotConst, .. }))
     }
 
     /// Asserts this is a struct or union and returns its unique variant.
-    pub fn non_enum_variant(&self) -> &VariantDef {
+    pub fn non_enum_variant(self) -> &'tcx VariantDef {
         assert!(self.is_struct() || self.is_union());
-        &self.variants[VariantIdx::new(0)]
+        &self.variant(VariantIdx::new(0))
     }
 
     #[inline]
-    pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
-        tcx.predicates_of(self.did)
+    pub fn predicates(self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
+        tcx.predicates_of(self.did())
     }
 
     /// Returns an iterator over all fields contained
     /// by this ADT.
     #[inline]
-    pub fn all_fields(&self) -> impl Iterator<Item = &FieldDef> + Clone {
-        self.variants.iter().flat_map(|v| v.fields.iter())
+    pub fn all_fields(self) -> impl Iterator<Item = &'tcx FieldDef> + Clone {
+        self.variants().iter().flat_map(|v| v.fields.iter())
     }
 
     /// Whether the ADT lacks fields. Note that this includes uninhabited enums,
     /// e.g., `enum Void {}` is considered payload free as well.
-    pub fn is_payloadfree(&self) -> bool {
+    pub fn is_payloadfree(self) -> bool {
         // Treat the ADT as not payload-free if arbitrary_enum_discriminant is used (#88621).
         // This would disallow the following kind of enum from being casted into integer.
         // ```
@@ -347,31 +376,31 @@ pub fn is_payloadfree(&self) -> bool {
         // }
         // ```
         if self
-            .variants
+            .variants()
             .iter()
             .any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const)
         {
             return false;
         }
-        self.variants.iter().all(|v| v.fields.is_empty())
+        self.variants().iter().all(|v| v.fields.is_empty())
     }
 
     /// Return a `VariantDef` given a variant id.
-    pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
-        self.variants.iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
+    pub fn variant_with_id(self, vid: DefId) -> &'tcx VariantDef {
+        self.variants().iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
     }
 
     /// Return a `VariantDef` given a constructor id.
-    pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef {
-        self.variants
+    pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef {
+        self.variants()
             .iter()
             .find(|v| v.ctor_def_id == Some(cid))
             .expect("variant_with_ctor_id: unknown variant")
     }
 
     /// Return the index of `VariantDef` given a variant id.
-    pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
-        self.variants
+    pub fn variant_index_with_id(self, vid: DefId) -> VariantIdx {
+        self.variants()
             .iter_enumerated()
             .find(|(_, v)| v.def_id == vid)
             .expect("variant_index_with_id: unknown variant")
@@ -379,15 +408,15 @@ pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
     }
 
     /// Return the index of `VariantDef` given a constructor id.
-    pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx {
-        self.variants
+    pub fn variant_index_with_ctor_id(self, cid: DefId) -> VariantIdx {
+        self.variants()
             .iter_enumerated()
             .find(|(_, v)| v.ctor_def_id == Some(cid))
             .expect("variant_index_with_ctor_id: unknown variant")
             .0
     }
 
-    pub fn variant_of_res(&self, res: Res) -> &VariantDef {
+    pub fn variant_of_res(self, res: Res) -> &'tcx VariantDef {
         match res {
             Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
             Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
@@ -402,10 +431,10 @@ pub fn variant_of_res(&self, res: Res) -> &VariantDef {
     }
 
     #[inline]
-    pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
+    pub fn eval_explicit_discr(self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
         assert!(self.is_enum());
         let param_env = tcx.param_env(expr_did);
-        let repr_type = self.repr.discr_type();
+        let repr_type = self.repr().discr_type();
         match tcx.const_eval_poly(expr_did) {
             Ok(val) => {
                 let ty = repr_type.to_ty(tcx);
@@ -437,14 +466,14 @@ pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<
 
     #[inline]
     pub fn discriminants(
-        &'tcx self,
+        self,
         tcx: TyCtxt<'tcx>,
     ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
         assert!(self.is_enum());
-        let repr_type = self.repr.discr_type();
+        let repr_type = self.repr().discr_type();
         let initial = repr_type.initial_discriminant(tcx);
         let mut prev_discr = None::<Discr<'tcx>>;
-        self.variants.iter_enumerated().map(move |(i, v)| {
+        self.variants().iter_enumerated().map(move |(i, v)| {
             let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
             if let VariantDiscr::Explicit(expr_did) = v.discr {
                 if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
@@ -458,8 +487,8 @@ pub fn discriminants(
     }
 
     #[inline]
-    pub fn variant_range(&self) -> Range<VariantIdx> {
-        VariantIdx::new(0)..VariantIdx::new(self.variants.len())
+    pub fn variant_range(self) -> Range<VariantIdx> {
+        VariantIdx::new(0)..VariantIdx::new(self.variants().len())
     }
 
     /// Computes the discriminant value used by a specific variant.
@@ -469,7 +498,7 @@ pub fn variant_range(&self) -> Range<VariantIdx> {
     /// assuming there are no constant-evaluation errors there.
     #[inline]
     pub fn discriminant_for_variant(
-        &self,
+        self,
         tcx: TyCtxt<'tcx>,
         variant_index: VariantIdx,
     ) -> Discr<'tcx> {
@@ -477,19 +506,19 @@ pub fn discriminant_for_variant(
         let (val, offset) = self.discriminant_def_for_variant(variant_index);
         let explicit_value = val
             .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
-            .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx));
+            .unwrap_or_else(|| self.repr().discr_type().initial_discriminant(tcx));
         explicit_value.checked_add(tcx, offset as u128).0
     }
 
     /// Yields a `DefId` for the discriminant and an offset to add to it
     /// Alternatively, if there is no explicit discriminant, returns the
     /// inferred discriminant directly.
-    pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
-        assert!(!self.variants.is_empty());
+    pub fn discriminant_def_for_variant(self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
+        assert!(!self.variants().is_empty());
         let mut explicit_index = variant_index.as_u32();
         let expr_did;
         loop {
-            match self.variants[VariantIdx::from_u32(explicit_index)].discr {
+            match self.variant(VariantIdx::from_u32(explicit_index)).discr {
                 ty::VariantDiscr::Relative(0) => {
                     expr_did = None;
                     break;
@@ -506,8 +535,8 @@ pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option
         (expr_did, variant_index.as_u32() - explicit_index)
     }
 
-    pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
-        tcx.adt_destructor(self.did)
+    pub fn destructor(self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
+        tcx.adt_destructor(self.did())
     }
 
     /// Returns a list of types such that `Self: Sized` if and only
@@ -520,7 +549,7 @@ pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
     ///
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer (e.g., issue #31299).
-    pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
-        tcx.adt_sized_constraint(self.did).0
+    pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
+        tcx.adt_sized_constraint(self.did()).0
     }
 }
index 65a60dd6b9d7b70ffdc8d36750f0c95fa30f65ef..1446f7dac36385c5f683ec43de579d79e98efb18 100644 (file)
@@ -164,7 +164,7 @@ fn to_symbol(&self, tcx: TyCtxt<'tcx>) -> Symbol {
                         write!(
                             &mut symbol,
                             "__{}",
-                            def.variants[variant].fields[idx as usize].name.as_str(),
+                            def.variant(variant).fields[idx as usize].name.as_str(),
                         )
                         .unwrap();
                     }
@@ -330,7 +330,7 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
                     curr_string = format!(
                         "{}.{}",
                         curr_string,
-                        def.variants[variant].fields[idx as usize].name.as_str()
+                        def.variant(variant).fields[idx as usize].name.as_str()
                     );
                 }
                 ty::Tuple(_) => {
index 69455951c5794b8a97f1814ad52fa33396bbd844..7fcc46cc7c206fd0b7d103bbbbb62d91d74412fb 100644 (file)
@@ -15,7 +15,7 @@
 use crate::thir;
 use crate::traits;
 use crate::ty::subst::SubstsRef;
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{self, AdtDef, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::Span;
@@ -156,6 +156,12 @@ fn encode(&self, e: &mut E) -> Result<(), E::Error> {
     }
 }
 
+impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AdtDef<'tcx> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+        self.0.0.encode(e)
+    }
+}
+
 impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         e.encode_alloc_id(self)
@@ -178,8 +184,7 @@ fn encode(&self, e: &mut E) -> Result<(), E::Error> {
     &'tcx mir::Body<'tcx>,
     &'tcx mir::UnsafetyCheckResult,
     &'tcx mir::BorrowCheckResult<'tcx>,
-    &'tcx mir::coverage::CodeRegion,
-    &'tcx ty::AdtDef
+    &'tcx mir::coverage::CodeRegion
 }
 
 pub trait TyDecoder<'tcx>: Decoder {
@@ -367,6 +372,12 @@ fn decode(decoder: &mut D) -> Self {
     }
 }
 
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AdtDef<'tcx> {
+    fn decode(decoder: &mut D) -> Self {
+        decoder.tcx().intern_adt_def(Decodable::decode(decoder))
+    }
+}
+
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
     fn decode(decoder: &mut D) -> &'tcx Self {
         decoder.tcx().arena.alloc_from_iter(
@@ -409,8 +420,7 @@ fn decode(decoder: &mut D) -> &'tcx Self {
     &'tcx mir::UnsafetyCheckResult,
     &'tcx mir::BorrowCheckResult<'tcx>,
     &'tcx mir::coverage::CodeRegion,
-    &'tcx ty::List<ty::BoundVariableKind>,
-    &'tcx ty::AdtDef
+    &'tcx ty::List<ty::BoundVariableKind>
 }
 
 #[macro_export]
index 99dd4ab1bf5fd8e14d620c27f5b441fdfd97a3aa..494535f3d597ac1ca294ce2599cd6f322ccbe6e7 100644 (file)
@@ -17,7 +17,7 @@
 use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
 use crate::ty::TyKind::*;
 use crate::ty::{
-    self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
+    self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
     ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
     FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
     ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
@@ -115,7 +115,7 @@ pub struct CtxtInterners<'tcx> {
     const_allocation: InternedSet<'tcx, Allocation>,
     bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
     layout: InternedSet<'tcx, LayoutS<'tcx>>,
-    adt_def: InternedSet<'tcx, AdtDef>,
+    adt_def: InternedSet<'tcx, AdtDefData>,
 }
 
 impl<'tcx> CtxtInterners<'tcx> {
@@ -1123,8 +1123,8 @@ pub fn alloc_adt_def(
         kind: AdtKind,
         variants: IndexVec<VariantIdx, ty::VariantDef>,
         repr: ReprOptions,
-    ) -> &'tcx ty::AdtDef {
-        self.intern_adt_def(ty::AdtDef::new(self, did, kind, variants, repr))
+    ) -> ty::AdtDef<'tcx> {
+        self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
     }
 
     /// Allocates a read-only byte or string literal for `mir::interpret`.
@@ -2147,47 +2147,7 @@ pub fn $method(self, v: $ty) -> $ret_ty {
     const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
     const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
     layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
-}
-
-macro_rules! direct_interners_old {
-    ($($name:ident: $method:ident($ty:ty),)+) => {
-        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
-            fn borrow<'a>(&'a self) -> &'a $ty {
-                &self.0
-            }
-        }
-
-        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
-            fn eq(&self, other: &Self) -> bool {
-                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
-                // equals `x == y`.
-                self.0 == other.0
-            }
-        }
-
-        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
-
-        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
-            fn hash<H: Hasher>(&self, s: &mut H) {
-                // The `Borrow` trait requires that `x.borrow().hash(s) ==
-                // x.hash(s)`.
-                self.0.hash(s)
-            }
-        }
-
-        impl<'tcx> TyCtxt<'tcx> {
-            pub fn $method(self, v: $ty) -> &'tcx $ty {
-                self.interners.$name.intern(v, |v| {
-                    InternedInSet(self.interners.arena.alloc(v))
-                }).0
-            }
-        })+
-    }
-}
-
-// FIXME: eventually these should all be converted to `direct_interners`.
-direct_interners_old! {
-    adt_def: intern_adt_def(AdtDef),
+    adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
 }
 
 macro_rules! slice_interners {
@@ -2341,7 +2301,7 @@ pub fn mk_static_str(self) -> Ty<'tcx> {
     }
 
     #[inline]
-    pub fn mk_adt(self, def: &'tcx AdtDef, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
+    pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
         // Take a copy of substs so that we own the vectors inside.
         self.mk_ty(Adt(def, substs))
     }
@@ -2563,12 +2523,12 @@ pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
     pub fn mk_place_downcast(
         self,
         place: Place<'tcx>,
-        adt_def: &'tcx AdtDef,
+        adt_def: AdtDef<'tcx>,
         variant_index: VariantIdx,
     ) -> Place<'tcx> {
         self.mk_place_elem(
             place,
-            PlaceElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index),
+            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
         )
     }
 
index 99a3d4c7fe4f7c11f301e6e17621909103c4d343..7d950b79cdd8da671d4c1835370355b5c02ffcc1 100644 (file)
@@ -512,7 +512,7 @@ pub fn suggest_constraining_type_params<'a>(
         };
 
         err.span_suggestion_verbose(span, msg, suggestion, applicability);
-    } else {
+    } else if suggestions.len() > 1 {
         err.multipart_suggestion_verbose(
             "consider restricting type parameters",
             suggestions.into_iter().map(|(span, suggestion, _)| (span, suggestion)).collect(),
index 708bd64578c3a69bc29968f2c5ba52d1141e1cc6..599845bae79f35b9c3124dedcb3d9b1cae83f721 100644 (file)
@@ -247,7 +247,7 @@ pub fn sort_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
             }
             ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(),
 
-            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
+            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did())).into(),
             ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
             ty::Array(t, n) => {
                 if t.is_simple_ty() {
index c0dd4db2945dc0f0c710b0449d08a3d215943fc8..9c018dc685c46c2e9ff8f4dc1ec427567639979f 100644 (file)
@@ -86,7 +86,7 @@ pub fn simplify_type<'tcx>(
         ty::Int(int_type) => Some(IntSimplifiedType(int_type)),
         ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)),
         ty::Float(float_type) => Some(FloatSimplifiedType(float_type)),
-        ty::Adt(def, _) => Some(AdtSimplifiedType(def.did)),
+        ty::Adt(def, _) => Some(AdtSimplifiedType(def.did())),
         ty::Str => Some(StrSimplifiedType),
         ty::Array(..) => Some(ArraySimplifiedType),
         ty::Slice(..) => Some(SliceSimplifiedType),
index e2289b44b5c5b554891197bded06df5d4e43f91b..2c78c1f63d8ff519328bdfd5adc8e1c544cd54e4 100644 (file)
@@ -105,21 +105,21 @@ pub fn is_ty_uninhabited_from(
     }
 }
 
-impl<'tcx> AdtDef {
+impl<'tcx> AdtDef<'tcx> {
     /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
     fn uninhabited_from(
-        &self,
+        self,
         tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> DefIdForest<'tcx> {
         // Non-exhaustive ADTs from other crates are always considered inhabited.
-        if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
+        if self.is_variant_list_non_exhaustive() && !self.did().is_local() {
             DefIdForest::empty()
         } else {
             DefIdForest::intersection(
                 tcx,
-                self.variants
+                self.variants()
                     .iter()
                     .map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)),
             )
index 23664640aaef0f8987c7b82121bb7675359a769c..5b92b33f6d457574b22c0d6cae81887e7d66f636 100644 (file)
@@ -733,7 +733,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
             }
 
             // SIMD vector types.
-            ty::Adt(def, substs) if def.repr.simd() => {
+            ty::Adt(def, substs) if def.repr().simd() => {
                 if !def.is_struct() {
                     // Should have yielded E0517 by now.
                     tcx.sess.delay_span_bug(
@@ -853,7 +853,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
             ty::Adt(def, substs) => {
                 // Cache the field layouts.
                 let variants = def
-                    .variants
+                    .variants()
                     .iter()
                     .map(|v| {
                         v.fields
@@ -864,22 +864,22 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                     .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
 
                 if def.is_union() {
-                    if def.repr.pack.is_some() && def.repr.align.is_some() {
+                    if def.repr().pack.is_some() && def.repr().align.is_some() {
                         self.tcx.sess.delay_span_bug(
-                            tcx.def_span(def.did),
+                            tcx.def_span(def.did()),
                             "union cannot be packed and aligned",
                         );
                         return Err(LayoutError::Unknown(ty));
                     }
 
                     let mut align =
-                        if def.repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
+                        if def.repr().pack.is_some() { dl.i8_align } else { dl.aggregate_align };
 
-                    if let Some(repr_align) = def.repr.align {
+                    if let Some(repr_align) = def.repr().align {
                         align = align.max(AbiAndPrefAlign::new(repr_align));
                     }
 
-                    let optimize = !def.repr.inhibit_union_abi_opt();
+                    let optimize = !def.repr().inhibit_union_abi_opt();
                     let mut size = Size::ZERO;
                     let mut abi = Abi::Aggregate { sized: true };
                     let index = VariantIdx::new(0);
@@ -915,7 +915,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                         size = cmp::max(size, field.size);
                     }
 
-                    if let Some(pack) = def.repr.pack {
+                    if let Some(pack) = def.repr().pack {
                         align = align.min(AbiAndPrefAlign::new(pack));
                     }
 
@@ -963,7 +963,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                     // Only one variant is present.
                     (present_second.is_none() &&
                     // Representation optimizations are allowed.
-                    !def.repr.inhibit_enum_layout_opt());
+                    !def.repr().inhibit_enum_layout_opt());
                 if is_struct {
                     // Struct, or univariant enum equivalent to a struct.
                     // (Typechecking will reject discriminant-sizing attrs.)
@@ -972,8 +972,8 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                     let kind = if def.is_enum() || variants[v].is_empty() {
                         StructKind::AlwaysSized
                     } else {
-                        let param_env = tcx.param_env(def.did);
-                        let last_field = def.variants[v].fields.last().unwrap();
+                        let param_env = tcx.param_env(def.did());
+                        let last_field = def.variant(v).fields.last().unwrap();
                         let always_sized =
                             tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
                         if !always_sized {
@@ -983,9 +983,9 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                         }
                     };
 
-                    let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr, kind)?;
+                    let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr(), kind)?;
                     st.variants = Variants::Single { index: v };
-                    let (start, end) = self.tcx.layout_scalar_valid_range(def.did);
+                    let (start, end) = self.tcx.layout_scalar_valid_range(def.did());
                     match st.abi {
                         Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
                             // the asserts ensure that we are not using the
@@ -1011,7 +1011,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                             }
 
                             // Update `largest_niche` if we have introduced a larger niche.
-                            let niche = if def.repr.hide_niche() {
+                            let niche = if def.repr().hide_niche() {
                                 None
                             } else {
                                 Niche::from_scalar(dl, Size::ZERO, *scalar)
@@ -1049,14 +1049,14 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                 // instead of actual discriminants, so dataful enums with
                 // explicit discriminants (RFC #2363) would misbehave.
                 let no_explicit_discriminants = def
-                    .variants
+                    .variants()
                     .iter_enumerated()
                     .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
 
                 let mut niche_filling_layout = None;
 
                 // Niche-filling enum optimization.
-                if !def.repr.inhibit_enum_layout_opt() && no_explicit_discriminants {
+                if !def.repr().inhibit_enum_layout_opt() && no_explicit_discriminants {
                     let mut dataful_variant = None;
                     let mut niche_variants = VariantIdx::MAX..=VariantIdx::new(0);
 
@@ -1107,7 +1107,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                                     let mut st = self.univariant_uninterned(
                                         ty,
                                         v,
-                                        &def.repr,
+                                        &def.repr(),
                                         StructKind::AlwaysSized,
                                     )?;
                                     st.variants = Variants::Single { index: j };
@@ -1169,7 +1169,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                 }
 
                 let (mut min, mut max) = (i128::MAX, i128::MIN);
-                let discr_type = def.repr.discr_type();
+                let discr_type = def.repr().discr_type();
                 let bits = Integer::from_attr(self, discr_type).size().bits();
                 for (i, discr) in def.discriminants(tcx) {
                     if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
@@ -1193,7 +1193,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                     max = 0;
                 }
                 assert!(min <= max, "discriminant range is {}...{}", min, max);
-                let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
+                let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr(), min, max);
 
                 let mut align = dl.aggregate_align;
                 let mut size = Size::ZERO;
@@ -1208,7 +1208,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                 // determining the alignment of the overall enum, and the
                 // determining the alignment of the payload after the tag.)
                 let mut prefix_align = min_ity.align(dl).abi;
-                if def.repr.c() {
+                if def.repr().c() {
                     for fields in &variants {
                         for field in fields {
                             prefix_align = prefix_align.max(field.align.abi);
@@ -1223,7 +1223,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                         let mut st = self.univariant_uninterned(
                             ty,
                             &field_layouts,
-                            &def.repr,
+                            &def.repr(),
                             StructKind::Prefixed(min_ity.size(), prefix_align),
                         )?;
                         st.variants = Variants::Single { index: i };
@@ -1250,7 +1250,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                     return Err(LayoutError::SizeOverflow(ty));
                 }
 
-                let typeck_ity = Integer::from_attr(dl, def.repr.discr_type());
+                let typeck_ity = Integer::from_attr(dl, def.repr().discr_type());
                 if typeck_ity < min_ity {
                     // It is a bug if Layout decided on a greater discriminant size than typeck for
                     // some reason at this point (based on values discriminant can take on). Mostly
@@ -1280,7 +1280,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'
                 // won't be so conservative.
 
                 // Use the initial field alignment
-                let mut ity = if def.repr.c() || def.repr.int.is_some() {
+                let mut ity = if def.repr().c() || def.repr().int.is_some() {
                     min_ity
                 } else {
                     Integer::for_align(dl, start_align).unwrap_or(min_ity)
@@ -1821,7 +1821,7 @@ fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) {
         };
 
         let adt_kind = adt_def.adt_kind();
-        let adt_packed = adt_def.repr.pack.is_some();
+        let adt_packed = adt_def.repr().pack.is_some();
 
         let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
             let mut min_size = Size::ZERO;
@@ -1855,12 +1855,13 @@ fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) {
 
         match layout.variants {
             Variants::Single { index } => {
-                if !adt_def.variants.is_empty() && layout.fields != FieldsShape::Primitive {
+                if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive {
                     debug!(
                         "print-type-size `{:#?}` variant {}",
-                        layout, adt_def.variants[index].name
+                        layout,
+                        adt_def.variant(index).name
                     );
-                    let variant_def = &adt_def.variants[index];
+                    let variant_def = &adt_def.variant(index);
                     let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
                     record(
                         adt_kind.into(),
@@ -1879,10 +1880,10 @@ fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) {
                 debug!(
                     "print-type-size `{:#?}` adt general variants def {}",
                     layout.ty,
-                    adt_def.variants.len()
+                    adt_def.variants().len()
                 );
                 let variant_infos: Vec<_> = adt_def
-                    .variants
+                    .variants()
                     .iter_enumerated()
                     .map(|(i, variant_def)| {
                         let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
@@ -1964,17 +1965,17 @@ pub fn compute(
 
             ty::Adt(def, substs) => {
                 // Only newtypes and enums w/ nullable pointer optimization.
-                if def.is_union() || def.variants.is_empty() || def.variants.len() > 2 {
+                if def.is_union() || def.variants().is_empty() || def.variants().len() > 2 {
                     return Err(err);
                 }
 
                 // Get a zero-sized variant or a pointer newtype.
                 let zero_or_ptr_variant = |i| {
                     let i = VariantIdx::new(i);
-                    let fields = def.variants[i]
-                        .fields
-                        .iter()
-                        .map(|field| SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env));
+                    let fields =
+                        def.variant(i).fields.iter().map(|field| {
+                            SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
+                        });
                     let mut ptr = None;
                     for field in fields {
                         let field = field?;
@@ -1997,11 +1998,11 @@ pub fn compute(
 
                 let v0 = zero_or_ptr_variant(0)?;
                 // Newtype.
-                if def.variants.len() == 1 {
+                if def.variants().len() == 1 {
                     if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 {
                         return Ok(SizeSkeleton::Pointer {
                             non_zero: non_zero
-                                || match tcx.layout_scalar_valid_range(def.did) {
+                                || match tcx.layout_scalar_valid_range(def.did()) {
                                     (Bound::Included(start), Bound::Unbounded) => start > 0,
                                     (Bound::Included(start), Bound::Included(end)) => {
                                         0 < start && start < end
@@ -2262,9 +2263,9 @@ fn ty_and_layout_for_variant(
                 }
 
                 let fields = match this.ty.kind() {
-                    ty::Adt(def, _) if def.variants.is_empty() =>
+                    ty::Adt(def, _) if def.variants().is_empty() =>
                         bug!("for_variant called on zero-variant enum"),
-                    ty::Adt(def, _) => def.variants[variant_index].fields.len(),
+                    ty::Adt(def, _) => def.variant(variant_index).fields.len(),
                     _ => bug!(),
                 };
                 tcx.intern_layout(LayoutS {
@@ -2405,7 +2406,7 @@ fn field_ty_or_layout<'tcx>(
                 ty::Adt(def, substs) => {
                     match this.variants {
                         Variants::Single { index } => {
-                            TyMaybeWithLayout::Ty(def.variants[index].fields[i].ty(tcx, substs))
+                            TyMaybeWithLayout::Ty(def.variant(index).fields[i].ty(tcx, substs))
                         }
 
                         // Discriminant field for enums (where applicable).
index 8d7f6d84c7c38d8090e331143508442bd4c7cc9d..c74b3e9d0fc3937d620350ad21b612c1086f789e 100644 (file)
@@ -274,7 +274,7 @@ fn characteristic_def_id_of_type_cached<'a>(
     visited: &mut SsoHashSet<Ty<'a>>,
 ) -> Option<DefId> {
     match *ty.kind() {
-        ty::Adt(adt_def, _) => Some(adt_def.did),
+        ty::Adt(adt_def, _) => Some(adt_def.did()),
 
         ty::Dynamic(data, ..) => data.principal_def_id(),
 
index 0927dc2d266abe4353b461d3276fcfe135bb76d6..00cb9907d95a5dae0aebd50fa3f6e2cced010ef1 100644 (file)
@@ -618,7 +618,7 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
                 ty::BoundTyKind::Param(p) => p!(write("{}", p)),
             },
             ty::Adt(def, substs) => {
-                p!(print_def_path(def.did, substs));
+                p!(print_def_path(def.did(), substs));
             }
             ty::Dynamic(data, r) => {
                 let print_r = self.should_print_region(r);
@@ -1487,7 +1487,7 @@ fn pretty_print_const_value(
                         }
                         p!(")");
                     }
-                    ty::Adt(def, _) if def.variants.is_empty() => {
+                    ty::Adt(def, _) if def.variants().is_empty() => {
                         self = self.typed_value(
                             |mut this| {
                                 write!(this, "unreachable()")?;
@@ -1500,7 +1500,7 @@ fn pretty_print_const_value(
                     ty::Adt(def, substs) => {
                         let variant_idx =
                             contents.variant.expect("destructed const of adt without variant idx");
-                        let variant_def = &def.variants[variant_idx];
+                        let variant_def = &def.variant(variant_idx);
                         p!(print_value_path(variant_def.def_id, substs));
 
                         match variant_def.ctor_kind {
index 42ddbcc1e2f3b839d4618fe1966fa2d8893319ef..81ee7942c4d3452da10a4c0d61b61493e2837f4f 100644 (file)
@@ -406,7 +406,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
         (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
 
         (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) if a_def == b_def => {
-            let substs = relation.relate_item_substs(a_def.did, a_substs, b_substs)?;
+            let substs = relation.relate_item_substs(a_def.did(), a_substs, b_substs)?;
             Ok(tcx.mk_adt(a_def, substs))
         }
 
index 2d51462221c07e8e1fef6f4e9eb164fc46c85dca..5c7910db362d290c2257e04daf031bdebffb8436 100644 (file)
@@ -33,13 +33,13 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl fmt::Debug for ty::AdtDef {
+impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         ty::tls::with(|tcx| {
             with_no_trimmed_paths!({
                 f.write_str(
                     &FmtPrinter::new(tcx, Namespace::TypeNS)
-                        .print_def_path(self.did, &[])?
+                        .print_def_path(self.did(), &[])?
                         .into_buffer(),
                 )
             })
@@ -672,7 +672,7 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
 // TypeFoldable implementations.
 
 /// AdtDefs are basically the same as a DefId.
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
+impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> {
     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
         self,
         _folder: &mut F,
index 775d86153ced20929f402b35ab1995d41e37f478..a49189ae92afb0e11e8dc51aff6c29414aea163a 100644 (file)
@@ -109,7 +109,7 @@ pub enum TyKind<'tcx> {
     ///
     /// Note that generic parameters in fields only get lazily substituted
     /// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`.
-    Adt(&'tcx AdtDef, SubstsRef<'tcx>),
+    Adt(AdtDef<'tcx>, SubstsRef<'tcx>),
 
     /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
     Foreign(DefId),
@@ -1903,7 +1903,7 @@ pub fn is_array(self) -> bool {
     #[inline]
     pub fn is_simd(self) -> bool {
         match self.kind() {
-            Adt(def, _) => def.repr.simd(),
+            Adt(def, _) => def.repr().simd(),
             _ => false,
         }
     }
@@ -1919,7 +1919,7 @@ pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
     pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
         match self.kind() {
             Adt(def, substs) => {
-                assert!(def.repr.simd(), "`simd_size_and_type` called on non-SIMD type");
+                assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
                 let variant = def.non_enum_variant();
                 let f0_ty = variant.fields[0].ty(tcx, substs);
 
@@ -2153,9 +2153,9 @@ pub fn is_impl_trait(self) -> bool {
     }
 
     #[inline]
-    pub fn ty_adt_def(self) -> Option<&'tcx AdtDef> {
+    pub fn ty_adt_def(self) -> Option<AdtDef<'tcx>> {
         match self.kind() {
-            Adt(adt, _) => Some(adt),
+            Adt(adt, _) => Some(*adt),
             _ => None,
         }
     }
@@ -2194,7 +2194,7 @@ pub fn discriminant_for_variant(
         variant_index: VariantIdx,
     ) -> Option<Discr<'tcx>> {
         match self.kind() {
-            TyKind::Adt(adt, _) if adt.variants.is_empty() => {
+            TyKind::Adt(adt, _) if adt.variants().is_empty() => {
                 // This can actually happen during CTFE, see
                 // https://github.com/rust-lang/rust/issues/89765.
                 None
@@ -2212,7 +2212,7 @@ pub fn discriminant_for_variant(
     /// Returns the type of the discriminant of this type.
     pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self.kind() {
-            ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
+            ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx),
             ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
 
             ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => {
index eb16d305d0a8085c17caab0668a982a65a2e586b..6bde9e6d5e25c89a0b70790e37b51d264ac413ea 100644 (file)
@@ -377,10 +377,10 @@ pub fn calculate_dtor(
     /// Note that this returns only the constraints for the
     /// destructor of `def` itself. For the destructors of the
     /// contents, you need `adt_dtorck_constraint`.
-    pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) -> Vec<ty::subst::GenericArg<'tcx>> {
+    pub fn destructor_constraints(self, def: ty::AdtDef<'tcx>) -> Vec<ty::subst::GenericArg<'tcx>> {
         let dtor = match def.destructor(self) {
             None => {
-                debug!("destructor_constraints({:?}) - no dtor", def.did);
+                debug!("destructor_constraints({:?}) - no dtor", def.did());
                 return vec![];
             }
             Some(dtor) => dtor.did,
@@ -415,7 +415,7 @@ pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) -> Vec<ty::subst::Gen
             _ => bug!(),
         };
 
-        let item_substs = match *self.type_of(def.did).kind() {
+        let item_substs = match *self.type_of(def.did()).kind() {
             ty::Adt(def_, substs) if def_ == def => substs,
             _ => bug!(),
         };
@@ -445,7 +445,7 @@ pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) -> Vec<ty::subst::Gen
             })
             .map(|(item_param, _)| item_param)
             .collect();
-        debug!("destructor_constraint({:?}) = {:?}", def.did, result);
+        debug!("destructor_constraint({:?}) = {:?}", def.did(), result);
         result
     }
 
index 389f711099ba085a83376a855fb834058ea22e22..3b93d127d2c29ea54b72ed18a455ef738f022f38 100644 (file)
@@ -334,8 +334,8 @@ fn expect_upvars_resolved<'a>(
         self.project(PlaceElem::Deref)
     }
 
-    crate fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Self {
-        self.project(PlaceElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index))
+    crate fn downcast(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx) -> Self {
+        self.project(PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index))
     }
 
     fn index(self, index: Local) -> Self {
index 9c7c7203f47de83de2cc5f859d159e190ffdcfb7..8092f999311230544793bce0c49624d19ebae303 100644 (file)
@@ -332,7 +332,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     .collect();
 
                 let field_names: Vec<_> =
-                    (0..adt_def.variants[variant_index].fields.len()).map(Field::new).collect();
+                    (0..adt_def.variant(variant_index).fields.len()).map(Field::new).collect();
 
                 let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
                     let place_builder =
@@ -367,7 +367,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     })
                 });
                 let adt = Box::new(AggregateKind::Adt(
-                    adt_def.did,
+                    adt_def.did(),
                     variant_index,
                     substs,
                     user_ty,
index 44fe93ba3630c96de23c66c015f442c222c367cc..c724e3e1b8f2af94e4b97e5c4a211660af96dd2b 100644 (file)
@@ -946,7 +946,7 @@ enum TestKind<'tcx> {
     /// Test what enum variant a value is.
     Switch {
         /// The enum type being tested.
-        adt_def: &'tcx ty::AdtDef,
+        adt_def: ty::AdtDef<'tcx>,
         /// The set of variants that we should create a branch for. We also
         /// create an additional "otherwise" case.
         variants: BitSet<VariantIdx>,
index 4f9a2c0ce779da4e53ea14d374ce0692ffa4e339..7f53d9dd70502ad10b0f567efdd81d9e77a9f3fa 100644 (file)
@@ -264,7 +264,7 @@ fn simplify_match_pair<'pat>(
             }
 
             PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
-                let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| {
+                let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
                     i == variant_index || {
                         self.tcx.features().exhaustive_patterns
                             && !v
@@ -276,7 +276,7 @@ fn simplify_match_pair<'pat>(
                                 )
                                 .is_empty()
                     }
-                }) && (adt_def.did.is_local()
+                }) && (adt_def.did().is_local()
                     || !adt_def.is_variant_list_non_exhaustive());
                 if irrefutable {
                     let place_builder = match_pair.place.downcast(adt_def, variant_index);
index da9c4b930df47a4854a26d5bff363c60563675a6..96069f05b40f3ad30e5a3ef2515f294d579ec011 100644 (file)
@@ -30,11 +30,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// It is a bug to call this with a not-fully-simplified pattern.
     pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
         match *match_pair.pattern.kind {
-            PatKind::Variant { ref adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
+            PatKind::Variant { adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
                 span: match_pair.pattern.span,
                 kind: TestKind::Switch {
                     adt_def,
-                    variants: BitSet::new_empty(adt_def.variants.len()),
+                    variants: BitSet::new_empty(adt_def.variants().len()),
                 },
             },
 
@@ -174,7 +174,7 @@ pub(super) fn perform_test(
             TestKind::Switch { adt_def, ref variants } => {
                 let target_blocks = make_target_blocks(self);
                 // Variants is a BitVec of indexes into adt_def.variants.
-                let num_enum_variants = adt_def.variants.len();
+                let num_enum_variants = adt_def.variants().len();
                 debug_assert_eq!(target_blocks.len(), num_enum_variants + 1);
                 let otherwise_block = *target_blocks.last().unwrap();
                 let tcx = self.tcx;
@@ -201,7 +201,7 @@ pub(super) fn perform_test(
                     otherwise_block,
                 );
                 debug!("num_enum_variants: {}, variants: {:?}", num_enum_variants, variants);
-                let discr_ty = adt_def.repr.discr_type().to_ty(tcx);
+                let discr_ty = adt_def.repr().discr_type().to_ty(tcx);
                 let discr = self.temp(discr_ty, test.span);
                 self.cfg.push_assign(
                     block,
@@ -733,7 +733,7 @@ fn candidate_after_slice_test<'pat>(
     fn candidate_after_variant_switch<'pat>(
         &mut self,
         match_pair_index: usize,
-        adt_def: &'tcx ty::AdtDef,
+        adt_def: ty::AdtDef<'tcx>,
         variant_index: VariantIdx,
         subpatterns: &'pat [FieldPat<'tcx>],
         candidate: &mut Candidate<'pat, 'tcx>,
@@ -744,7 +744,7 @@ fn candidate_after_variant_switch<'pat>(
         // we want to create a set of derived match-patterns like
         // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
         let elem =
-            ProjectionElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index);
+            ProjectionElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index);
         let downcast_place = match_pair.place.project(elem); // `(x as Variant)`
         let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
             // e.g., `(x as Variant).0`
@@ -798,7 +798,7 @@ pub(super) fn targets(&self) -> usize {
                 // variants, we have a target for each variant and the
                 // otherwise case, and we make sure that all of the cases not
                 // specified have the same block.
-                adt_def.variants.len() + 1
+                adt_def.variants().len() + 1
             }
             TestKind::SwitchInt { switch_ty, ref options, .. } => {
                 if switch_ty.is_bool() {
index b40d3e453e931153eb8e8434061bda83ab5f3446..2d1198edbc393899ec3c8d28281ad0698b2b1227 100644 (file)
@@ -162,7 +162,7 @@ fn visit_expr(&mut self, expr: &Expr<'tcx>) {
             ExprKind::Field { lhs, .. } => {
                 if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() {
                     if (Bound::Unbounded, Bound::Unbounded)
-                        != self.tcx.layout_scalar_valid_range(adt_def.did)
+                        != self.tcx.layout_scalar_valid_range(adt_def.did())
                     {
                         self.found = true;
                     }
@@ -242,7 +242,7 @@ fn visit_pat(&mut self, pat: &Pat<'tcx>) {
                         visit::walk_pat(self, pat);
                         self.in_union_destructure = old_in_union_destructure;
                     } else if (Bound::Unbounded, Bound::Unbounded)
-                        != self.tcx.layout_scalar_valid_range(adt_def.did)
+                        != self.tcx.layout_scalar_valid_range(adt_def.did())
                     {
                         let old_inside_adt = std::mem::replace(&mut self.inside_adt, true);
                         visit::walk_pat(self, pat);
@@ -386,7 +386,7 @@ fn visit_expr(&mut self, expr: &Expr<'tcx>) {
                 user_ty: _,
                 fields: _,
                 base: _,
-            }) => match self.tcx.layout_scalar_valid_range(adt_def.did) {
+            }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
                 (Bound::Unbounded, Bound::Unbounded) => {}
                 _ => self.requires_unsafe(expr.span, InitializingTypeWith),
             },
index dc11c76e07b237a1c8443a09986ed5f5c488c62a..23ee982489db2069efca36e4dba41542a6891b5a 100644 (file)
@@ -228,7 +228,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
                         let user_ty =
                             user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
                                 if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
-                                    *did = adt_def.did;
+                                    *did = adt_def.did();
                                 }
                                 u_ty
                             });
@@ -376,7 +376,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
                         let user_ty = user_provided_types.get(expr.hir_id).copied();
                         debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
                         ExprKind::Adt(Box::new(Adt {
-                            adt_def: adt,
+                            adt_def: *adt,
                             variant_index: VariantIdx::new(0),
                             substs,
                             user_ty,
@@ -402,7 +402,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
                                 let user_ty = user_provided_types.get(expr.hir_id).copied();
                                 debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
                                 ExprKind::Adt(Box::new(Adt {
-                                    adt_def: adt,
+                                    adt_def: *adt,
                                     variant_index: index,
                                     substs,
                                     user_ty,
@@ -680,7 +680,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
                                     let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
                                     let (d, o) = adt_def.discriminant_def_for_variant(idx);
                                     use rustc_middle::ty::util::IntTypeExt;
-                                    let ty = adt_def.repr.discr_type();
+                                    let ty = adt_def.repr().discr_type();
                                     let ty = ty.to_ty(self.tcx());
                                     Some((d, o, ty))
                                 }
@@ -924,7 +924,7 @@ fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKi
                     // A unit struct/variant which is used as a value.
                     // We return a completely different ExprKind here to account for this special case.
                     ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(Adt {
-                        adt_def,
+                        adt_def: *adt_def,
                         variant_index: adt_def.variant_index_with_ctor_id(def_id),
                         substs,
                         user_ty: user_provided_type,
index c94da838680e075cc4c2c049fe6bf3886b229ce4..e2c56df60148bd5b3b2102cbc007a8b24819b342 100644 (file)
@@ -395,17 +395,17 @@ fn check_for_bindings_named_same_as_variants(
             && let pat_ty = cx.typeck_results.pat_ty(p).peel_refs()
             && let ty::Adt(edef, _) = pat_ty.kind()
             && edef.is_enum()
-            && edef.variants.iter().any(|variant| {
+            && edef.variants().iter().any(|variant| {
                 variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const
             })
         {
-            let variant_count = edef.variants.len();
+            let variant_count = edef.variants().len();
             cx.tcx.struct_span_lint_hir(
                 BINDINGS_WITH_VARIANT_NAME,
                 p.hir_id,
                 p.span,
                 |lint| {
-                    let ty_path = cx.tcx.def_path_str(edef.did);
+                    let ty_path = cx.tcx.def_path_str(edef.did());
                     let mut err = lint.build(&format!(
                         "pattern binding `{}` is named the same as one \
                          of the variants of the type `{}`",
@@ -573,7 +573,7 @@ fn non_exhaustive_match<'p, 'tcx>(
 ) {
     let is_empty_match = arms.is_empty();
     let non_empty_enum = match scrut_ty.kind() {
-        ty::Adt(def, _) => def.is_enum() && !def.variants.is_empty(),
+        ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
         _ => false,
     };
     // In the case of an empty match, replace the '`_` not covered' diagnostic with something more
@@ -609,7 +609,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     };
 
     let is_variant_list_non_exhaustive = match scrut_ty.kind() {
-        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did.is_local() => true,
+        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => true,
         _ => false,
     };
 
@@ -762,17 +762,17 @@ fn adt_defined_here<'p, 'tcx>(
     if let ty::Adt(def, _) = ty.kind() {
         let mut spans = vec![];
         if witnesses.len() < 5 {
-            for sp in maybe_point_at_variant(cx, def, witnesses.iter()) {
+            for sp in maybe_point_at_variant(cx, *def, witnesses.iter()) {
                 spans.push(sp);
             }
         }
         let def_span = cx
             .tcx
             .hir()
-            .get_if_local(def.did)
+            .get_if_local(def.did())
             .and_then(|node| node.ident())
             .map(|ident| ident.span)
-            .unwrap_or_else(|| cx.tcx.def_span(def.did));
+            .unwrap_or_else(|| cx.tcx.def_span(def.did()));
         let mut span: MultiSpan =
             if spans.is_empty() { def_span.into() } else { spans.clone().into() };
 
@@ -786,17 +786,17 @@ fn adt_defined_here<'p, 'tcx>(
 
 fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
-    def: &AdtDef,
+    def: AdtDef<'tcx>,
     patterns: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>,
 ) -> Vec<Span> {
     use Constructor::*;
     let mut covered = vec![];
     for pattern in patterns {
         if let Variant(variant_index) = pattern.ctor() {
-            if let ty::Adt(this_def, _) = pattern.ty().kind() && this_def.did != def.did {
+            if let ty::Adt(this_def, _) = pattern.ty().kind() && this_def.did() != def.did() {
                 continue;
             }
-            let sp = def.variants[*variant_index].ident(cx.tcx).span;
+            let sp = def.variant(*variant_index).ident(cx.tcx).span;
             if covered.contains(&sp) {
                 // Don't point at variants that have already been covered due to other patterns to avoid
                 // visual clutter.
index b83cbb753df72ae88b76e48b4138c0ec46fe1a05..ae9b44cee4bf8fe07dbf803c20fe3a28b1720a91 100644 (file)
@@ -110,8 +110,8 @@ fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
-    fn adt_derive_msg(&self, adt_def: &AdtDef) -> String {
-        let path = self.tcx().def_path_str(adt_def.did);
+    fn adt_derive_msg(&self, adt_def: AdtDef<'tcx>) -> String {
+        let path = self.tcx().def_path_str(adt_def.did());
         format!(
             "to use a constant of type `{}` in a pattern, \
             `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@@ -346,7 +346,7 @@ fn recur(
                     adt_def,
                     cv.ty()
                 );
-                let path = tcx.def_path_str(adt_def.did);
+                let path = tcx.def_path_str(adt_def.did());
                 let msg = format!(
                     "to use a constant of type `{}` in a pattern, \
                      `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@@ -363,7 +363,7 @@ fn recur(
             ty::Adt(adt_def, substs) if adt_def.is_enum() => {
                 let destructured = tcx.destructure_const(param_env.and(cv));
                 PatKind::Variant {
-                    adt_def,
+                    adt_def: *adt_def,
                     substs,
                     variant_index: destructured
                         .variant
index 002c0b5f7d8ed3c4b2502dbb1d3ca5d029d0334d..612bed639bfb1f383232e5a8ca2a3e8d8daaf174 100644 (file)
@@ -681,7 +681,7 @@ fn as_slice(&self) -> Option<Slice> {
     /// This means that the variant has a stdlib unstable feature marking it.
     pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
         if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() {
-            let variant_def_id = adt.variants[*idx].def_id;
+            let variant_def_id = adt.variant(*idx).def_id;
             // Filter variants that depend on a disabled unstable feature.
             return matches!(
                 pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None),
@@ -692,16 +692,16 @@ pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
     }
 
     /// Checks if the `Constructor` is a `Constructor::Variant` with a `#[doc(hidden)]`
-    /// attribute.
+    /// attribute from a type not local to the current crate.
     pub(super) fn is_doc_hidden_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
         if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() {
-            let variant_def_id = adt.variants[*idx].def_id;
-            return pcx.cx.tcx.is_doc_hidden(variant_def_id);
+            let variant_def_id = adt.variants()[*idx].def_id;
+            return pcx.cx.tcx.is_doc_hidden(variant_def_id) && !variant_def_id.is_local();
         }
         false
     }
 
-    fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx {
+    fn variant_index_for_adt(&self, adt: ty::AdtDef<'tcx>) -> VariantIdx {
         match *self {
             Variant(idx) => idx,
             Single => {
@@ -725,7 +725,7 @@ pub(super) fn arity(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> usize {
                         // patterns. If we're here we can assume this is a box pattern.
                         1
                     } else {
-                        let variant = &adt.variants[self.variant_index_for_adt(adt)];
+                        let variant = &adt.variant(self.variant_index_for_adt(*adt));
                         Fields::list_variant_nonhidden_fields(pcx.cx, pcx.ty, variant).count()
                     }
                 }
@@ -973,10 +973,10 @@ pub(super) fn new<'p>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Self {
                 // exception is if the pattern is at the top level, because we want empty matches to be
                 // considered exhaustive.
                 let is_secretly_empty =
-                    def.variants.is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
+                    def.variants().is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
 
                 let mut ctors: SmallVec<[_; 1]> = def
-                    .variants
+                    .variants()
                     .iter_enumerated()
                     .filter(|(_, v)| {
                         // If `exhaustive_patterns` is enabled, we exclude variants known to be
@@ -1179,7 +1179,7 @@ fn list_variant_nonhidden_fields<'a>(
     ) -> impl Iterator<Item = (Field, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
         let ty::Adt(adt, substs) = ty.kind() else { bug!() };
         // Whether we must not match the fields of this variant exhaustively.
-        let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
+        let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
 
         variant.fields.iter().enumerate().filter_map(move |(i, field)| {
             let ty = field.ty(cx.tcx, substs);
@@ -1213,7 +1213,7 @@ pub(super) fn wildcards(
                         // patterns. If we're here we can assume this is a box pattern.
                         Fields::wildcards_from_tys(cx, once(substs.type_at(0)))
                     } else {
-                        let variant = &adt.variants[constructor.variant_index_for_adt(adt)];
+                        let variant = &adt.variant(constructor.variant_index_for_adt(*adt));
                         let tys = Fields::list_variant_nonhidden_fields(cx, ty, variant)
                             .map(|(_, ty)| ty);
                         Fields::wildcards_from_tys(cx, tys)
@@ -1346,7 +1346,7 @@ pub(crate) fn from_pat(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &Pat<'tcx>) -> Self {
                             PatKind::Variant { variant_index, .. } => Variant(*variant_index),
                             _ => bug!(),
                         };
-                        let variant = &adt.variants[ctor.variant_index_for_adt(adt)];
+                        let variant = &adt.variant(ctor.variant_index_for_adt(*adt));
                         // For each field in the variant, we store the relevant index into `self.fields` if any.
                         let mut field_id_to_id: Vec<Option<usize>> =
                             (0..variant.fields.len()).map(|_| None).collect();
@@ -1459,15 +1459,15 @@ pub(crate) fn to_pat(&self, cx: &MatchCheckCtxt<'p, 'tcx>) -> Pat<'tcx> {
                     PatKind::Deref { subpattern: subpatterns.next().unwrap() }
                 }
                 ty::Adt(adt_def, substs) => {
-                    let variant_index = self.ctor.variant_index_for_adt(adt_def);
-                    let variant = &adt_def.variants[variant_index];
+                    let variant_index = self.ctor.variant_index_for_adt(*adt_def);
+                    let variant = &adt_def.variant(variant_index);
                     let subpatterns = Fields::list_variant_nonhidden_fields(cx, self.ty, variant)
                         .zip(subpatterns)
                         .map(|((field, _ty), pattern)| FieldPat { field, pattern })
                         .collect();
 
                     if adt_def.is_enum() {
-                        PatKind::Variant { adt_def, substs, variant_index, subpatterns }
+                        PatKind::Variant { adt_def: *adt_def, substs, variant_index, subpatterns }
                     } else {
                         PatKind::Leaf { subpatterns }
                     }
@@ -1640,9 +1640,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 }
                 ty::Adt(..) | ty::Tuple(..) => {
                     let variant = match self.ty.kind() {
-                        ty::Adt(adt, _) => {
-                            Some(&adt.variants[self.ctor.variant_index_for_adt(adt)])
-                        }
+                        ty::Adt(adt, _) => Some(adt.variant(self.ctor.variant_index_for_adt(*adt))),
                         ty::Tuple(_) => None,
                         _ => unreachable!(),
                     };
index 6282b07e6f086e8fbd6a4f4805c7a05a7d956da7..d21fbb9edffb75ff648c8ae7ab3124e09d85466c 100644 (file)
@@ -653,7 +653,7 @@ fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self {
 
 CloneImpls! { <'tcx>
     Span, Field, Mutability, Symbol, hir::HirId, usize, ty::Const<'tcx>,
-    Region<'tcx>, Ty<'tcx>, BindingMode, &'tcx AdtDef,
+    Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>,
     SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
     UserTypeProjection, PatTyProj<'tcx>
 }
index 286473c38e36d2920fd15a34fab64d09c510a117..176723ab28b676905d58445e753f7c0167a9c2f3 100644 (file)
@@ -325,7 +325,7 @@ pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
     pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
         match ty.kind() {
             ty::Adt(def, ..) => {
-                def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did.is_local()
+                def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did().is_local()
             }
             _ => false,
         }
index aea8667314f485de7da65c35a936efe235e8adf4..82f97f22ccec4ed5cf792788c352e37791697a38 100644 (file)
@@ -20,7 +20,7 @@ fn user_substs_applied_to_ty_of_hir_id(
         match ty.kind() {
             ty::Adt(adt_def, ..) => {
                 if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
-                    *did = adt_def.did;
+                    *did = adt_def.did();
                 }
                 Some(user_ty)
             }
index 774df75211364a2d98794f36faeef621b8536744..84491d0c2ad198d092b32332d4fa56be41238937 100644 (file)
@@ -407,7 +407,7 @@ fn open_drop_for_tuple(&mut self, tys: &[Ty<'tcx>]) -> BasicBlock {
         self.drop_ladder(fields, succ, unwind).0
     }
 
-    fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
+    fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
         debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs);
 
         let interior = self.tcx().mk_place_deref(self.place);
@@ -420,9 +420,9 @@ fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>)
         self.drop_subpath(interior, interior_path, succ, unwind_succ)
     }
 
-    fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
+    fn open_drop_for_adt(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
         debug!("open_drop_for_adt({:?}, {:?}, {:?})", self, adt, substs);
-        if adt.variants.is_empty() {
+        if adt.variants().is_empty() {
             return self.elaborator.patch().new_block(BasicBlockData {
                 statements: vec![],
                 terminator: Some(Terminator {
@@ -434,7 +434,7 @@ fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>)
         }
 
         let skip_contents =
-            adt.is_union() || Some(adt.did) == self.tcx().lang_items().manually_drop();
+            adt.is_union() || Some(adt.did()) == self.tcx().lang_items().manually_drop();
         let contents_drop = if skip_contents {
             (self.succ, self.unwind)
         } else {
@@ -450,7 +450,7 @@ fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>)
 
     fn open_drop_for_adt_contents(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> (BasicBlock, Unwind) {
         let (succ, unwind) = self.drop_ladder_bottom();
@@ -458,7 +458,7 @@ fn open_drop_for_adt_contents(
             let fields = self.move_paths_for_fields(
                 self.place,
                 self.path,
-                &adt.variants[VariantIdx::new(0)],
+                &adt.variant(VariantIdx::new(0)),
                 substs,
             );
             self.drop_ladder(fields, succ, unwind)
@@ -469,22 +469,22 @@ fn open_drop_for_adt_contents(
 
     fn open_drop_for_multivariant(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         succ: BasicBlock,
         unwind: Unwind,
     ) -> (BasicBlock, Unwind) {
-        let mut values = Vec::with_capacity(adt.variants.len());
-        let mut normal_blocks = Vec::with_capacity(adt.variants.len());
+        let mut values = Vec::with_capacity(adt.variants().len());
+        let mut normal_blocks = Vec::with_capacity(adt.variants().len());
         let mut unwind_blocks =
-            if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants.len())) };
+            if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants().len())) };
 
         let mut have_otherwise_with_drop_glue = false;
         let mut have_otherwise = false;
         let tcx = self.tcx();
 
         for (variant_index, discr) in adt.discriminants(tcx) {
-            let variant = &adt.variants[variant_index];
+            let variant = &adt.variant(variant_index);
             let subpath = self.elaborator.downcast_subpath(self.path, variant_index);
 
             if let Some(variant_path) = subpath {
@@ -564,7 +564,7 @@ fn open_drop_for_multivariant(
 
     fn adt_switch_block(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         blocks: Vec<BasicBlock>,
         values: &[u128],
         succ: BasicBlock,
@@ -577,7 +577,7 @@ fn adt_switch_block(
         // Additionally, we do not want to switch on the
         // discriminant after it is free-ed, because that
         // way lies only trouble.
-        let discr_ty = adt.repr.discr_type().to_ty(self.tcx());
+        let discr_ty = adt.repr().discr_type().to_ty(self.tcx());
         let discr = Place::from(self.new_temp(discr_ty));
         let discr_rv = Rvalue::Discriminant(self.place);
         let switch_block = BasicBlockData {
@@ -869,9 +869,9 @@ fn open_drop(&mut self) -> BasicBlock {
             ty::Tuple(fields) => self.open_drop_for_tuple(fields),
             ty::Adt(def, substs) => {
                 if def.is_box() {
-                    self.open_drop_for_box(def, substs)
+                    self.open_drop_for_box(*def, substs)
                 } else {
-                    self.open_drop_for_adt(def, substs)
+                    self.open_drop_for_adt(*def, substs)
                 }
             }
             ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
@@ -927,7 +927,7 @@ fn elaborated_drop_block(&mut self) -> BasicBlock {
     /// The contained value will not be dropped.
     fn box_free_block(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         target: BasicBlock,
         unwind: Unwind,
@@ -940,7 +940,7 @@ fn box_free_block(
     /// value).
     fn unelaborated_free_block(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         target: BasicBlock,
         unwind: Unwind,
@@ -948,7 +948,8 @@ fn unelaborated_free_block(
         let tcx = self.tcx();
         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.variants[VariantIdx::new(0)]
+        let args = adt
+            .variant(VariantIdx::new(0))
             .fields
             .iter()
             .enumerate()
index 7d6a08d47dae1bb7eb84e24e3be5c2d28f848d16..87c1060f55257b4fb840b838fc0d365266567250 100644 (file)
@@ -705,14 +705,14 @@ fn switch_on_enum_discriminant<'mir, 'tcx>(
     body: &'mir mir::Body<'tcx>,
     block: &'mir mir::BasicBlockData<'tcx>,
     switch_on: mir::Place<'tcx>,
-) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
+) -> Option<(mir::Place<'tcx>, ty::AdtDef<'tcx>)> {
     for statement in block.statements.iter().rev() {
         match &statement.kind {
             mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))
                 if *lhs == switch_on =>
             {
-                match &discriminated.ty(body, tcx).ty.kind() {
-                    ty::Adt(def, _) => return Some((*discriminated, def)),
+                match discriminated.ty(body, tcx).ty.kind() {
+                    ty::Adt(def, _) => return Some((*discriminated, *def)),
 
                     // `Rvalue::Discriminant` is also used to get the active yield point for a
                     // generator, but we do not need edge-specific effects in that case. This may
index 87b9244c068edd7044aa68297c4748a9245a00eb..9d198ef2f7a05003aabadbaaeef8a35126526c4d 100644 (file)
@@ -336,7 +336,7 @@ fn check_mut_borrowing_layout_constrained_field(
                 ProjectionElem::Field(..) => {
                     let ty = place_base.ty(&self.body.local_decls, self.tcx).ty;
                     if let ty::Adt(def, _) = ty.kind() {
-                        if self.tcx.layout_scalar_valid_range(def.did)
+                        if self.tcx.layout_scalar_valid_range(def.did())
                             != (Bound::Unbounded, Bound::Unbounded)
                         {
                             let details = if is_mut_use {
index d9a66cace52e5bd4013afd1d0fd67480b29b781f..8bc7f5e9ce2e0e467260c13ec16293e3e663935f 100644 (file)
@@ -210,7 +210,7 @@ struct SuspensionPoint<'tcx> {
 
 struct TransformVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    state_adt_ref: &'tcx AdtDef,
+    state_adt_ref: AdtDef<'tcx>,
     state_substs: SubstsRef<'tcx>,
 
     // The type of the discriminant in the generator struct
@@ -243,11 +243,11 @@ fn make_state(
         val: Operand<'tcx>,
         source_info: SourceInfo,
     ) -> impl Iterator<Item = Statement<'tcx>> {
-        let kind = AggregateKind::Adt(self.state_adt_ref.did, idx, self.state_substs, None, None);
-        assert_eq!(self.state_adt_ref.variants[idx].fields.len(), 1);
+        let kind = AggregateKind::Adt(self.state_adt_ref.did(), idx, self.state_substs, None, None);
+        assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1);
         let ty = self
             .tcx
-            .type_of(self.state_adt_ref.variants[idx].fields[0].did)
+            .type_of(self.state_adt_ref.variant(idx).fields[0].did)
             .subst(self.tcx, self.state_substs);
         expand_aggregate(
             Place::return_place(),
index 4167f8df11cd8b09c517bb2f33626606a3fc5d95..d7fb706311434b8bcfd3a8509f2919fb26cf008e 100644 (file)
@@ -124,7 +124,7 @@ fn is_needs_drop_and_init<'tcx>(
             //
             // If its projection *is* present in `MoveData`, then the field may have been moved
             // from separate from its parent. Recurse.
-            adt.variants.iter_enumerated().any(|(vid, variant)| {
+            adt.variants().iter_enumerated().any(|(vid, variant)| {
                 // Enums have multiple variants, which are discriminated with a `Downcast` projection.
                 // Structs have a single variant, and don't use a `Downcast` projection.
                 let mpi = if adt.is_enum() {
index 9533e869bc59682a9c6b72f34c15aa58010b14b6..bf031b423c2e503e7841a6e335c6d1093798b548 100644 (file)
@@ -760,10 +760,10 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
 
     let statements = expand_aggregate(
         Place::return_place(),
-        adt_def.variants[variant_index].fields.iter().enumerate().map(|(idx, field_def)| {
+        adt_def.variant(variant_index).fields.iter().enumerate().map(|(idx, field_def)| {
             (Operand::Move(Place::from(Local::new(idx + 1))), field_def.ty(tcx, substs))
         }),
-        AggregateKind::Adt(adt_def.did, variant_index, substs, None, None),
+        AggregateKind::Adt(adt_def.did(), variant_index, substs, None, None),
         source_info,
         tcx,
     )
index abd75c20524e9640fe6ceb652721855cce0ada3f..884c5fb765f421cbdc22dfdefba928b0d0e5963d 100644 (file)
@@ -726,7 +726,7 @@ fn statement_equality(
                 );
                 return StatementEquality::NotEqual;
             }
-            let variant_is_fieldless = adt.variants[variant_index].fields.is_empty();
+            let variant_is_fieldless = adt.variant(variant_index).fields.is_empty();
             if !variant_is_fieldless {
                 trace!("NO: variant {:?} was not fieldless", variant_index);
                 return StatementEquality::NotEqual;
index 40daf4eb28fc1b558e78fbf8e1b016b048b731ac..21d5bec65f03a8f57d2a19d087eb17f08836d315 100644 (file)
@@ -2073,6 +2073,19 @@ pub fn recover_const_arg(
                     let value = self.mk_expr_err(start.to(expr.span));
                     err.emit();
                     return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
+                } else if token::Colon == snapshot.token.kind
+                    && expr.span.lo() == snapshot.token.span.hi()
+                    && matches!(expr.kind, ExprKind::Path(..))
+                {
+                    // Find a mistake like "foo::var:A".
+                    err.span_suggestion(
+                        snapshot.token.span,
+                        "write a path separator here",
+                        "::".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                    err.emit();
+                    return Ok(GenericArg::Type(self.mk_ty(start.to(expr.span), TyKind::Err)));
                 } else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
                 {
                     // Avoid the following output by checking that we consumed a full const arg:
index 06460c7b1b31ddcc8e21ec89ff01fe4bdbfb2c00..122fe10e80f8fb331ce3aab4cae7a15c923ec420 100644 (file)
@@ -1534,6 +1534,16 @@ fn parse_name_and_ty(
         let name = self.parse_field_ident(adt_ty, lo)?;
         self.expect_field_ty_separator()?;
         let ty = self.parse_ty()?;
+        if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
+            self.struct_span_err(self.token.span, "found single colon in a struct field type path")
+                .span_suggestion_verbose(
+                    self.token.span,
+                    "write a path separator here",
+                    "::".to_string(),
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
+        }
         if self.token.kind == token::Eq {
             self.bump();
             let const_expr = self.parse_anon_const_expr()?;
index e438b521a952b8ccc8b38aac9a1e7b61b2a51891..c777074df46411d1528bc6daba50c2bd6e5a4967 100644 (file)
@@ -259,7 +259,7 @@ fn should_ignore_item(&mut self, def_id: DefId) -> bool {
                 if self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) {
                     let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap();
                     if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() {
-                        if let Some(adt_def_id) = adt_def.did.as_local() {
+                        if let Some(adt_def_id) = adt_def.did().as_local() {
                             self.ignored_derived_traits
                                 .entry(adt_def_id)
                                 .or_default()
@@ -297,7 +297,7 @@ fn visit_node(&mut self, node: Node<'tcx>) {
                 match item.kind {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
                         let def = self.tcx.adt_def(item.def_id);
-                        self.repr_has_repr_c = def.repr.c();
+                        self.repr_has_repr_c = def.repr().c();
 
                         intravisit::walk_item(self, &item);
                     }
@@ -328,8 +328,8 @@ fn visit_node(&mut self, node: Node<'tcx>) {
         self.repr_has_repr_c = had_repr_c;
     }
 
-    fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &[hir::ExprField<'_>]) {
-        if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did.is_local() {
+    fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) {
+        if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() {
             for field in fields {
                 let index = self.tcx.field_index(field.hir_id, self.typeck_results());
                 self.insert_def_id(adt.non_enum_variant().fields[index].did);
@@ -382,8 +382,8 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
             hir::ExprKind::Struct(ref qpath, ref fields, _) => {
                 let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
                 self.handle_res(res);
-                if let ty::Adt(ref adt, _) = self.typeck_results().expr_ty(expr).kind() {
-                    self.mark_as_used_if_union(adt, fields);
+                if let ty::Adt(adt, _) = self.typeck_results().expr_ty(expr).kind() {
+                    self.mark_as_used_if_union(*adt, fields);
                 }
             }
             _ => (),
index b2129ce9f24fc63a149cea3798e4cf194f2de907..6316f3b845914e481acec254e899af541a5939ab 100644 (file)
@@ -38,22 +38,22 @@ struct ExprVisitor<'tcx> {
 fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     let ty::Adt(def, substs) = *ty.kind() else { return ty };
 
-    if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() {
+    if def.variants().len() == 2 && !def.repr().c() && def.repr().int.is_none() {
         let data_idx;
 
         let one = VariantIdx::new(1);
         let zero = VariantIdx::new(0);
 
-        if def.variants[zero].fields.is_empty() {
+        if def.variant(zero).fields.is_empty() {
             data_idx = one;
-        } else if def.variants[one].fields.is_empty() {
+        } else if def.variant(one).fields.is_empty() {
             data_idx = zero;
         } else {
             return ty;
         }
 
-        if def.variants[data_idx].fields.len() == 1 {
-            return def.variants[data_idx].fields[0].ty(tcx, substs);
+        if def.variant(data_idx).fields.len() == 1 {
+            return def.variant(data_idx).fields[0].ty(tcx, substs);
         }
     }
 
@@ -165,7 +165,7 @@ fn check_asm_operand_type(
             ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
                 Some(asm_ty_isize)
             }
-            ty::Adt(adt, substs) if adt.repr.simd() => {
+            ty::Adt(adt, substs) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
                 let elem_ty = fields[0].ty(self.tcx, substs);
                 match elem_ty.kind() {
index fd1c0239b596511b011a76acd04436b0d90ff95c..fdda77d01b3febd8d4e31bea13d516dd5561d1ab 100644 (file)
@@ -9,6 +9,7 @@
 use rustc_ast::MacroDef;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::intern::Interned;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -182,7 +183,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
         let tcx = self.def_id_visitor.tcx();
         // InternalSubsts are not visited here because they are visited below in `super_visit_with`.
         match *ty.kind() {
-            ty::Adt(&ty::AdtDef { did: def_id, .. }, ..)
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..)
             | ty::Foreign(def_id)
             | ty::FnDef(def_id, ..)
             | ty::Closure(def_id, ..)
@@ -930,7 +931,7 @@ fn check_field(
         &mut self,
         use_ctxt: Span,        // syntax context of the field name at the use site
         span: Span,            // span of the field pattern, e.g., `x: 0`
-        def: &'tcx ty::AdtDef, // definition of the struct or enum
+        def: ty::AdtDef<'tcx>, // definition of the struct or enum
         field: &'tcx ty::FieldDef,
         in_update_syntax: bool,
     ) {
@@ -941,7 +942,7 @@ fn check_field(
         // definition of the field
         let ident = Ident::new(kw::Empty, use_ctxt);
         let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item);
-        let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, hir_id).1;
+        let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1;
         if !field.vis.is_accessible_from(def_id, self.tcx) {
             let label = if in_update_syntax {
                 format!("field `{}` is private", field.name)
@@ -956,7 +957,7 @@ fn check_field(
                 "field `{}` of {} `{}` is private",
                 field.name,
                 def.variant_descr(),
-                self.tcx.def_path_str(def.did)
+                self.tcx.def_path_str(def.did())
             )
             .span_label(span, label)
             .emit();
index cf71f9b3fc5aaa9076c3e016d8e4cf9cd5f0de38..d071d66ffa6303149d3310576c75ef7266a8488c 100644 (file)
@@ -554,7 +554,7 @@ pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option<Data> {
                     Some(Data::RefData(Ref {
                         kind: RefKind::Type,
                         span,
-                        ref_id: id_from_def_id(def.did),
+                        ref_id: id_from_def_id(def.did()),
                     }))
                 }
                 _ => {
index a9c41ce0c4ea4033bdfecb76bd9c261cafd5eff2..c8fdf363f053eb24e81663977a63886908a24c34 100644 (file)
@@ -1,5 +1,6 @@
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::intern::Interned;
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -453,7 +454,7 @@ fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
             }
 
             // Mangle all nominal types as paths.
-            ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
             | ty::FnDef(def_id, substs)
             | ty::Opaque(def_id, substs)
             | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
@@ -684,7 +685,7 @@ fn print_const(mut self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error
                     ty::Adt(def, substs) => {
                         let variant_idx =
                             contents.variant.expect("destructed const of adt without variant idx");
-                        let variant_def = &def.variants[variant_idx];
+                        let variant_def = &def.variant(variant_idx);
 
                         self.push("V");
                         self = self.print_def_path(variant_def.def_id, substs)?;
index 63efa951f9674717f5af28044c85678c20160027..a3d32acc6fb823ddf2e22f83b72d721020579c2c 100644 (file)
@@ -676,7 +676,7 @@ fn fundamental_ty_inner_tys<'tcx>(
             match types.next() {
                 None => {
                     tcx.sess.span_err(
-                        tcx.def_span(def.did),
+                        tcx.def_span(def.did()),
                         "`#[fundamental]` requires at least one type parameter",
                     );
 
@@ -729,7 +729,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
             InCrate::Remote => true,
         },
 
-        ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
+        ty::Adt(def, _) => def_id_is_local(def.did(), in_crate),
         ty::Foreign(did) => def_id_is_local(did, in_crate),
         ty::Opaque(..) => {
             // This merits some explanation.
index ccbd2dedfeab193328d9a78e3e0a8ba7a609646c..28c596c4e53f0d9eaa537ef603a5118ad8ffbebe 100644 (file)
@@ -813,7 +813,7 @@ fn report_selection_error(
                     | ty::Foreign(did)
                     | ty::FnDef(did, _)
                     | ty::Generator(did, ..) => Some(did),
-                    ty::Adt(def, _) => Some(def.did),
+                    ty::Adt(def, _) => Some(def.did()),
                     _ => None,
                 };
 
@@ -1467,7 +1467,7 @@ fn type_category(tcx: TyCtxt<'_>, t: Ty<'_>) -> Option<u32> {
                 ty::Bool => Some(0),
                 ty::Char => Some(1),
                 ty::Str => Some(2),
-                ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did) => Some(2),
+                ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did()) => Some(2),
                 ty::Int(..)
                 | ty::Uint(..)
                 | ty::Float(..)
index 59c88b6603c228aa1f8f7fde58ad0ad65d9d7bc1..d2b1fe2e0df9b8d17bc3db988d55711b28aae2a9 100644 (file)
@@ -172,7 +172,7 @@ fn on_unimplemented_note(
             if let Some(def) = self_ty.ty_adt_def() {
                 // We also want to be able to select self's original
                 // signature with no type arguments resolved
-                flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string())));
+                flags.push((sym::_Self, Some(self.tcx.type_of(def.did()).to_string())));
             }
 
             for param in generics.params.iter() {
@@ -190,12 +190,12 @@ fn on_unimplemented_note(
                     if let Some(def) = param_ty.ty_adt_def() {
                         // We also want to be able to select the parameter's
                         // original signature with no type arguments resolved
-                        flags.push((name, Some(self.tcx.type_of(def.did).to_string())));
+                        flags.push((name, Some(self.tcx.type_of(def.did()).to_string())));
                     }
                 }
             }
 
-            if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
+            if let Some(true) = self_ty.ty_adt_def().map(|def| def.did().is_local()) {
                 flags.push((sym::crate_local, None));
             }
 
@@ -214,7 +214,7 @@ fn on_unimplemented_note(
                 if let Some(def) = aty.ty_adt_def() {
                     // We also want to be able to select the array's type's original
                     // signature with no type arguments resolved
-                    let type_string = self.tcx.type_of(def.did).to_string();
+                    let type_string = self.tcx.type_of(def.did()).to_string();
                     flags.push((sym::_Self, Some(format!("[{}]", type_string))));
 
                     let len =
index f2ddc3ea7fa3909eebfebdd593ef60acc0fbf0a1..b617067e66dddea6b1e38fa05075e92f0726c9c9 100644 (file)
@@ -2129,7 +2129,7 @@ fn note_obligation_cause_code<T>(
                 if !is_upvar_tys_infer_tuple {
                     let msg = format!("required because it appears within the type `{}`", ty);
                     match ty.kind() {
-                        ty::Adt(def, _) => match self.tcx.opt_item_name(def.did) {
+                        ty::Adt(def, _) => match self.tcx.opt_item_name(def.did()) {
                             Some(ident) => err.span_note(ident.span, &msg),
                             None => err.note(&msg),
                         },
index c293708dcc9296017383fca25f247c334f6a12f1..08308253ced5f15ef837f53e73bd1be6653318b1 100644 (file)
@@ -43,7 +43,7 @@ pub fn can_type_implement_copy<'tcx>(
         };
 
         let mut infringing = Vec::new();
-        for variant in &adt.variants {
+        for variant in adt.variants() {
             for field in &variant.fields {
                 let ty = field.ty(tcx, substs);
                 if ty.references_error() {
@@ -56,7 +56,7 @@ pub fn can_type_implement_copy<'tcx>(
                 // If it does not, then this field probably doesn't normalize
                 // to begin with, and point to the bad field's span instead.
                 let cause = if field
-                    .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did))
+                    .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did()))
                     .has_param_types_or_consts()
                 {
                     cause.clone()
index 435d709d37e60987cc30676d1fe79b90571edb25..2df0d9f0f6fb223e0434c78e86a1d2542a516b66 100644 (file)
@@ -112,7 +112,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
         }
 
         ty::Adt(def, _) => {
-            if Some(def.did) == tcx.lang_items().manually_drop() {
+            if Some(def.did()) == tcx.lang_items().manually_drop() {
                 // `ManuallyDrop` never has a dtor.
                 true
             } else {
index 2ed7a8f9cf9ea2d2f4366289f3f6f6a5ee3ab43d..67e3bf80486a822afd484c6e353881ad4e2c942e 100644 (file)
@@ -12,7 +12,7 @@
 
 #[derive(Debug)]
 pub enum NonStructuralMatchTy<'tcx> {
-    Adt(&'tcx AdtDef),
+    Adt(AdtDef<'tcx>),
     Param,
     Dynamic,
     Foreign,
@@ -208,14 +208,14 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
             }
         };
 
-        if !self.seen.insert(adt_def.did) {
+        if !self.seen.insert(adt_def.did()) {
             debug!("Search already seen adt_def: {:?}", adt_def);
             return ControlFlow::CONTINUE;
         }
 
         if !self.type_marked_structural(ty) {
             debug!("Search found ty: {:?}", ty);
-            return ControlFlow::Break(NonStructuralMatchTy::Adt(&adt_def));
+            return ControlFlow::Break(NonStructuralMatchTy::Adt(adt_def));
         }
 
         // structural-match does not care about the
index 943f36efc153fb7521f4bf7338239a145cc99f1f..b4ed5b95b10473046e42665872548e633561f4d6 100644 (file)
@@ -540,7 +540,7 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
 
                 ty::Adt(def, substs) => {
                     // WfNominalType
-                    let obligations = self.nominal_obligations(def.did, substs);
+                    let obligations = self.nominal_obligations(def.did(), substs);
                     self.out.extend(obligations);
                 }
 
index 47b1ee04e777fabb649564c68243fe66e5f20465..9b85242e90a71ff5a8c6487c1f0314522dd6d284 100644 (file)
@@ -166,13 +166,13 @@ fn adt_datum(
     ) -> Arc<chalk_solve::rust_ir::AdtDatum<RustInterner<'tcx>>> {
         let adt_def = adt_id.0;
 
-        let bound_vars = bound_vars_for_item(self.interner.tcx, adt_def.did);
+        let bound_vars = bound_vars_for_item(self.interner.tcx, adt_def.did());
         let binders = binders_for(self.interner, bound_vars);
 
-        let where_clauses = self.where_clauses_for(adt_def.did, bound_vars);
+        let where_clauses = self.where_clauses_for(adt_def.did(), bound_vars);
 
         let variants: Vec<_> = adt_def
-            .variants
+            .variants()
             .iter()
             .map(|variant| chalk_solve::rust_ir::AdtVariantDatum {
                 fields: variant
@@ -189,7 +189,7 @@ fn adt_datum(
                 chalk_solve::rust_ir::AdtDatumBound { variants, where_clauses },
             ),
             flags: chalk_solve::rust_ir::AdtFlags {
-                upstream: !adt_def.did.is_local(),
+                upstream: !adt_def.did().is_local(),
                 fundamental: adt_def.is_fundamental(),
                 phantom_data: adt_def.is_phantom_data(),
             },
@@ -209,9 +209,9 @@ fn adt_repr(
         let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)).intern(self.interner);
         let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)).intern(self.interner);
         Arc::new(chalk_solve::rust_ir::AdtRepr {
-            c: adt_def.repr.c(),
-            packed: adt_def.repr.packed(),
-            int: adt_def.repr.int.map(|i| match i {
+            c: adt_def.repr().c(),
+            packed: adt_def.repr().packed(),
+            int: adt_def.repr().int.map(|i| match i {
                 attr::IntType::SignedInt(ty) => match ty {
                     ast::IntTy::Isize => int(chalk_ir::IntTy::Isize),
                     ast::IntTy::I8 => int(chalk_ir::IntTy::I8),
@@ -354,7 +354,7 @@ fn impl_provided_for(
             let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap();
             let self_ty = trait_ref.self_ty();
             let provides = match (self_ty.kind(), chalk_ty) {
-                (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did == id.0.did,
+                (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did() == id.0.did(),
                 (_, AssociatedType(_ty_id, ..)) => {
                     // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774
                     false
@@ -671,7 +671,7 @@ fn adt_variance(
         &self,
         adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
     ) -> chalk_ir::Variances<RustInterner<'tcx>> {
-        let variances = self.interner.tcx.variances_of(adt_id.0.did);
+        let variances = self.interner.tcx.variances_of(adt_id.0.did());
         chalk_ir::Variances::from_iter(
             self.interner,
             variances.iter().map(|v| v.lower_into(self.interner)),
index 3658f8e57356ba58f920632c04739238b644a6e8..df5df176186a16da84826e61cce915f3ecc9d04f 100644 (file)
@@ -268,7 +268,7 @@ fn dtorck_constraint_for_ty<'tcx>(
 
         ty::Adt(def, substs) => {
             let DtorckConstraint { dtorck_types, outlives, overflows } =
-                tcx.at(span).adt_dtorck_constraint(def.did)?;
+                tcx.at(span).adt_dtorck_constraint(def.did())?;
             // FIXME: we can try to recursively `dtorck_constraint_on_ty`
             // there, but that needs some way to handle cycles.
             constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs)));
index 322511be817fb08e6642aa7bceb5375edfc43667..6195c712c58940b8dad828ebb2bd85ce1ff34c56 100644 (file)
@@ -16,7 +16,7 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
     // parameter without a `Copy` bound, then we conservatively return that it
     // needs drop.
     let adt_has_dtor =
-        |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
+        |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant);
     let res =
         drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some();
 
@@ -78,7 +78,7 @@ fn new(
 
 impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F>
 where
-    F: Fn(&ty::AdtDef, SubstsRef<'tcx>) -> NeedsDropResult<I>,
+    F: Fn(ty::AdtDef<'tcx>, SubstsRef<'tcx>) -> NeedsDropResult<I>,
     I: Iterator<Item = Ty<'tcx>>,
 {
     type Item = NeedsDropResult<Ty<'tcx>>;
@@ -193,7 +193,7 @@ fn drop_tys_helper<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
     param_env: rustc_middle::ty::ParamEnv<'tcx>,
-    adt_has_dtor: impl Fn(&ty::AdtDef) -> Option<DtorType>,
+    adt_has_dtor: impl Fn(ty::AdtDef<'tcx>) -> Option<DtorType>,
     only_significant: bool,
 ) -> impl Iterator<Item = NeedsDropResult<Ty<'tcx>>> {
     fn with_query_cache<'tcx>(
@@ -203,7 +203,7 @@ fn with_query_cache<'tcx>(
         iter.into_iter().try_fold(Vec::new(), |mut vec, subty| {
             match subty.kind() {
                 ty::Adt(adt_id, subst) => {
-                    for subty in tcx.adt_drop_tys(adt_id.did)? {
+                    for subty in tcx.adt_drop_tys(adt_id.did())? {
                         vec.push(subty.subst(tcx, subst));
                     }
                 }
@@ -213,7 +213,7 @@ fn with_query_cache<'tcx>(
         })
     }
 
-    let adt_components = move |adt_def: &ty::AdtDef, substs: SubstsRef<'tcx>| {
+    let adt_components = move |adt_def: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>| {
         if adt_def.is_manually_drop() {
             debug!("drop_tys_helper: `{:?}` is manually drop", adt_def);
             Ok(Vec::new())
@@ -260,9 +260,9 @@ fn with_query_cache<'tcx>(
 
 fn adt_consider_insignificant_dtor<'tcx>(
     tcx: TyCtxt<'tcx>,
-) -> impl Fn(&ty::AdtDef) -> Option<DtorType> + 'tcx {
-    move |adt_def: &ty::AdtDef| {
-        let is_marked_insig = tcx.has_attr(adt_def.did, sym::rustc_insignificant_dtor);
+) -> impl Fn(ty::AdtDef<'tcx>) -> Option<DtorType> + 'tcx {
+    move |adt_def: ty::AdtDef<'tcx>| {
+        let is_marked_insig = tcx.has_attr(adt_def.did(), sym::rustc_insignificant_dtor);
         if is_marked_insig {
             // In some cases like `std::collections::HashMap` where the struct is a wrapper around
             // a type that is a Drop type, and the wrapped type (eg: `hashbrown::HashMap`) lies
@@ -281,11 +281,14 @@ fn adt_consider_insignificant_dtor<'tcx>(
     }
 }
 
-fn adt_drop_tys(tcx: TyCtxt<'_>, def_id: DefId) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> {
+fn adt_drop_tys<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+) -> Result<&ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
     // This is for the "adt_drop_tys" query, that considers all `Drop` impls, therefore all dtors are
     // significant.
     let adt_has_dtor =
-        |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
+        |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant);
     // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_substs)`
     drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor, false)
         .collect::<Result<Vec<_>, _>>()
index 11a57688580a67025100b68ccadb057fd2f66837..b8f3efe6462ead3ebc863767033ab19b1611f031 100644 (file)
@@ -33,7 +33,7 @@ pub fn ty_is_representable<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, sp: Span) -> R
     // cleared when recursing to check A, but `shadow_seen` won't, so that we
     // can catch cases of mutual recursion where A also contains B).
     let mut seen: Vec<Ty<'_>> = Vec::new();
-    let mut shadow_seen: Vec<&'tcx ty::AdtDef> = Vec::new();
+    let mut shadow_seen: Vec<ty::AdtDef<'tcx>> = Vec::new();
     let mut representable_cache = FxHashMap::default();
     let mut force_result = false;
     let r = is_type_structurally_recursive(
@@ -63,7 +63,7 @@ fn are_inner_types_recursive<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
     seen: &mut Vec<Ty<'tcx>>,
-    shadow_seen: &mut Vec<&'tcx ty::AdtDef>,
+    shadow_seen: &mut Vec<ty::AdtDef<'tcx>>,
     representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
     ty: Ty<'tcx>,
     force_result: &mut bool,
@@ -150,7 +150,7 @@ fn are_inner_types_recursive<'tcx>(
                             .take(shadow_seen.len() - 1)
                             .any(|seen_def| seen_def == def)
                     {
-                        let adt_def_id = def.did;
+                        let adt_def_id = def.did();
                         let raw_adt_ty = tcx.type_of(adt_def_id);
                         debug!("are_inner_types_recursive: checking nested type: {:?}", raw_adt_ty);
 
@@ -236,7 +236,7 @@ fn are_inner_types_recursive<'tcx>(
     }
 }
 
-fn same_adt<'tcx>(ty: Ty<'tcx>, def: &'tcx ty::AdtDef) -> bool {
+fn same_adt<'tcx>(ty: Ty<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
     match *ty.kind() {
         ty::Adt(ty_def, _) => ty_def == def,
         _ => false,
@@ -249,7 +249,7 @@ fn is_type_structurally_recursive<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
     seen: &mut Vec<Ty<'tcx>>,
-    shadow_seen: &mut Vec<&'tcx ty::AdtDef>,
+    shadow_seen: &mut Vec<ty::AdtDef<'tcx>>,
     representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
     ty: Ty<'tcx>,
     force_result: &mut bool,
@@ -281,7 +281,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
     seen: &mut Vec<Ty<'tcx>>,
-    shadow_seen: &mut Vec<&'tcx ty::AdtDef>,
+    shadow_seen: &mut Vec<ty::AdtDef<'tcx>>,
     representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
     ty: Ty<'tcx>,
     force_result: &mut bool,
@@ -332,7 +332,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
             // For structs and enums, track all previously seen types by pushing them
             // onto the 'seen' stack.
             seen.push(ty);
-            shadow_seen.push(def);
+            shadow_seen.push(*def);
             let out = are_inner_types_recursive(
                 tcx,
                 sp,
index e6ce3447548de4cf2e9894b5af4b149e06d9fd54..44ef0a09a654bd2fff7ceea1e0fe9b4f834640d8 100644 (file)
@@ -8,7 +8,7 @@
 
 fn sized_constraint_for_ty<'tcx>(
     tcx: TyCtxt<'tcx>,
-    adtdef: &ty::AdtDef,
+    adtdef: ty::AdtDef<'tcx>,
     ty: Ty<'tcx>,
 ) -> Vec<Ty<'tcx>> {
     use ty::TyKind::*;
@@ -56,7 +56,7 @@ fn sized_constraint_for_ty<'tcx>(
             })
             .without_const()
             .to_predicate(tcx);
-            let predicates = tcx.predicates_of(adtdef.did).predicates;
+            let predicates = tcx.predicates_of(adtdef.did()).predicates;
             if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
         }
 
@@ -99,7 +99,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstrain
     let def = tcx.adt_def(def_id);
 
     let result = tcx.mk_type_list(
-        def.variants
+        def.variants()
             .iter()
             .flat_map(|v| v.fields.last())
             .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did))),
@@ -454,7 +454,7 @@ pub fn conservative_is_privately_uninhabited_raw<'tcx>(
             // (a) It has no variants (i.e. an empty `enum`);
             // (b) Each of its variants (a single one in the case of a `struct`) has at least
             //     one uninhabited field.
-            def.variants.iter().all(|var| {
+            def.variants().iter().all(|var| {
                 var.fields.iter().any(|field| {
                     let ty = tcx.type_of(field.did).subst(tcx, substs);
                     tcx.conservative_is_privately_uninhabited(param_env.and(ty))
index d409cedddda8d2b7210a54fbff10fdb6a0cea658..144953caa4c3be3a4e5e7438bf3178632947cc82 100644 (file)
@@ -1788,9 +1788,9 @@ pub fn associated_path_to_ty(
         if let ty::Adt(adt_def, _) = qself_ty.kind() {
             if adt_def.is_enum() {
                 let variant_def = adt_def
-                    .variants
+                    .variants()
                     .iter()
-                    .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did));
+                    .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did()));
                 if let Some(variant_def) = variant_def {
                     if permit_variants {
                         tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
@@ -1845,7 +1845,7 @@ pub fn associated_path_to_ty(
                     let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
                     if let Some(suggested_name) = find_best_match_for_name(
                         &adt_def
-                            .variants
+                            .variants()
                             .iter()
                             .map(|variant| variant.name)
                             .collect::<Vec<Symbol>>(),
@@ -1865,7 +1865,7 @@ pub fn associated_path_to_ty(
                         );
                     }
 
-                    if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
+                    if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
                         let sp = tcx.sess.source_map().guess_head_span(sp);
                         err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
                     }
@@ -2154,7 +2154,7 @@ pub fn def_ids_for_value_path_segments(
                 let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
                 let (generics_def_id, index) = if let Some(adt_def) = adt_def {
                     debug_assert!(adt_def.is_enum());
-                    (adt_def.did, last)
+                    (adt_def.did(), last)
                 } else if last >= 1 && segments[last - 1].args.is_some() {
                     // Everything but the penultimate segment should have no
                     // parameters at all.
index 7c3594175b85508ed4c10ac92fc306d6cbf79d52..9016a8ffe9add582bc205c654db926165762a35a 100644 (file)
@@ -269,7 +269,7 @@ pub(super) fn check_fn<'a, 'tcx>(
                     let arg_is_panic_info = match *inputs[0].kind() {
                         ty::Ref(region, ty, mutbl) => match *ty.kind() {
                             ty::Adt(ref adt, _) => {
-                                adt.did == panic_info_did
+                                adt.did() == panic_info_did
                                     && mutbl == hir::Mutability::Not
                                     && !region.is_static()
                             }
@@ -310,7 +310,7 @@ pub(super) fn check_fn<'a, 'tcx>(
                 let span = hir.span(fn_id);
                 if inputs.len() == 1 {
                     let arg_is_alloc_layout = match inputs[0].kind() {
-                        ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
+                        ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
                         _ => false,
                     };
 
@@ -345,7 +345,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) {
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
 
-    if def.repr.simd() {
+    if def.repr().simd() {
         check_simd(tcx, span, def_id);
     }
 
@@ -1086,7 +1086,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
             }
 
             let len = if let ty::Array(_ty, c) = e.kind() {
-                c.try_eval_usize(tcx, tcx.param_env(def.did))
+                c.try_eval_usize(tcx, tcx.param_env(def.did()))
             } else {
                 Some(fields.len() as u64)
             };
@@ -1137,10 +1137,10 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
     }
 }
 
-pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
-    let repr = def.repr;
+pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
+    let repr = def.repr();
     if repr.packed() {
-        for attr in tcx.get_attrs(def.did).iter() {
+        for attr in tcx.get_attrs(def.did()).iter() {
             for r in attr::find_repr_attrs(&tcx.sess, attr) {
                 if let attr::ReprPacked(pack) = r
                     && let Some(repr_pack) = repr.pack
@@ -1165,7 +1165,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
             )
             .emit();
         } else {
-            if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
+            if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut vec![]) {
                 let mut err = struct_span_err!(
                     tcx.sess,
                     sp,
@@ -1190,7 +1190,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
                             &if first {
                                 format!(
                                     "`{}` contains a field of type `{}`",
-                                    tcx.type_of(def.did),
+                                    tcx.type_of(def.did()),
                                     ident
                                 )
                             } else {
@@ -1214,16 +1214,16 @@ pub(super) fn check_packed_inner(
 ) -> Option<Vec<(DefId, Span)>> {
     if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() {
         if def.is_struct() || def.is_union() {
-            if def.repr.align.is_some() {
-                return Some(vec![(def.did, DUMMY_SP)]);
+            if def.repr().align.is_some() {
+                return Some(vec![(def.did(), DUMMY_SP)]);
             }
 
             stack.push(def_id);
             for field in &def.non_enum_variant().fields {
                 if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
-                    if !stack.contains(&def.did) {
-                        if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
-                            defs.push((def.did, field.ident(tcx).span));
+                    if !stack.contains(&def.did()) {
+                        if let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) {
+                            defs.push((def.did(), field.ident(tcx).span));
                             return Some(defs);
                         }
                     }
@@ -1236,8 +1236,8 @@ pub(super) fn check_packed_inner(
     None
 }
 
-pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
-    if !adt.repr.transparent() {
+pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtDef<'tcx>) {
+    if !adt.repr().transparent() {
         return;
     }
     let sp = tcx.sess.source_map().guess_head_span(sp);
@@ -1252,9 +1252,9 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty
         .emit();
     }
 
-    if adt.variants.len() != 1 {
-        bad_variant_count(tcx, adt, sp, adt.did);
-        if adt.variants.is_empty() {
+    if adt.variants().len() != 1 {
+        bad_variant_count(tcx, adt, sp, adt.did());
+        if adt.variants().is_empty() {
             // Don't bother checking the fields. No variants (and thus no fields) exist.
             return;
         }
@@ -1317,7 +1317,7 @@ fn check_enum<'tcx>(
         }
     }
 
-    let repr_type_ty = def.repr.discr_type().to_ty(tcx);
+    let repr_type_ty = def.repr().discr_type().to_ty(tcx);
     if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
         if !tcx.features().repr128 {
             feature_err(
@@ -1336,7 +1336,7 @@ fn check_enum<'tcx>(
         }
     }
 
-    if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
+    if tcx.adt_def(def_id).repr().int.is_none() && tcx.features().arbitrary_enum_discriminant {
         let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
 
         let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
@@ -1355,7 +1355,7 @@ fn check_enum<'tcx>(
     for ((_, discr), v) in iter::zip(def.discriminants(tcx), vs) {
         // Check for duplicate discriminant values
         if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
-            let variant_did = def.variants[VariantIdx::new(i)].def_id;
+            let variant_did = def.variant(VariantIdx::new(i)).def_id;
             let variant_i_hir_id = tcx.hir().local_def_id_to_hir_id(variant_did.expect_local());
             let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
             let i_span = match variant_i.disr_expr {
index f01843ebabacf75e3c6fd87a315f014339658567..58e5c9315c30c7c706702ef4135253f8d3f73c79 100644 (file)
@@ -299,15 +299,16 @@ fn suggest_compatible_variants(
                 {
                     if e.hir_id == id {
                         if let Some(span) = expr.span.find_ancestor_inside(block_span) {
-                            let return_suggestions =
-                                if self.tcx.is_diagnostic_item(sym::Result, expected_adt.did) {
-                                    vec!["Ok(())".to_string()]
-                                } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did)
-                                {
-                                    vec!["None".to_string(), "Some(())".to_string()]
-                                } else {
-                                    return;
-                                };
+                            let return_suggestions = if self
+                                .tcx
+                                .is_diagnostic_item(sym::Result, expected_adt.did())
+                            {
+                                vec!["Ok(())".to_string()]
+                            } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did()) {
+                                vec!["None".to_string(), "Some(())".to_string()]
+                            } else {
+                                return;
+                            };
                             if let Some(indent) =
                                 self.tcx.sess.source_map().indentation_before(span.shrink_to_lo())
                             {
@@ -333,7 +334,7 @@ fn suggest_compatible_variants(
             }
 
             let compatible_variants: Vec<String> = expected_adt
-                .variants
+                .variants()
                 .iter()
                 .filter(|variant| variant.fields.len() == 1)
                 .filter_map(|variant| {
@@ -378,7 +379,7 @@ fn suggest_compatible_variants(
                     err.multipart_suggestions(
                         &format!(
                             "try wrapping the expression in a variant of `{}`",
-                            self.tcx.def_path_str(expected_adt.did)
+                            self.tcx.def_path_str(expected_adt.did())
                         ),
                         compatible_variants.into_iter().map(|variant| {
                             vec![
index 26aade16fd4b067df6360e77d13ee4995c9e4752..1849ece9f76d9aa1df6b11acfaf17fd5d2c1f8b7 100644 (file)
@@ -40,13 +40,13 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
                 tcx,
                 drop_impl_did.expect_local(),
                 dtor_self_type,
-                adt_def.did,
+                adt_def.did(),
             )?;
 
             ensure_drop_predicates_are_implied_by_item_defn(
                 tcx,
                 dtor_predicates,
-                adt_def.did.expect_local(),
+                adt_def.did().expect_local(),
                 self_to_impl_substs,
             )
         }
index 7e7104f62fdc67588d58a2b91cf844d982422644..d944bb76241773dcc11e7b511f702fa8b2cc252f 100644 (file)
@@ -1333,7 +1333,7 @@ fn check_expr_struct(
 
         // Prohibit struct expressions when non-exhaustive flag is set.
         let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
-        if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
+        if !adt.did().is_local() && variant.is_field_list_non_exhaustive() {
             self.tcx
                 .sess
                 .emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() });
@@ -1863,7 +1863,7 @@ fn check_field(
                 ty::Adt(base_def, substs) if !base_def.is_enum() => {
                     debug!("struct named {:?}", base_t);
                     let (ident, def_scope) =
-                        self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
+                        self.tcx.adjust_ident_and_get_scope(field, base_def.did(), self.body_id);
                     let fields = &base_def.non_enum_variant().fields;
                     if let Some(index) = fields
                         .iter()
@@ -1882,7 +1882,7 @@ fn check_field(
                             self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
                             return field_ty;
                         }
-                        private_candidate = Some((adjustments, base_def.did, field_ty));
+                        private_candidate = Some((adjustments, base_def.did(), field_ty));
                     }
                 }
                 ty::Tuple(tys) => {
@@ -2103,9 +2103,9 @@ fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field
 
             if let ty::RawPtr(ty_and_mut) = expr_t.kind() {
                 if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() {
-                    if adt_def.variants.len() == 1
+                    if adt_def.variants().len() == 1
                         && adt_def
-                            .variants
+                            .variants()
                             .iter()
                             .next()
                             .unwrap()
@@ -2154,7 +2154,7 @@ fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) {
     fn suggest_fields_on_recordish(
         &self,
         err: &mut Diagnostic,
-        def: &'tcx ty::AdtDef,
+        def: ty::AdtDef<'tcx>,
         field: Ident,
         access_span: Span,
     ) {
index b3213451d76c43049bddb5ecef655d312455c6a5..ed70b85e3f1478ad14a8c0c2366bcc55636d7661 100644 (file)
@@ -1166,7 +1166,7 @@ pub fn instantiate_value_path(
                 if let Some(self_ty) = self_ty =>
             {
                 let adt_def = self_ty.ty_adt_def().unwrap();
-                user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
+                user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty });
                 is_alias_variant_ctor = true;
             }
             Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
index f165093c958dba28ffcfcd499828aadf6a9f4beb..d336573c254f8693f4475690e527469a0d30a68e 100644 (file)
@@ -577,13 +577,13 @@ pub fn check_struct_path(
                 return None;
             }
             Res::Def(DefKind::Variant, _) => match ty.kind() {
-                ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
+                ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did(), substs)),
                 _ => bug!("unexpected type: {:?}", ty),
             },
             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfTy { .. } => match ty.kind() {
                 ty::Adt(adt, substs) if !adt.is_enum() => {
-                    Some((adt.non_enum_variant(), adt.did, substs))
+                    Some((adt.non_enum_variant(), adt.did(), substs))
                 }
                 _ => None,
             },
index 523602d5b1888dbcc3b2756fdbee760724c95adc..67d61668b6d8542cab03059ce5897ae15d5912bd 100644 (file)
@@ -398,7 +398,7 @@ pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
         let pin_box_found = self.tcx.mk_lang_item(box_found, LangItem::Pin).unwrap();
         let pin_found = self.tcx.mk_lang_item(found, LangItem::Pin).unwrap();
         match expected.kind() {
-            ty::Adt(def, _) if Some(def.did) == pin_did => {
+            ty::Adt(def, _) if Some(def.did()) == pin_did => {
                 if self.can_coerce(pin_box_found, expected) {
                     debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
                     match found.kind() {
index 9684237be831369603321854d1701f72cc37dff7..48d241700727ad39801732d2f8a310aef85a7bf2 100644 (file)
@@ -496,7 +496,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
             let descr_pre = &format!("{}boxed ", data.descr_pre);
             check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data })
         }
-        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did, hir_id, data),
+        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did(), hir_id, data),
         // FIXME: support adding the attribute to TAITs
         ty::Opaque(def, _) => {
             let mut has_emitted = false;
index 7bb84581a82de6e654214bbb0c0b48f46f755cfb..1ca9c1920961a0ceabfa99834aeba39f2c4185a0 100644 (file)
@@ -589,9 +589,9 @@ pub fn resolve_fully_qualified_call(
         if let ty::Adt(adt_def, _) = self_ty.kind() {
             if adt_def.is_enum() {
                 let variant_def = adt_def
-                    .variants
+                    .variants()
                     .iter()
-                    .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did));
+                    .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did()));
                 if let Some(variant_def) = variant_def {
                     // Braced variants generate unusable names in value namespace (reserved for
                     // possible future use), so variants resolved as associated items may refer to
index bc2859719e8ebb66a16e586bed3a4f742ec4d980..dbc4adfb0a3cf7df71fab58b57b96ff0df5bb077 100644 (file)
@@ -297,7 +297,7 @@ pub(super) fn lint_fully_qualified_call_from_2018(
             // for a "<" in `self_ty_name`.
             if !self_ty_name.contains('<') {
                 if let Adt(def, _) = self_ty.kind() {
-                    let generics = self.tcx.generics_of(def.did);
+                    let generics = self.tcx.generics_of(def.did());
                     if !generics.params.is_empty() {
                         let counts = generics.own_counts();
                         self_ty_name += &format!(
index 876c575781cf6580c116b06475806d8d598dd9c4..e79085fdad28dda5ae5fd594631a716e31bea2b6 100644 (file)
@@ -640,7 +640,7 @@ fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'t
                 self.assemble_inherent_impl_candidates_for_type(p.def_id());
             }
             ty::Adt(def, _) => {
-                self.assemble_inherent_impl_candidates_for_type(def.did);
+                self.assemble_inherent_impl_candidates_for_type(def.did());
             }
             ty::Foreign(did) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
index 504e1ce8c9f51c84de1a494d5db9e613adef0a1d..715671dd4522d075012f101bb7ee8043594b99f7 100644 (file)
@@ -398,7 +398,7 @@ pub fn report_method_error(
                                 let candidate_found = autoderef.any(|(ty, _)| {
                                     if let ty::Adt(adt_deref, _) = ty.kind() {
                                         self.tcx
-                                            .inherent_impls(adt_deref.did)
+                                            .inherent_impls(adt_deref.did())
                                             .iter()
                                             .filter_map(|def_id| {
                                                 self.associated_value(*def_id, item_name)
@@ -470,7 +470,7 @@ pub fn report_method_error(
                 }
 
                 if let Some(def) = actual.ty_adt_def() {
-                    if let Some(full_sp) = tcx.hir().span_if_local(def.did) {
+                    if let Some(full_sp) = tcx.hir().span_if_local(def.did()) {
                         let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
                         err.span_label(
                             def_sp,
@@ -574,6 +574,7 @@ fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
                     // Pick out the list of unimplemented traits on the receiver.
                     // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
                     let mut unimplemented_traits = FxHashMap::default();
+                    let mut unimplemented_traits_only = true;
                     for (predicate, _parent_pred, cause) in &unsatisfied_predicates {
                         if let (ty::PredicateKind::Trait(p), Some(cause)) =
                             (predicate.kind().skip_binder(), cause.as_ref())
@@ -596,6 +597,21 @@ fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
                         }
                     }
 
+                    // Make sure that, if any traits other than the found ones were involved,
+                    // we don't don't report an unimplemented trait.
+                    // We don't want to say that `iter::Cloned` is not an interator, just
+                    // because of some non-Clone item being iterated over.
+                    for (predicate, _parent_pred, _cause) in &unsatisfied_predicates {
+                        match predicate.kind().skip_binder() {
+                            ty::PredicateKind::Trait(p)
+                                if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {}
+                            _ => {
+                                unimplemented_traits_only = false;
+                                break;
+                            }
+                        }
+                    }
+
                     let mut collect_type_param_suggestions =
                         |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
                             // We don't care about regions here, so it's fine to skip the binder here.
@@ -615,7 +631,7 @@ fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
                                                 .get(self.tcx.hir().local_def_id_to_hir_id(did)),
                                         )
                                     }
-                                    ty::Adt(def, _) => def.did.as_local().map(|def_id| {
+                                    ty::Adt(def, _) => def.did().as_local().map(|def_id| {
                                         self.tcx
                                             .hir()
                                             .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
@@ -646,7 +662,7 @@ fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
                         );
                         match &self_ty.kind() {
                             // Point at the type that couldn't satisfy the bound.
-                            ty::Adt(def, _) => bound_spans.push((def_span(def.did), msg)),
+                            ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
                             // Point at the trait object that couldn't satisfy the bound.
                             ty::Dynamic(preds, _) => {
                                 for pred in preds.iter() {
@@ -839,7 +855,9 @@ trait bound{s}",
                             .join("\n");
                         let actual_prefix = actual.prefix_string(self.tcx);
                         info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
-                        let (primary_message, label) = if unimplemented_traits.len() == 1 {
+                        let (primary_message, label) = if unimplemented_traits.len() == 1
+                            && unimplemented_traits_only
+                        {
                             unimplemented_traits
                                 .into_iter()
                                 .next()
@@ -885,10 +903,10 @@ trait bound{s}",
                                 ty.is_str()
                                     || matches!(
                                         ty.kind(),
-                                        ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did)
+                                        ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
                                     )
                             }
-                            ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did),
+                            ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
                             _ => false,
                         };
                         if is_string_or_ref_str && item_name.name == sym::iter {
@@ -903,7 +921,7 @@ trait bound{s}",
                         if let ty::Adt(adt, _) = rcvr_ty.kind() {
                             let mut inherent_impls_candidate = self
                                 .tcx
-                                .inherent_impls(adt.did)
+                                .inherent_impls(adt.did())
                                 .iter()
                                 .copied()
                                 .filter(|def_id| {
@@ -1046,7 +1064,7 @@ trait bound{s}",
                 if unsatisfied_predicates.is_empty() && actual.is_enum() {
                     let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
                     if let Some(suggestion) = lev_distance::find_best_match_for_name(
-                        &adt_def.variants.iter().map(|s| s.name).collect::<Vec<_>>(),
+                        &adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
                         item_name.name,
                         None,
                     ) {
@@ -1173,7 +1191,7 @@ trait bound{s}",
         let all_local_types_needing_impls =
             errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
                 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
-                    ty::Adt(def, _) => def.did.is_local(),
+                    ty::Adt(def, _) => def.did().is_local(),
                     _ => false,
                 },
                 _ => false,
@@ -1189,7 +1207,7 @@ trait bound{s}",
         let def_ids = preds
             .iter()
             .filter_map(|pred| match pred.self_ty().kind() {
-                ty::Adt(def, _) => Some(def.did),
+                ty::Adt(def, _) => Some(def.did()),
                 _ => None,
             })
             .collect::<FxHashSet<_>>();
@@ -1207,7 +1225,7 @@ trait bound{s}",
             match pred.self_ty().kind() {
                 ty::Adt(def, _) => {
                     spans.push_span_label(
-                        sm.guess_head_span(self.tcx.def_span(def.did)),
+                        sm.guess_head_span(self.tcx.def_span(def.did())),
                         format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
                     );
                 }
@@ -1255,7 +1273,7 @@ fn suggest_derive(
         for (pred, _, _) in unsatisfied_predicates {
             let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
             let adt = match trait_pred.self_ty().ty_adt_def() {
-                Some(adt) if adt.did.is_local() => adt,
+                Some(adt) if adt.did().is_local() => adt,
                 _ => continue,
             };
             if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
@@ -1273,7 +1291,7 @@ fn suggest_derive(
                 };
                 if can_derive {
                     let self_name = trait_pred.self_ty().to_string();
-                    let self_span = self.tcx.def_span(adt.did);
+                    let self_span = self.tcx.def_span(adt.did());
                     if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
                         for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
                         {
@@ -1336,7 +1354,7 @@ fn suggest_derive(
     /// Print out the type for use in value namespace.
     fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
         match ty.kind() {
-            ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did, substs)),
+            ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)),
             _ => self.ty_to_string(ty),
         }
     }
@@ -1930,7 +1948,7 @@ fn type_derefs_to_local(
     ) -> bool {
         fn is_local(ty: Ty<'_>) -> bool {
             match ty.kind() {
-                ty::Adt(def, _) => def.did.is_local(),
+                ty::Adt(def, _) => def.did().is_local(),
                 ty::Foreign(did) => did.is_local(),
                 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
                 ty::Param(_) => true,
index 4c0eab51c355833decf4392b29e624345c2921a9..31cc3fa2ac648c59919365244ac91aa6928f82eb 100644 (file)
@@ -822,13 +822,13 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
 }
 
 /// Emit an error when encountering two or more variants in a transparent enum.
-fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
+fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, did: DefId) {
     let variant_spans: Vec<_> = adt
-        .variants
+        .variants()
         .iter()
         .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
         .collect();
-    let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
+    let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
     let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
     err.span_label(sp, &msg);
     if let [start @ .., end] = &*variant_spans {
@@ -844,7 +844,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d
 /// enum.
 fn bad_non_zero_sized_fields<'tcx>(
     tcx: TyCtxt<'tcx>,
-    adt: &'tcx ty::AdtDef,
+    adt: ty::AdtDef<'tcx>,
     field_count: usize,
     field_spans: impl Iterator<Item = Span>,
     sp: Span,
index cd77e6d0384d88226d7e1207ba9dc7cc6ed32b64..af154e62a1e1629a89adc243e96f6c46ce222fd2 100644 (file)
@@ -576,7 +576,7 @@ fn check_str_addition(
 
         let string_type = self.tcx.get_diagnostic_item(sym::String);
         let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() {
-            Some(ty_def) => Some(ty_def.did) == string_type,
+            Some(ty_def) => Some(ty_def.did()) == string_type,
             None => false,
         };
 
index 8a369797210af08cbfcc86ea70545fba05a88ed9..a264ee5d1475d62268c9dd0d805977cc742db73b 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_hir::{HirId, Pat, PatKind};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeFoldable};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::hygiene::DesugaringKind;
@@ -850,7 +851,7 @@ fn emit_bad_pat_path<'b>(
                     _ => {
                         let (type_def_id, item_def_id) = match pat_ty.kind() {
                             Adt(def, _) => match res {
-                                Res::Def(DefKind::Const, def_id) => (Some(def.did), Some(def_id)),
+                                Res::Def(DefKind::Const, def_id) => (Some(def.did()), Some(def_id)),
                                 _ => (None, None),
                             },
                             _ => (None, None),
@@ -1286,7 +1287,7 @@ fn check_struct_pat_fields(
         };
 
         // Require `..` if struct has non_exhaustive attribute.
-        let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
+        let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
         if non_exhaustive && !has_rest_pat {
             self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
         }
@@ -1308,6 +1309,12 @@ fn check_struct_pat_fields(
                 .copied()
                 .filter(|(field, _)| {
                     field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
+                        && !matches!(
+                            tcx.eval_stability(field.did, None, DUMMY_SP, None),
+                            EvalResult::Deny { .. }
+                        )
+                        // We only want to report the error if it is hidden and not local
+                        && !(tcx.is_doc_hidden(field.did) && !field.did.is_local())
                 })
                 .collect();
 
@@ -2042,8 +2049,8 @@ fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: T
                     .find_map(|(ty, _)| {
                         match ty.kind() {
                             ty::Adt(adt_def, _)
-                                if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
-                                    || self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
+                                if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
+                                    || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
                             {
                                 // Slicing won't work here, but `.as_deref()` might (issue #91328).
                                 err.span_suggestion(
index 318979b462759413fad36d629de06aa229041fef..42eec1776495e7ecd72c5b05cc14f20d40ecde07 100644 (file)
@@ -1,6 +1,7 @@
 use crate::check::method::MethodCallee;
 use crate::check::{has_expected_num_generic_args, FnCtxt, PlaceOp};
 use rustc_ast as ast;
+use rustc_data_structures::intern::Interned;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -125,7 +126,7 @@ fn try_index_step(
         ) = index_expr.kind
         {
             match adjusted_ty.kind() {
-                ty::Adt(ty::AdtDef { did, .. }, _)
+                ty::Adt(ty::AdtDef(Interned(ty::AdtDefData { did, .. }, _)), _)
                     if self.tcx.is_diagnostic_item(sym::Vec, *did) =>
                 {
                     return self.negative_index(adjusted_ty, index_expr.span, base_expr);
index a2c79c6903218b1c473a200a4cc2621d9d45994f..1a94b7261f7abab1bfe39005782313e94ae8f5b6 100644 (file)
@@ -1413,7 +1413,7 @@ fn has_significant_drop_outside_of_captures(
             ty::Adt(def, substs) => {
                 // Multi-varaint enums are captured in entirety,
                 // which would've been handled in the case of single empty slice in `captured_by_move_projs`.
-                assert_eq!(def.variants.len(), 1);
+                assert_eq!(def.variants().len(), 1);
 
                 // Only Field projections can be applied to a non-box Adt.
                 assert!(
@@ -1422,7 +1422,7 @@ fn has_significant_drop_outside_of_captures(
                         ProjectionKind::Field(..)
                     ))
                 );
-                def.variants.get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any(
+                def.variants().get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any(
                     |(i, field)| {
                         let paths_using_field = captured_by_move_projs
                             .iter()
@@ -1649,7 +1649,7 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
         // Return true for fields of packed structs, unless those fields have alignment 1.
         match p.kind {
             ProjectionKind::Field(..) => match ty.kind() {
-                ty::Adt(def, _) if def.repr.packed() => {
+                ty::Adt(def, _) if def.repr().packed() => {
                     // We erase regions here because they cannot be hashed
                     match tcx.layout_of(param_env.and(tcx.erase_regions(p.ty))) {
                         Ok(layout) if layout.align.abi.bytes() == 1 => {
index 8672bf654669a48cf4110b94c221b156f85ade43..30603d6f487940434d49f38dc6f4235bf47ef1b1 100644 (file)
@@ -995,7 +995,7 @@ fn check_type_defn<'tcx, F>(
 {
     for_item(tcx, item).with_fcx(|fcx| {
         let variants = lookup_fields(fcx);
-        let packed = tcx.adt_def(item.def_id).repr.packed();
+        let packed = tcx.adt_def(item.def_id).repr().packed();
 
         for variant in &variants {
             // For DST, or when drop needs to copy things around, all
index ac1f2db848fb34a00a22aec2217dca8450fc3d07..ef59df0dc88f3556341be2ee33d131a481aa2989 100644 (file)
@@ -154,8 +154,8 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
                 if def_a.is_struct() && def_b.is_struct() =>
             {
                 if def_a != def_b {
-                    let source_path = tcx.def_path_str(def_a.did);
-                    let target_path = tcx.def_path_str(def_b.did);
+                    let source_path = tcx.def_path_str(def_a.did());
+                    let target_path = tcx.def_path_str(def_b.did());
 
                     create_err(&format!(
                         "the trait `DispatchFromDyn` may only be implemented \
@@ -168,7 +168,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
                     return;
                 }
 
-                if def_a.repr.c() || def_a.repr.packed() {
+                if def_a.repr().c() || def_a.repr().packed() {
                     create_err(
                         "structs implementing `DispatchFromDyn` may not have \
                              `#[repr(packed)]` or `#[repr(C)]`",
@@ -353,8 +353,8 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
                 if def_a.is_struct() && def_b.is_struct() =>
             {
                 if def_a != def_b {
-                    let source_path = tcx.def_path_str(def_a.did);
-                    let target_path = tcx.def_path_str(def_b.did);
+                    let source_path = tcx.def_path_str(def_a.did());
+                    let target_path = tcx.def_path_str(def_b.did());
                     struct_span_err!(
                         tcx.sess,
                         span,
index 78e549974030192e6bd1c4fa0af6b94f05933943..59c252dec05056b8b57bb9e4a2d147ccdafaa5cb 100644 (file)
@@ -48,7 +48,7 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
         let lang_items = self.tcx.lang_items();
         match *self_ty.kind() {
             ty::Adt(def, _) => {
-                self.check_def_id(item, def.did);
+                self.check_def_id(item, def.did());
             }
             ty::Foreign(did) => {
                 self.check_def_id(item, did);
index 8ed47226d5f594589a741583af343be3e6ba072d..a1bcd141e10634c3ec9abe59acadfd893ce010df 100644 (file)
@@ -97,7 +97,7 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
     if tcx.trait_is_auto(trait_def_id) && !trait_def_id.is_local() {
         let self_ty = trait_ref.self_ty();
         let opt_self_def_id = match *self_ty.kind() {
-            ty::Adt(self_def, _) => Some(self_def.did),
+            ty::Adt(self_def, _) => Some(self_def.did()),
             ty::Foreign(did) => Some(did),
             _ => None,
         };
@@ -181,7 +181,7 @@ fn emit_orphan_check_error<'tcx>(
                     // That way if we had `Vec<MyType>`, we will properly attribute the
                     // problem to `Vec<T>` and avoid confusing the user if they were to see
                     // `MyType` in the error.
-                    ty::Adt(def, _) => tcx.mk_adt(def, ty::List::empty()),
+                    ty::Adt(def, _) => tcx.mk_adt(*def, ty::List::empty()),
                     _ => ty,
                 };
                 let this = "this".to_string();
@@ -340,7 +340,7 @@ fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDef
         assert_eq!(trait_ref.substs.len(), 1);
         let self_ty = trait_ref.self_ty();
         let (self_type_did, substs) = match self_ty.kind() {
-            ty::Adt(def, substs) => (def.did, substs),
+            ty::Adt(def, substs) => (def.did(), substs),
             _ => {
                 // FIXME: should also lint for stuff like `&i32` but
                 // considering that auto traits are unstable, that
@@ -443,7 +443,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                     // by only visiting each `DefId` once.
                     //
                     // This will be is incorrect in subtle cases, but I don't care :)
-                    if self.seen.insert(def.did) {
+                    if self.seen.insert(def.did()) {
                         for ty in def.all_fields().map(|field| field.ty(tcx, substs)) {
                             ty.visit_with(self)?;
                         }
@@ -457,7 +457,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
     }
 
     let self_ty_root = match self_ty.kind() {
-        ty::Adt(def, _) => tcx.mk_adt(def, InternalSubsts::identity_for_item(tcx, def.did)),
+        ty::Adt(def, _) => tcx.mk_adt(*def, InternalSubsts::identity_for_item(tcx, def.did())),
         _ => unimplemented!("unexpected self ty {:?}", self_ty),
     };
 
index 8229f4a80e10c3171c3fb272f0a762c61095fc97..cabdcdc214bbf586abc001262f7e8273e717c715 100644 (file)
@@ -917,7 +917,7 @@ fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
 
 fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId, variants: &[hir::Variant<'_>]) {
     let def = tcx.adt_def(def_id);
-    let repr_type = def.repr.discr_type();
+    let repr_type = def.repr().discr_type();
     let initial = repr_type.initial_discriminant(tcx);
     let mut prev_discr = None::<Discr<'_>>;
 
@@ -1012,7 +1012,7 @@ fn convert_variant(
     )
 }
 
-fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
+fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> {
     use rustc_hir::*;
 
     let def_id = def_id.expect_local();
index 2867574e6562e66fdddb9aa1e674f3105818a9f9..3247a292242a34a3740628e533970507d04e5940 100644 (file)
@@ -464,7 +464,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 
                 Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx
                     .adt_def(tcx.hir().get_parent_item(hir_id))
-                    .repr
+                    .repr()
                     .discr_type()
                     .to_ty(tcx),
 
index 62598d23bd64e9536372257af02338e4f3707af8..be4958ea062763424156f4f8a24ee52417fad10b 100644 (file)
@@ -855,7 +855,7 @@ fn is_multivariant_adt(ty: Ty<'_>) -> bool {
             }
             AdtKind::Enum => def.is_variant_list_non_exhaustive(),
         };
-        def.variants.len() > 1 || (!def.did.is_local() && is_non_exhaustive)
+        def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive)
     } else {
         false
     }
index 876b1ae72ad9644a194791a5942d54fa2104d95d..1464420090bdadc61fe9b15e5b319b144996dc35 100644 (file)
@@ -576,7 +576,7 @@ fn total_fields_in_adt_variant(
     ) -> McResult<usize> {
         let ty = self.typeck_results.node_type(pat_hir_id);
         match ty.kind() {
-            ty::Adt(adt_def, _) => Ok(adt_def.variants[variant_index].fields.len()),
+            ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
             _ => {
                 self.tcx()
                     .sess
index 61ca09f6b982c581d700fb8d1b24fb3bff362a3f..00163c72974ad93482149675b88121ffc1ccc2e8 100644 (file)
@@ -157,7 +157,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 // `['b => 'a, U => T]` and thus get the requirement that `T:
                 // 'a` holds for `Foo`.
                 debug!("Adt");
-                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did) {
+                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
                     for (unsubstituted_predicate, &span) in unsubstituted_predicates {
                         // `unsubstituted_predicate` is `U: 'b` in the
                         // example above.  So apply the substitution to
@@ -178,7 +178,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 // let _: () = substs.region_at(0);
                 check_explicit_predicates(
                     tcx,
-                    def.did,
+                    def.did(),
                     substs,
                     required_predicates,
                     explicit_map,
index 196e476b0e37a7dfcd15af491ca113a3377037f6..76755de4964e1435bf1e4b6335519b953034ac5c 100644 (file)
@@ -283,7 +283,7 @@ fn add_constraints_from_ty(
             }
 
             ty::Adt(def, substs) => {
-                self.add_constraints_from_substs(current, def.did, substs, variance);
+                self.add_constraints_from_substs(current, def.did(), substs, variance);
             }
 
             ty::Projection(ref data) => {
index edadd666edce630676924ea340bdbc847387c109..e8290809276fbf031ad414615f4e1814edbff0f5 100644 (file)
@@ -1,5 +1,6 @@
 use core::fmt;
 use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
+use core::mem::MaybeUninit;
 use core::ops::Try;
 
 use super::{count, wrap_index, RingSlices};
@@ -12,7 +13,7 @@
 /// [`iter`]: super::VecDeque::iter
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T: 'a> {
-    pub(crate) ring: &'a [T],
+    pub(crate) ring: &'a [MaybeUninit<T>],
     pub(crate) tail: usize,
     pub(crate) head: usize,
 }
@@ -21,7 +22,15 @@ pub struct Iter<'a, T: 'a> {
 impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
-        f.debug_tuple("Iter").field(&front).field(&back).finish()
+        // Safety:
+        // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+        // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
+        unsafe {
+            f.debug_tuple("Iter")
+                .field(&MaybeUninit::slice_assume_init_ref(front))
+                .field(&MaybeUninit::slice_assume_init_ref(back))
+                .finish()
+        }
     }
 }
 
@@ -44,7 +53,10 @@ fn next(&mut self) -> Option<&'a T> {
         }
         let tail = self.tail;
         self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
-        unsafe { Some(self.ring.get_unchecked(tail)) }
+        // Safety:
+        // - `self.tail` in a ring buffer is always a valid index.
+        // - `self.head` and `self.tail` equality is checked above.
+        unsafe { Some(self.ring.get_unchecked(tail).assume_init_ref()) }
     }
 
     #[inline]
@@ -58,8 +70,13 @@ fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
         F: FnMut(Acc, Self::Item) -> Acc,
     {
         let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
-        accum = front.iter().fold(accum, &mut f);
-        back.iter().fold(accum, &mut f)
+        // Safety:
+        // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+        // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
+        unsafe {
+            accum = MaybeUninit::slice_assume_init_ref(front).iter().fold(accum, &mut f);
+            MaybeUninit::slice_assume_init_ref(back).iter().fold(accum, &mut f)
+        }
     }
 
     fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
@@ -70,17 +87,19 @@ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
     {
         let (mut iter, final_res);
         if self.tail <= self.head {
-            // single slice self.ring[self.tail..self.head]
-            iter = self.ring[self.tail..self.head].iter();
+            // Safety: single slice self.ring[self.tail..self.head] is initialized.
+            iter = unsafe { MaybeUninit::slice_assume_init_ref(&self.ring[self.tail..self.head]) }
+                .iter();
             final_res = iter.try_fold(init, &mut f);
         } else {
-            // two slices: self.ring[self.tail..], self.ring[..self.head]
+            // Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
             let (front, back) = self.ring.split_at(self.tail);
-            let mut back_iter = back.iter();
+
+            let mut back_iter = unsafe { MaybeUninit::slice_assume_init_ref(back).iter() };
             let res = back_iter.try_fold(init, &mut f);
             let len = self.ring.len();
             self.tail = (self.ring.len() - back_iter.len()) & (len - 1);
-            iter = front[..self.head].iter();
+            iter = unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() };
             final_res = iter.try_fold(res?, &mut f);
         }
         self.tail = self.head - iter.len();
@@ -109,7 +128,7 @@ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
         // that is in bounds.
         unsafe {
             let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
-            self.ring.get_unchecked(idx)
+            self.ring.get_unchecked(idx).assume_init_ref()
         }
     }
 }
@@ -122,7 +141,10 @@ fn next_back(&mut self) -> Option<&'a T> {
             return None;
         }
         self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
-        unsafe { Some(self.ring.get_unchecked(self.head)) }
+        // Safety:
+        // - `self.head` in a ring buffer is always a valid index.
+        // - `self.head` and `self.tail` equality is checked above.
+        unsafe { Some(self.ring.get_unchecked(self.head).assume_init_ref()) }
     }
 
     fn rfold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
@@ -130,8 +152,13 @@ fn rfold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
         F: FnMut(Acc, Self::Item) -> Acc,
     {
         let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
-        accum = back.iter().rfold(accum, &mut f);
-        front.iter().rfold(accum, &mut f)
+        // Safety:
+        // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+        // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
+        unsafe {
+            accum = MaybeUninit::slice_assume_init_ref(back).iter().rfold(accum, &mut f);
+            MaybeUninit::slice_assume_init_ref(front).iter().rfold(accum, &mut f)
+        }
     }
 
     fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
@@ -142,16 +169,20 @@ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
     {
         let (mut iter, final_res);
         if self.tail <= self.head {
-            // single slice self.ring[self.tail..self.head]
-            iter = self.ring[self.tail..self.head].iter();
+            // Safety: single slice self.ring[self.tail..self.head] is initialized.
+            iter = unsafe {
+                MaybeUninit::slice_assume_init_ref(&self.ring[self.tail..self.head]).iter()
+            };
             final_res = iter.try_rfold(init, &mut f);
         } else {
-            // two slices: self.ring[self.tail..], self.ring[..self.head]
+            // Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
             let (front, back) = self.ring.split_at(self.tail);
-            let mut front_iter = front[..self.head].iter();
+
+            let mut front_iter =
+                unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() };
             let res = front_iter.try_rfold(init, &mut f);
             self.head = front_iter.len();
-            iter = back.iter();
+            iter = unsafe { MaybeUninit::slice_assume_init_ref(back).iter() };
             final_res = iter.try_rfold(res?, &mut f);
         }
         self.head = self.tail + iter.len();
index c3cabc754e6a8069c4846121c39650317ffb3eb6..63280e56332cb367da63e8a1a48a659b2d0ceb2f 100644 (file)
@@ -12,7 +12,7 @@
 use core::hash::{Hash, Hasher};
 use core::iter::{repeat_with, FromIterator};
 use core::marker::PhantomData;
-use core::mem::{self, ManuallyDrop};
+use core::mem::{self, ManuallyDrop, MaybeUninit};
 use core::ops::{Index, IndexMut, Range, RangeBounds};
 use core::ptr::{self, NonNull};
 use core::slice;
@@ -181,16 +181,28 @@ fn cap(&self) -> usize {
         }
     }
 
-    /// Turn ptr into a slice
+    /// Turn ptr into a slice, since the elements of the backing buffer may be uninitialized,
+    /// we will return a slice of [`MaybeUninit<T>`].
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
+    /// incorrect usage of this method.
+    ///
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[inline]
-    unsafe fn buffer_as_slice(&self) -> &[T] {
-        unsafe { slice::from_raw_parts(self.ptr(), self.cap()) }
+    unsafe fn buffer_as_slice(&self) -> &[MaybeUninit<T>] {
+        unsafe { slice::from_raw_parts(self.ptr() as *mut MaybeUninit<T>, self.cap()) }
     }
 
-    /// Turn ptr into a mut slice
+    /// Turn ptr into a mut slice, since the elements of the backing buffer may be uninitialized,
+    /// we will return a slice of [`MaybeUninit<T>`].
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
+    /// incorrect usage of this method.
+    ///
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[inline]
-    unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
-        unsafe { slice::from_raw_parts_mut(self.ptr(), self.cap()) }
+    unsafe fn buffer_as_mut_slice(&mut self) -> &mut [MaybeUninit<T>] {
+        unsafe { slice::from_raw_parts_mut(self.ptr() as *mut MaybeUninit<T>, self.cap()) }
     }
 
     /// Moves an element out of the buffer
@@ -1055,9 +1067,13 @@ pub fn iter_mut(&mut self) -> IterMut<'_, T> {
     #[inline]
     #[stable(feature = "deque_extras_15", since = "1.5.0")]
     pub fn as_slices(&self) -> (&[T], &[T]) {
+        // Safety:
+        // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+        // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
         unsafe {
             let buf = self.buffer_as_slice();
-            RingSlices::ring_slices(buf, self.head, self.tail)
+            let (front, back) = RingSlices::ring_slices(buf, self.head, self.tail);
+            (MaybeUninit::slice_assume_init_ref(front), MaybeUninit::slice_assume_init_ref(back))
         }
     }
 
@@ -1089,11 +1105,15 @@ pub fn as_slices(&self) -> (&[T], &[T]) {
     #[inline]
     #[stable(feature = "deque_extras_15", since = "1.5.0")]
     pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
+        // Safety:
+        // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+        // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
         unsafe {
             let head = self.head;
             let tail = self.tail;
             let buf = self.buffer_as_mut_slice();
-            RingSlices::ring_slices(buf, head, tail)
+            let (front, back) = RingSlices::ring_slices(buf, head, tail);
+            (MaybeUninit::slice_assume_init_mut(front), MaybeUninit::slice_assume_init_mut(back))
         }
     }
 
@@ -2327,7 +2347,14 @@ pub fn make_contiguous(&mut self) -> &mut [T] {
         if self.is_contiguous() {
             let tail = self.tail;
             let head = self.head;
-            return unsafe { RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0 };
+            // Safety:
+            // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+            // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
+            return unsafe {
+                MaybeUninit::slice_assume_init_mut(
+                    RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0,
+                )
+            };
         }
 
         let buf = self.buf.ptr();
@@ -2413,7 +2440,14 @@ pub fn make_contiguous(&mut self) -> &mut [T] {
 
         let tail = self.tail;
         let head = self.head;
-        unsafe { RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0 }
+        // Safety:
+        // - `self.head` and `self.tail` in a ring buffer are always valid indices.
+        // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
+        unsafe {
+            MaybeUninit::slice_assume_init_mut(
+                RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0,
+            )
+        }
     }
 
     /// Rotates the double-ended queue `mid` places to the left.
index 139841368d6a1c4096f329ee062e9041e194f64a..4ee0310b361fbce6f0d34a41c8e1b67b138d825f 100644 (file)
@@ -218,6 +218,8 @@ fn from(i: u8) -> Self {
 }
 
 /// An error which can be returned when parsing a char.
+///
+/// This `struct` is created when using the [`char::from_str`] method.
 #[stable(feature = "char_from_str", since = "1.20.0")]
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ParseCharError {
@@ -300,7 +302,10 @@ fn try_from(i: u32) -> Result<Self, Self::Error> {
     }
 }
 
-/// The error type returned when a conversion from u32 to char fails.
+/// The error type returned when a conversion from [`prim@u32`] to [`prim@char`] fails.
+///
+/// This `struct` is created by the [`char::try_from<u32>`](char#impl-TryFrom<u32>) method.
+/// See its documentation for more.
 #[stable(feature = "try_from", since = "1.34.0")]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct CharTryFromError(());
index 0912f8675fa84d18467f88806fd4ae83367097e1..8014dacdd98da6887b938cd1b377582b28f3e4a3 100644 (file)
@@ -9,20 +9,20 @@ pub trait IntoFuture {
 
     /// Which kind of future are we turning this into?
     #[unstable(feature = "into_future", issue = "67644")]
-    type Future: Future<Output = Self::Output>;
+    type IntoFuture: Future<Output = Self::Output>;
 
     /// Creates a future from a value.
     #[unstable(feature = "into_future", issue = "67644")]
     #[lang = "into_future"]
-    fn into_future(self) -> Self::Future;
+    fn into_future(self) -> Self::IntoFuture;
 }
 
 #[unstable(feature = "into_future", issue = "67644")]
 impl<F: Future> IntoFuture for F {
     type Output = F::Output;
-    type Future = F;
+    type IntoFuture = F;
 
-    fn into_future(self) -> Self::Future {
+    fn into_future(self) -> Self::IntoFuture {
         self
     }
 }
index d45ba595f1bae7c543f25942c7622928fa771e72..541adb69b8e2b400b9cfb04184e0e895644222ac 100644 (file)
@@ -112,21 +112,24 @@ impl FromStr for $t {
             /// * '2.5E-10'
             /// * '5.'
             /// * '.5', or, equivalently, '0.5'
-            /// * 'inf', '-inf', 'NaN'
+            /// * 'inf', '-inf', '+infinity', 'NaN'
+            ///
+            /// Note that alphabetical characters are not case-sensitive.
             ///
             /// Leading and trailing whitespace represent an error.
             ///
             /// # Grammar
             ///
-            /// All strings that adhere to the following [EBNF] grammar
-            /// will result in an [`Ok`] being returned:
+            /// All strings that adhere to the following [EBNF] grammar when
+            /// lowercased will result in an [`Ok`] being returned:
             ///
             /// ```txt
-            /// Float  ::= Sign? ( 'inf' | 'NaN' | Number )
+            /// Float  ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
             /// Number ::= ( Digit+ |
+            ///              '.' Digit* |
             ///              Digit+ '.' Digit* |
             ///              Digit* '.' Digit+ ) Exp?
-            /// Exp    ::= [eE] Sign? Digit+
+            /// Exp    ::= 'e' Sign? Digit+
             /// Sign   ::= [+-]
             /// Digit  ::= [0-9]
             /// ```
index e1235829b3aeff524b6997bf24ebd5f66312b050..aff2b6c3cbfdb684bf791c1a5b14db92c34fae04 100644 (file)
@@ -161,9 +161,9 @@ fn rustup_installed() -> bool {
 }
 
 fn stage_dir_exists(stage_path: &str) -> bool {
-    match fs::create_dir(&stage_path[..]) {
+    match fs::create_dir(&stage_path) {
         Ok(_) => true,
-        Err(_) => Path::new(&stage_path[..]).exists(),
+        Err(_) => Path::new(&stage_path).exists(),
     }
 }
 
@@ -179,7 +179,7 @@ fn attempt_toolchain_link(stage_path: &str) {
         return;
     }
 
-    if try_link_toolchain(&stage_path[..]) {
+    if try_link_toolchain(&stage_path) {
         println!(
             "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
         );
@@ -188,7 +188,7 @@ fn attempt_toolchain_link(stage_path: &str) {
         println!(
             "To manually link stage 1 build to `stage1` toolchain, run:\n
             `rustup toolchain link stage1 {}`",
-            &stage_path[..]
+            &stage_path
         );
     }
 }
@@ -222,7 +222,7 @@ fn toolchain_is_linked() -> bool {
 fn try_link_toolchain(stage_path: &str) -> bool {
     Command::new("rustup")
         .stdout(std::process::Stdio::null())
-        .args(&["toolchain", "link", "stage1", &stage_path[..]])
+        .args(&["toolchain", "link", "stage1", &stage_path])
         .output()
         .map_or(false, |output| output.status.success())
 }
index 9b92bed1f02b3f729b394293170ddaec87471c2d..b0f052e6cf0d9df089d5f0c8943649a9cab50658 100644 (file)
@@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
 # https://github.com/puppeteer/puppeteer/issues/375
 #
 # We also specify the version in case we need to update it to go around cache limitations.
-RUN npm install -g browser-ui-test@0.8.0 --unsafe-perm=true
+RUN npm install -g browser-ui-test@0.8.1 --unsafe-perm=true
 
 ENV RUST_CONFIGURE_ARGS \
   --build=x86_64-unknown-linux-gnu \
index 2e66db425d611298ac38ef5291e4d6d3fd5ddb9f..ec538f11831b06a0e70c080ec3739906d0ddab44 100644 (file)
@@ -244,7 +244,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
     clean::Enum {
         generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
         variants_stripped: false,
-        variants: cx.tcx.adt_def(did).variants.iter().map(|v| v.clean(cx)).collect(),
+        variants: cx.tcx.adt_def(did).variants().iter().map(|v| v.clean(cx)).collect(),
     }
 }
 
@@ -327,7 +327,7 @@ fn merge_attrs(
 /// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl`.
 crate fn build_impl(
     cx: &mut DocContext<'_>,
-    parent_module: impl Into<Option<DefId>>,
+    parent_module: Option<DefId>,
     did: DefId,
     attrs: Option<Attrs<'_>>,
     ret: &mut Vec<clean::Item>,
@@ -478,7 +478,7 @@ fn merge_attrs(
         record_extern_trait(cx, did);
     }
 
-    let (merged_attrs, cfg) = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
+    let (merged_attrs, cfg) = merge_attrs(cx, parent_module, load_attrs(cx, did), attrs);
     trace!("merged_attrs={:?}", merged_attrs);
 
     trace!(
index fa0030a936030f12bcf5ad482674795fb0ec483d..52b556ae4b1db729962e9044169e8b7939da0c6c 100644 (file)
@@ -1551,7 +1551,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 })
             }
             ty::Adt(def, substs) => {
-                let did = def.did;
+                let did = def.did();
                 let kind = match def.adt_kind() {
                     AdtKind::Struct => ItemType::Struct,
                     AdtKind::Union => ItemType::Union,
index 26f29a3524b00cf03763b36d98f60623374251f8..34d1268a7df61d28dc179605d71b7ff6c2daee5a 100644 (file)
@@ -699,7 +699,13 @@ fn short_item_info(
 
 // Render the list of items inside one of the sections "Trait Implementations",
 // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
-fn render_impls(cx: &Context<'_>, w: &mut Buffer, impls: &[&&Impl], containing_item: &clean::Item) {
+fn render_impls(
+    cx: &Context<'_>,
+    w: &mut Buffer,
+    impls: &[&&Impl],
+    containing_item: &clean::Item,
+    toggle_open_by_default: bool,
+) {
     let tcx = cx.tcx();
     let mut rendered_impls = impls
         .iter()
@@ -722,7 +728,7 @@ fn render_impls(cx: &Context<'_>, w: &mut Buffer, impls: &[&&Impl], containing_i
                     is_on_foreign_type: false,
                     show_default_items: true,
                     show_non_assoc_items: true,
-                    toggle_open_by_default: true,
+                    toggle_open_by_default,
                 },
             );
             buffer.into_inner()
@@ -1143,7 +1149,7 @@ fn render_assoc_items_inner(
             concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
 
         let mut impls = Buffer::empty_from(w);
-        render_impls(cx, &mut impls, &concrete, containing_item);
+        render_impls(cx, &mut impls, &concrete, containing_item, true);
         let impls = impls.into_inner();
         if !impls.is_empty() {
             write!(
@@ -1165,7 +1171,7 @@ fn render_assoc_items_inner(
                  </h2>\
                  <div id=\"synthetic-implementations-list\">",
             );
-            render_impls(cx, w, &synthetic, containing_item);
+            render_impls(cx, w, &synthetic, containing_item, false);
             w.write_str("</div>");
         }
 
@@ -1177,7 +1183,7 @@ fn render_assoc_items_inner(
                  </h2>\
                  <div id=\"blanket-implementations-list\">",
             );
-            render_impls(cx, w, &blanket_impl, containing_item);
+            render_impls(cx, w, &blanket_impl, containing_item, false);
             w.write_str("</div>");
         }
     }
index 68644a017a4004001188eaf3c697e99dd1f9a0ac..e6c7745c6e10f16399ecd49ca742cdab27d2c59c 100644 (file)
@@ -1765,7 +1765,7 @@ fn write_size_of_layout(w: &mut Buffer, layout: Layout<'_>, tag_size: u64) {
                     };
 
                     for (index, layout) in variants.iter_enumerated() {
-                        let name = adt.variants[index].name;
+                        let name = adt.variant(index).name;
                         write!(w, "<li><code>{name}</code>: ", name = name);
                         write_size_of_layout(w, *layout, tag_size);
                         writeln!(w, "</li>");
index 4358dc8980f2f6b322903d99a5bb7faf40f240b1..7ffcfada5c07987b620ee32c27cbf4a3dc7db255 100644 (file)
@@ -340,9 +340,10 @@ fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self {
             Lifetime { outlives } => GenericParamDefKind::Lifetime {
                 outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(),
             },
-            Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type {
+            Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
                 bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
                 default: default.map(|x| (*x).into_tcx(tcx)),
+                synthetic,
             },
             Const { did: _, ty, default } => {
                 GenericParamDefKind::Const { ty: (*ty).into_tcx(tcx), default: default.map(|x| *x) }
index aa771a06f9c36e5593ed49e7dcc550fe8c2f584c..e1ae0a19ef977b025808e3eb67274fe1f3b79148 100644 (file)
@@ -2,7 +2,7 @@
 //!
 //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
 
-use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet};
+use rustc_data_structures::{fx::FxHashMap, intern::Interned, stable_set::FxHashSet};
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_hir::def::{
     DefKind,
@@ -439,7 +439,7 @@ fn variant_field<'path>(
                             Err(ResolutionFailure::NotResolved {
                                 item_id,
                                 module_id,
-                                partial_res: Some(Res::Def(DefKind::Enum, def.did)),
+                                partial_res: Some(Res::Def(DefKind::Enum, def.did())),
                                 unresolved: variant_field_name.to_string().into(),
                             }
                             .into())
@@ -686,7 +686,7 @@ fn def_id_to_res(&self, ty_id: DefId) -> Option<Res> {
             ty::FnDef(..) => panic!("type alias to a function definition"),
             ty::FnPtr(_) => Res::Primitive(Fn),
             ty::Never => Res::Primitive(Never),
-            ty::Adt(&ty::AdtDef { did, .. }, _) | ty::Foreign(did) => {
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => {
                 Res::Def(self.cx.tcx.def_kind(did), did)
             }
             ty::Projection(_)
@@ -779,7 +779,7 @@ fn resolve_associated_item(
                 if ns == TypeNS && def_kind == DefKind::Enum {
                     match tcx.type_of(did).kind() {
                         ty::Adt(adt_def, _) => {
-                            for variant in &adt_def.variants {
+                            for variant in adt_def.variants() {
                                 if variant.name == item_name {
                                     return Some((
                                         root_res,
@@ -1002,8 +1002,8 @@ fn trait_impls_for<'a>(
             let saw_impl = impl_type == ty
                 || match (impl_type.kind(), ty.kind()) {
                     (ty::Adt(impl_def, _), ty::Adt(ty_def, _)) => {
-                        debug!("impl def_id: {:?}, ty def_id: {:?}", impl_def.did, ty_def.did);
-                        impl_def.did == ty_def.did
+                        debug!("impl def_id: {:?}, ty def_id: {:?}", impl_def.did(), ty_def.did());
+                        impl_def.did() == ty_def.did()
                     }
                     _ => false,
                 };
index 40b0de448293ac5fada8edd894b74104a65cf5c9..7df880a4ed80731e3e0c2d7b671a6d4a7abc7b13 100644 (file)
@@ -9,7 +9,7 @@
 use serde::{Deserialize, Serialize};
 
 /// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 12;
+pub const FORMAT_VERSION: u32 = 13;
 
 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
 /// about the language items in the local crate, as well as info about external items to allow
@@ -346,9 +346,41 @@ pub struct GenericParamDef {
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all = "snake_case")]
 pub enum GenericParamDefKind {
-    Lifetime { outlives: Vec<String> },
-    Type { bounds: Vec<GenericBound>, default: Option<Type> },
-    Const { ty: Type, default: Option<String> },
+    Lifetime {
+        outlives: Vec<String>,
+    },
+    Type {
+        bounds: Vec<GenericBound>,
+        default: Option<Type>,
+        /// This is normally `false`, which means that this generic parameter is
+        /// declared in the Rust source text.
+        ///
+        /// If it is `true`, this generic parameter has been introduced by the
+        /// compiler behind the scenes.
+        ///
+        /// # Example
+        ///
+        /// Consider
+        ///
+        /// ```ignore (pseudo-rust)
+        /// pub fn f(_: impl Trait) {}
+        /// ```
+        ///
+        /// The compiler will transform this behind the scenes to
+        ///
+        /// ```ignore (pseudo-rust)
+        /// pub fn f<impl Trait: Trait>(_: impl Trait) {}
+        /// ```
+        ///
+        /// In this example, the generic parameter named `impl Trait` (and which
+        /// is bound by `Trait`) is synthetic, because it was not originally in
+        /// the Rust source text.
+        synthetic: bool,
+    },
+    Const {
+        ty: Type,
+        default: Option<String>,
+    },
 }
 
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
index f98111484f315b428bc6f3632d3fbe843a304be0..bbc85ecd4ad49e3d75448c84bafb213644cbd601 100644 (file)
@@ -17,7 +17,14 @@ assert-text: ("#toggle-all-docs", "[−]")
 goto: file://|DOC_PATH|/test_docs/struct.Foo.html
 // We first check that everything is visible.
 assert-text: ("#toggle-all-docs", "[−]")
-assert-attribute: ("details.rustdoc-toggle", {"open": ""}, ALL)
+assert-attribute: ("#implementations-list details.rustdoc-toggle", {"open": ""}, ALL)
+assert-attribute: ("#trait-implementations-list details.rustdoc-toggle", {"open": ""}, ALL)
+assert-attribute-false: (
+    "#blanket-implementations-list > details.rustdoc-toggle",
+    {"open": ""},
+    ALL,
+)
+
 // We collapse them all.
 click: "#toggle-all-docs"
 wait-for: 50
diff --git a/src/test/rustdoc-json/fns/generics.rs b/src/test/rustdoc-json/fns/generics.rs
new file mode 100644 (file)
index 0000000..e777fab
--- /dev/null
@@ -0,0 +1,26 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @set wham_id = generics.json "$.index[*][?(@.name=='Wham')].id"
+pub trait Wham {}
+
+// @is    - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
+// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
+// @is    - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
+// @has   - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
+// @has   - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @is    - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
+pub fn one_generic_param_fn<T: Wham>(w: T) {}
+
+// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
+// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
+// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
+// @has   - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
+// @has   - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
+// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
+// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
+// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
+pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
index b74b16844408559a2234a3fe27a333508e4025c4..6e1b155e181eea8cc84ef2580991e7754f4f3427 100644 (file)
@@ -10,9 +10,9 @@
 
 impl IntoFuture for AwaitMe {
     type Output = i32;
-    type Future = Pin<Box<dyn Future<Output = i32>>>;
+    type IntoFuture = Pin<Box<dyn Future<Output = i32>>>;
 
-    fn into_future(self) -> Self::Future {
+    fn into_future(self) -> Self::IntoFuture {
         Box::pin(me())
     }
 }
index 3ef1171ff50d9c8328d596031a684b0fdb9a82cd..b3a882ff089b00764ec7a451b7d102436435dedd 100644 (file)
@@ -1,5 +1,6 @@
 // build-pass
 #![feature(allocator_api)]
+#![allow(unused_must_use)]
 
 use std::alloc::Allocator;
 
@@ -20,4 +21,9 @@ unsafe fn deallocate(&self, _: std::ptr::NonNull<u8>, _: std::alloc::Layout) {
 fn main() {
     Box::new_in((), &std::alloc::Global);
     Box::new_in((), BigAllocator([0; 2]));
+    generic_function(0);
+}
+
+fn generic_function<T>(val: T) {
+    *Box::new_in(val, &std::alloc::Global);
 }
index cbc88bc4d9c382999971f5095021a03641ecd160..fee61907eb3caa8d593239a7c26c999a99a8fc3d 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(const_ptr_offset_from)]
+#![feature(const_ptr_offset_from, const_ptr_offset)]
 #![feature(core_intrinsics)]
 
 use std::intrinsics::ptr_offset_from;
@@ -44,4 +44,30 @@ struct Struct {
     //~| 0x10 is not a valid pointer
 };
 
+const OUT_OF_BOUNDS_1: isize = {
+    let start_ptr = &4 as *const _ as *const u8;
+    let length = 10;
+    let end_ptr = (start_ptr).wrapping_add(length);
+    // First ptr is out of bounds
+    unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed
+    //~| pointer at offset 10 is out-of-bounds
+};
+
+const OUT_OF_BOUNDS_2: isize = {
+    let start_ptr = &4 as *const _ as *const u8;
+    let length = 10;
+    let end_ptr = (start_ptr).wrapping_add(length);
+    // Second ptr is out of bounds
+    unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed
+    //~| pointer at offset 10 is out-of-bounds
+};
+
+const OUT_OF_BOUNDS_SAME: isize = {
+    let start_ptr = &4 as *const _ as *const u8;
+    let length = 10;
+    let end_ptr = (start_ptr).wrapping_add(length);
+    unsafe { ptr_offset_from(end_ptr, end_ptr) } //~ERROR evaluation of constant value failed
+    //~| pointer at offset 10 is out-of-bounds
+};
+
 fn main() {}
index ffd6ad58c301d69e392006cc569bbfac09957102..4d60d4df203b33d4659513cf21a07ae7a540a2a9 100644 (file)
@@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed
 LL |         unsafe { intrinsics::ptr_offset_from(self, origin) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
-   |                  0x2a is not a valid pointer
+   |                  out-of-bounds offset_from: 0x2a is not a valid pointer
    |                  inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
   ::: $DIR/offset_from_ub.rs:23:14
@@ -28,14 +28,32 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:36:14
    |
 LL |     unsafe { ptr_offset_from(ptr, ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is not a valid pointer
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:43:14
    |
 LL |     unsafe { ptr_offset_from(ptr2, ptr1) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0x10 is not a valid pointer
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: 0x10 is not a valid pointer
 
-error: aborting due to 5 previous errors
+error[E0080]: evaluation of constant value failed
+  --> $DIR/offset_from_ub.rs:52:14
+   |
+LL |     unsafe { ptr_offset_from(end_ptr, start_ptr) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc18 has size 4, so pointer at offset 10 is out-of-bounds
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/offset_from_ub.rs:61:14
+   |
+LL |     unsafe { ptr_offset_from(start_ptr, end_ptr) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc21 has size 4, so pointer at offset 10 is out-of-bounds
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/offset_from_ub.rs:69:14
+   |
+LL |     unsafe { ptr_offset_from(end_ptr, end_ptr) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc24 has size 4, so pointer at offset 10 is out-of-bounds
+
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
index 4c3f373e0801c03eadb6f1610e86bdc046dda6ac..237950a30e841ba7fc56eb040446d91cf9775354 100644 (file)
@@ -144,7 +144,7 @@ error[E0080]: evaluation of constant value failed
 LL |         unsafe { intrinsics::offset(self, count) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
-   |                  pointer arithmetic failed: 0x0 is not a valid pointer
+   |                  pointer arithmetic failed: null pointer is not a valid pointer
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
   ::: $DIR/offset_ub.rs:22:50
diff --git a/src/test/ui/generics/single-colon-path-not-const-generics.rs b/src/test/ui/generics/single-colon-path-not-const-generics.rs
new file mode 100644 (file)
index 0000000..55a7ae0
--- /dev/null
@@ -0,0 +1,13 @@
+pub mod foo {
+    pub mod bar {
+        pub struct A;
+    }
+}
+
+pub struct Foo {
+  a: Vec<foo::bar:A>,
+  //~^ ERROR expected
+  //~| HELP path separator
+}
+
+fn main() {}
diff --git a/src/test/ui/generics/single-colon-path-not-const-generics.stderr b/src/test/ui/generics/single-colon-path-not-const-generics.stderr
new file mode 100644 (file)
index 0000000..3eafa9f
--- /dev/null
@@ -0,0 +1,11 @@
+error: expected one of `,` or `>`, found `:`
+  --> $DIR/single-colon-path-not-const-generics.rs:8:18
+   |
+LL |   a: Vec<foo::bar:A>,
+   |                  ^
+   |                  |
+   |                  expected one of `,` or `>`
+   |                  help: write a path separator here: `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs b/src/test/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs
new file mode 100644 (file)
index 0000000..ab8d95a
--- /dev/null
@@ -0,0 +1,271 @@
+// run-pass
+
+#![feature(macro_metavar_expr)]
+
+fn main() {
+    macro_rules! one_nested_count_and_length {
+        ( $( [ $( $l:literal ),* ] ),* ) => {
+            [
+                // outer-most repetition
+                $(
+                    // inner-most repetition
+                    $(
+                        ${ignore(l)} ${index()}, ${length()},
+                    )*
+                    ${count(l)}, ${index()}, ${length()},
+                )*
+                ${count(l)},
+            ]
+        };
+    }
+    assert_eq!(
+        one_nested_count_and_length!(["foo"], ["bar", "baz"]),
+        [
+            // # ["foo"]
+
+            // ## inner-most repetition (first iteration)
+            //
+            // `index` is 0 because this is the first inner-most iteration.
+            // `length` is 1 because there is only one inner-most repetition, "foo".
+            0, 1,
+
+            // ## outer-most repetition (first iteration)
+            //
+            // `count` is 1 because of "foo", i,e, `$l` has only one repetition,
+            // `index` is 0 because this is the first outer-most iteration.
+            // `length` is 2 because there are 2 outer-most repetitions, ["foo"] and ["bar", "baz"]
+            1, 0, 2,
+
+            // # ["bar", "baz"]
+
+            // ## inner-most repetition (first iteration)
+            //
+            // `index` is 0 because this is the first inner-most iteration
+            // `length` is 2 because there are repetitions, "bar" and "baz"
+            0, 2,
+
+            // ## inner-most repetition (second iteration)
+            //
+            // `index` is 1 because this is the second inner-most iteration
+            // `length` is 2 because there are repetitions, "bar" and "baz"
+            1, 2,
+
+            // ## outer-most repetition (second iteration)
+            //
+            // `count` is 2 because of "bar" and "baz", i,e, `$l` has two repetitions,
+            // `index` is 1 because this is the second outer-most iteration
+            // `length` is 2 because there are 2 outer-most repetitions, ["foo"] and ["bar", "baz"]
+            2, 1, 2,
+
+            // # last count
+
+            // Because there are a total of 3 repetitions of `$l`, "foo", "bar" and "baz"
+            3,
+        ]
+    );
+
+    // Based on the above explanation, the following macros should be straightforward
+
+    // Grouped from the outer-most to the inner-most
+    macro_rules! three_nested_count {
+        ( $( { $( [ $( ( $( $i:ident )* ) )* ] )* } )* ) => {
+            &[
+                $( $( $(
+                    &[
+                        ${ignore(i)} ${count(i, 0)},
+                    ][..],
+                )* )* )*
+
+                $( $(
+                    &[
+                        ${ignore(i)} ${count(i, 0)},
+                        ${ignore(i)} ${count(i, 1)},
+                    ][..],
+                )* )*
+
+                $(
+                    &[
+                        ${ignore(i)} ${count(i, 0)},
+                        ${ignore(i)} ${count(i, 1)},
+                        ${ignore(i)} ${count(i, 2)},
+                    ][..],
+                )*
+
+                &[
+                    ${count(i, 0)},
+                    ${count(i, 1)},
+                    ${count(i, 2)},
+                    ${count(i, 3)},
+                ][..]
+            ][..]
+        }
+    }
+    assert_eq!(
+        three_nested_count!(
+            {
+                [ (a b c) (d e f) ]
+                [ (g h) (i j k l m) ]
+                [ (n) ]
+            }
+            {
+                [ (o) (p q) (r s) ]
+                [ (t u v w x y z) ]
+            }
+        ),
+        &[
+            // a b c
+            &[3][..],
+            // d e f
+            &[3][..],
+            // g h
+            &[2][..],
+            // i j k l m
+            &[5][..],
+            // n
+            &[1][..],
+            // o
+            &[1][..],
+            // p q
+            &[2][..],
+            // r s
+            &[2][..],
+            // t u v w x y z
+            &[7][..],
+
+            // (a b c) (d e f)
+            &[2, 6][..],
+            // (g h) (i j k l m)
+            &[2, 7][..],
+            // (n)
+            &[1, 1][..],
+            // (o) (p q) (r s)
+            &[3, 5][..],
+            // (t u v w x y z)
+            &[1, 7][..],
+
+            // [ (a b c) (d e f) ]
+            // [ (g h) (i j k l m) ]
+            // [ (n) ]
+            &[3, 5, 14][..],
+            // [ (o) (p q) (r s) ]
+            // [ (t u v w x y z) ]
+            &[2, 4, 12][..],
+
+            // {
+            //     [ (a b c) (d e f) ]
+            //     [ (g h) (i j k l m) ]
+            //     [ (n) ]
+            // }
+            // {
+            //     [ (o) (p q) (r s) ]
+            //     [ (t u v w x y z) ]
+            // }
+            &[2, 5, 9, 26][..]
+        ][..]
+    );
+
+    // Grouped from the outer-most to the inner-most
+    macro_rules! three_nested_length {
+        ( $( { $( [ $( ( $( $i:ident )* ) )* ] )* } )* ) => {
+            &[
+                $( $( $( $(
+                    &[
+                        ${ignore(i)} ${length(3)},
+                        ${ignore(i)} ${length(2)},
+                        ${ignore(i)} ${length(1)},
+                        ${ignore(i)} ${length(0)},
+                    ][..],
+                )* )* )* )*
+
+                $( $( $(
+                    &[
+                        ${ignore(i)} ${length(2)},
+                        ${ignore(i)} ${length(1)},
+                        ${ignore(i)} ${length(0)},
+                    ][..],
+                )* )* )*
+
+                $( $(
+                    &[
+                        ${ignore(i)} ${length(1)},
+                        ${ignore(i)} ${length(0)},
+                    ][..],
+                )* )*
+
+                $(
+                    &[
+                        ${ignore(i)} ${length(0)},
+                    ][..],
+                )*
+            ][..]
+        }
+    }
+    assert_eq!(
+        three_nested_length!(
+            {
+                [ (a b c) (d e f) ]
+                [ (g h) (i j k l m) ]
+                [ (n) ]
+            }
+            {
+                [ (o) (p q) (r s) ]
+                [ (t u v w x y z) ]
+            }
+        ),
+        &[
+            // a b c
+            &[2, 3, 2, 3][..], &[2, 3, 2, 3][..], &[2, 3, 2, 3][..],
+            // d e f
+            &[2, 3, 2, 3][..], &[2, 3, 2, 3][..], &[2, 3, 2, 3][..],
+            // g h
+            &[2, 3, 2, 2][..], &[2, 3, 2, 2][..],
+            // i j k l m
+            &[2, 3, 2, 5][..], &[2, 3, 2, 5][..], &[2, 3, 2, 5][..], &[2, 3, 2, 5][..],
+            &[2, 3, 2, 5][..],
+            // n
+            &[2, 3, 1, 1][..],
+            // o
+            &[2, 2, 3, 1][..],
+            // p q
+            &[2, 2, 3, 2][..], &[2, 2, 3, 2][..],
+            // r s
+            &[2, 2, 3, 2][..], &[2, 2, 3, 2][..],
+            // t u v w x y z
+            &[2, 2, 1, 7][..], &[2, 2, 1, 7][..], &[2, 2, 1, 7][..], &[2, 2, 1, 7][..],
+            &[2, 2, 1, 7][..], &[2, 2, 1, 7][..], &[2, 2, 1, 7][..],
+
+            // (a b c) (d e f)
+            &[2, 3, 2][..], &[2, 3, 2][..],
+            // (g h) (i j k l m)
+            &[2, 3, 2][..], &[2, 3, 2][..],
+            // (n)
+            &[2, 3, 1][..],
+            // (o) (p q) (r s)
+            &[2, 2, 3][..], &[2, 2, 3][..], &[2, 2, 3][..],
+            // (t u v w x y z)
+            &[2, 2, 1][..],
+
+            // [ (a b c) (d e f) ]
+            // [ (g h) (i j k l m) ]
+            // [ (n) ]
+            &[2, 3][..], &[2, 3][..],  &[2, 3,][..],
+            // [ (o) (p q) (r s) ]
+            // [ (t u v w x y z) ]
+            &[2, 2][..], &[2, 2][..],
+
+            // {
+            //     [ (a b c) (d e f) ]
+            //     [ (g h) (i j k l m) ]
+            //     [ (n) ]
+            // }
+            // {
+            //     [ (o) (p q) (r s) ]
+            //     [ (t u v w x y z) ]
+            // }
+            &[2][..], &[2][..]
+        ][..]
+    );
+
+    // It is possible to say, to some degree, that count is an "amalgamation" of length (see
+    // each length line result and compare them with the count results)
+}
index 6434ecc7e092df4ba67378218e209777aeea2b13..d05cd1b31bc12735fc3e06ca581376b055942941 100644 (file)
 
 #![feature(macro_metavar_expr)]
 
-macro_rules! ignore {
-    ( $( $i:ident ),* ) => {{
-        let array: [i32; 0] = [$( ${ignore(i)} )*];
-        array
-    }};
+/// Count the number of idents in a macro repetition.
+macro_rules! count_idents {
+    ( $( $i:ident ),* ) => {
+        ${count(i)}
+    };
 }
 
+/// Count the number of idents in a 2-dimensional macro repetition.
+macro_rules! count_idents_2 {
+    ( $( [ $( $i:ident ),* ] ),* ) => {
+        ${count(i)}
+    };
+}
+
+/// Mostly counts the number of OUTER-MOST repetitions
+macro_rules! count_depth_limits {
+    ( $( { $( [ $( $outer:ident : ( $( $inner:ident )* ) )* ] )* } )* ) => {
+        (
+            (
+                ${count(inner)},
+                ${count(inner, 0)},
+                ${count(inner, 1)},
+                ${count(inner, 2)},
+                ${count(inner, 3)},
+            ),
+            (
+                ${count(outer)},
+                ${count(outer, 0)},
+                ${count(outer, 1)},
+                ${count(outer, 2)},
+            ),
+        )
+    };
+}
+
+/// Produce (index, length) pairs for literals in a macro repetition.
+/// The literal is not included in the output, so this macro uses the
+/// `ignore` meta-variable expression to create a non-expanding
+/// repetition binding.
+macro_rules! enumerate_literals {
+    ( $( ($l:stmt) ),* ) => {
+        [$( ${ignore(l)} (${index()}, ${length()}) ),*]
+    };
+}
+
+/// Produce index and length tuples for literals in a 2-dimensional
+/// macro repetition.
+macro_rules! enumerate_literals_2 {
+    ( $( [ $( ($l:literal) ),* ] ),* ) => {
+        [
+            $(
+                $(
+                    (
+                        ${index(1)},
+                        ${length(1)},
+                        ${index(0)},
+                        ${length(0)},
+                        $l
+                    ),
+                )*
+            )*
+        ]
+    };
+}
+
+/// Generate macros that count idents and then add a constant number
+/// to the count.
+///
+/// This macro uses dollar escaping to make it unambiguous as to which
+/// macro the repetition belongs to.
+macro_rules! make_count_adders {
+    ( $( $i:ident, $b:literal );* ) => {
+        $(
+            macro_rules! $i {
+                ( $$( $$j:ident ),* ) => {
+                    $b + $${count(j)}
+                };
+            }
+        )*
+    };
+}
+
+make_count_adders! { plus_one, 1; plus_five, 5 }
+
+/// Generate a macro that allows selection of a particular literal
+/// from a sequence of inputs by their identifier.
+///
+/// This macro uses dollar escaping to make it unambiguous as to which
+/// macro the repetition belongs to, and to allow expansion of an
+/// identifier the name of which is not known in the definition
+/// of `make_picker`.
+macro_rules! make_picker {
+    ( $m:ident => $( $i:ident ),* ; $p:ident ) => {
+        macro_rules! $m {
+            ( $( $$ $i:literal ),* ) => {
+                $$ $p
+            };
+        }
+    };
+}
+
+make_picker!(first => a, b; a);
+
+make_picker!(second => a, b; b);
+
 fn main() {
-    assert_eq!(ignore!(a, b, c), []);
+    assert_eq!(count_idents!(a, b, c), 3);
+    assert_eq!(count_idents_2!([a, b, c], [d, e], [f]), 6);
+    assert_eq!(
+        count_depth_limits! {
+            {
+                [ A: (a b c) D: (d e f) ]
+                [ G: (g h) I: (i j k l m) ]
+                [ N: (n) ]
+            }
+            {
+                [ O: (o) P: (p q) R: (r s) ]
+                [ T: (t u v w x y z) ]
+            }
+        },
+        ((26, 2, 5, 9, 26), (9, 2, 5, 9))
+    );
+    assert_eq!(enumerate_literals![("foo"), ("bar")], [(0, 2), (1, 2)]);
+    assert_eq!(
+        enumerate_literals_2![
+            [("foo"), ("bar"), ("baz")],
+            [("qux"), ("quux"), ("quuz"), ("xyzzy")]
+        ],
+        [
+            (0, 2, 0, 3, "foo"),
+            (0, 2, 1, 3, "bar"),
+            (0, 2, 2, 3, "baz"),
+
+            (1, 2, 0, 4, "qux"),
+            (1, 2, 1, 4, "quux"),
+            (1, 2, 2, 4, "quuz"),
+            (1, 2, 3, 4, "xyzzy"),
+        ]
+    );
+    assert_eq!(plus_one!(a, b, c), 4);
+    assert_eq!(plus_five!(a, b), 7);
+    assert_eq!(first!(1, 2), 1);
+    assert_eq!(second!(1, 2), 2);
 }
diff --git a/src/test/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs b/src/test/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs
new file mode 100644 (file)
index 0000000..b954967
--- /dev/null
@@ -0,0 +1,102 @@
+// run-pass
+
+#![feature(macro_metavar_expr)]
+
+#[derive(Debug)]
+struct Example<'a> {
+    _indexes: &'a [(u32, u32)],
+    _counts: &'a [u32],
+    _nested: Vec<Example<'a>>,
+}
+
+macro_rules! example {
+    ( $( [ $( ( $( $x:ident )* ) )* ] )* ) => {
+        Example {
+            _indexes: &[],
+            _counts: &[${count(x, 0)}, ${count(x, 1)}, ${count(x, 2)}],
+            _nested: vec![
+            $(
+                Example {
+                    _indexes: &[(${index()}, ${length()})],
+                    _counts: &[${count(x, 0)}, ${count(x, 1)}],
+                    _nested: vec![
+                    $(
+                        Example {
+                            _indexes: &[(${index(1)}, ${length(1)}), (${index()}, ${length()})],
+                            _counts: &[${count(x)}],
+                            _nested: vec![
+                            $(
+                                Example {
+                                    _indexes: &[
+                                        (${index(2)}, ${length(2)}),
+                                        (${index(1)}, ${length(1)}),
+                                        (${index()}, ${length()})
+                                    ],
+                                    _counts: &[],
+                                    _nested: vec![],
+                                    ${ignore(x)}
+                                }
+                            ),*
+                            ]
+                        }
+                    ),*
+                    ]
+                }
+            ),*
+            ]
+        }
+    };
+}
+
+static EXPECTED: &str = concat!(
+    "Example { _indexes: [], _counts: [2, 4, 13], _nested: [",
+    concat!(
+        "Example { _indexes: [(0, 2)], _counts: [3, 10], _nested: [",
+        concat!(
+            "Example { _indexes: [(0, 2), (0, 3)], _counts: [4], _nested: [",
+            concat!(
+                "Example { _indexes: [(0, 2), (0, 3), (0, 4)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (0, 3), (1, 4)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (0, 3), (2, 4)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (0, 3), (3, 4)], _counts: [], _nested: [] }",
+            ),
+            "] }, ",
+            "Example { _indexes: [(0, 2), (1, 3)], _counts: [4], _nested: [",
+            concat!(
+                "Example { _indexes: [(0, 2), (1, 3), (0, 4)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (1, 3), (1, 4)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (1, 3), (2, 4)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (1, 3), (3, 4)], _counts: [], _nested: [] }",
+            ),
+            "] }, ",
+            "Example { _indexes: [(0, 2), (2, 3)], _counts: [2], _nested: [",
+            concat!(
+                "Example { _indexes: [(0, 2), (2, 3), (0, 2)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(0, 2), (2, 3), (1, 2)], _counts: [], _nested: [] }",
+            ),
+            "] }",
+        ),
+        "] }, ",
+        "Example { _indexes: [(1, 2)], _counts: [1, 3], _nested: [",
+        concat!(
+            "Example { _indexes: [(1, 2), (0, 1)], _counts: [3], _nested: [",
+            concat!(
+                "Example { _indexes: [(1, 2), (0, 1), (0, 3)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(1, 2), (0, 1), (1, 3)], _counts: [], _nested: [] }, ",
+                "Example { _indexes: [(1, 2), (0, 1), (2, 3)], _counts: [], _nested: [] }",
+            ),
+            "] }",
+        ),
+        "] }",
+    ),
+    "] }",
+);
+
+fn main() {
+    let e = example! {
+        [ ( A B C D ) ( E F G H ) ( I J ) ]
+        [ ( K L M ) ]
+    };
+    let debug = format!("{:?}", e);
+    assert_eq!(debug, EXPECTED);
+}
diff --git a/src/test/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs b/src/test/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs
new file mode 100644 (file)
index 0000000..d81c862
--- /dev/null
@@ -0,0 +1,44 @@
+#![feature(macro_metavar_expr)]
+
+macro_rules! a {
+    ( $( { $( [ $( ( $( $foo:ident )* ) )* ] )* } )* ) => {
+        (
+            ${count(foo, 0)},
+            ${count(foo, 10)},
+            //~^ ERROR count depth must be less than 4
+        )
+    };
+}
+
+macro_rules! b {
+    ( $( { $( [ $( $foo:ident )* ] )* } )* ) => {
+        (
+            $( $( $(
+                ${ignore(foo)}
+                ${index(0)},
+                ${index(10)},
+                //~^ ERROR index depth must be less than 3
+            )* )* )*
+        )
+    };
+}
+
+macro_rules! c {
+    ( $( { $( $foo:ident )* } )* ) => {
+        (
+            $( $(
+                ${ignore(foo)}
+                ${length(0)}
+                ${length(10)}
+                //~^ ERROR length depth must be less than 2
+            )* )*
+        )
+    };
+}
+
+
+fn main() {
+    a!( { [ (a) ] [ (b c) ] } );
+    b!( { [ a b ] } );
+    c!( { a } );
+}
diff --git a/src/test/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr b/src/test/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr
new file mode 100644 (file)
index 0000000..7474c03
--- /dev/null
@@ -0,0 +1,20 @@
+error: count depth must be less than 4
+  --> $DIR/out-of-bounds-arguments.rs:7:14
+   |
+LL |             ${count(foo, 10)},
+   |              ^^^^^^^^^^^^^^^^
+
+error: index depth must be less than 3
+  --> $DIR/out-of-bounds-arguments.rs:19:18
+   |
+LL |                 ${index(10)},
+   |                  ^^^^^^^^^^^
+
+error: length depth must be less than 2
+  --> $DIR/out-of-bounds-arguments.rs:32:18
+   |
+LL |                 ${length(10)}
+   |                  ^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
index ea73fd0813c5bd249cc1b5c14497b07c46d53b08..fdf16442d2aa5d0d35917e559c2c0cc2511a6127 100644 (file)
@@ -10,6 +10,7 @@ macro_rules! curly__no_rhs_dollar__round {
 
 macro_rules! curly__no_rhs_dollar__no_round {
     ( $i:ident ) => { ${ count(i) } };
+    //~^ ERROR `count` can not be placed inside the inner-most repetition
 }
 
 macro_rules! curly__rhs_dollar__round {
@@ -121,6 +122,20 @@ macro_rules! open_brackets_without_tokens {
     //~| ERROR expected identifier
 }
 
+macro_rules! unknown_count_ident {
+    ( $( $i:ident )* ) => {
+        ${count(foo)}
+        //~^ ERROR variable `foo` is not recognized in meta-variable expression
+    };
+}
+
+macro_rules! unknown_ignore_ident {
+    ( $( $i:ident )* ) => {
+        ${ignore(bar)}
+        //~^ ERROR variable `bar` is not recognized in meta-variable expression
+    };
+}
+
 macro_rules! unknown_metavar {
     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
     //~^ ERROR unrecognized meta-variable expression
@@ -139,10 +154,12 @@ fn main() {
     //~^ ERROR cannot find value `a` in this scope
 
     extra_garbage_after_metavar!(a);
-    unknown_metavar!(a);
-    metavar_without_parens!(a);
-    metavar_token_without_ident!(a);
     metavar_depth_is_not_literal!(a);
+    metavar_token_without_ident!(a);
     metavar_with_literal_suffix!(a);
-    open_brackets_without_tokens!(a)
+    metavar_without_parens!(a);
+    open_brackets_without_tokens!(a);
+    unknown_count_ident!(a);
+    unknown_ignore_ident!(a);
+    unknown_metavar!(a);
 }
index dc8b7a668c4ee749abd8b61a28308187e55c6d72..0188938a30e8d9bc58482f8f20e6a1ea2e5af0e9 100644 (file)
 error: expected identifier, found `$`
-  --> $DIR/syntax-errors.rs:16:33
+  --> $DIR/syntax-errors.rs:17:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ count($i) } };
    |                                 ^^^^^ - help: try removing `$`
 
 error: expected identifier, found `$`
-  --> $DIR/syntax-errors.rs:22:26
+  --> $DIR/syntax-errors.rs:23:26
    |
 LL |     ( $i:ident ) => { ${ count($i) } };
    |                          ^^^^^ - help: try removing `$`
 
 error: unexpected token: $
-  --> $DIR/syntax-errors.rs:52:8
+  --> $DIR/syntax-errors.rs:53:8
    |
 LL |     ( $$ $a:ident ) => {
    |        ^
 
 note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions
-  --> $DIR/syntax-errors.rs:52:8
+  --> $DIR/syntax-errors.rs:53:8
    |
 LL |     ( $$ $a:ident ) => {
    |        ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:59:19
+  --> $DIR/syntax-errors.rs:60:19
    |
 LL |         ${count() a b c}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:59:19
+  --> $DIR/syntax-errors.rs:60:19
    |
 LL |         ${count() a b c}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:62:19
+  --> $DIR/syntax-errors.rs:63:19
    |
 LL |         ${count(i a b c)}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:62:19
+  --> $DIR/syntax-errors.rs:63:19
    |
 LL |         ${count(i a b c)}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:64:22
+  --> $DIR/syntax-errors.rs:65:22
    |
 LL |         ${count(i, 1 a b c)}
    |                      ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:64:22
+  --> $DIR/syntax-errors.rs:65:22
    |
 LL |         ${count(i, 1 a b c)}
    |                      ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:66:20
+  --> $DIR/syntax-errors.rs:67:20
    |
 LL |         ${count(i) a b c}
    |                    ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:66:20
+  --> $DIR/syntax-errors.rs:67:20
    |
 LL |         ${count(i) a b c}
    |                    ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:69:21
+  --> $DIR/syntax-errors.rs:70:21
    |
 LL |         ${ignore(i) a b c}
    |                     ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:69:21
+  --> $DIR/syntax-errors.rs:70:21
    |
 LL |         ${ignore(i) a b c}
    |                     ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:71:20
+  --> $DIR/syntax-errors.rs:72:20
    |
 LL |         ${ignore(i a b c)}
    |                    ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:71:20
+  --> $DIR/syntax-errors.rs:72:20
    |
 LL |         ${ignore(i a b c)}
    |                    ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:74:19
+  --> $DIR/syntax-errors.rs:75:19
    |
 LL |         ${index() a b c}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:74:19
+  --> $DIR/syntax-errors.rs:75:19
    |
 LL |         ${index() a b c}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:76:19
+  --> $DIR/syntax-errors.rs:77:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:76:19
+  --> $DIR/syntax-errors.rs:77:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:79:19
+  --> $DIR/syntax-errors.rs:80:19
    |
 LL |         ${index() a b c}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:79:19
+  --> $DIR/syntax-errors.rs:80:19
    |
 LL |         ${index() a b c}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:81:19
+  --> $DIR/syntax-errors.rs:82:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:81:19
+  --> $DIR/syntax-errors.rs:82:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
 
 error: meta-variable expression depth must be a literal
-  --> $DIR/syntax-errors.rs:88:33
+  --> $DIR/syntax-errors.rs:89:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(IDX) } };
    |                                 ^^^^^
 
 error: unexpected token: {
-  --> $DIR/syntax-errors.rs:94:8
+  --> $DIR/syntax-errors.rs:95:8
    |
 LL |     ( ${ length() } ) => {
    |        ^^^^^^^^^^^^
 
 note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions
-  --> $DIR/syntax-errors.rs:94:8
+  --> $DIR/syntax-errors.rs:95:8
    |
 LL |     ( ${ length() } ) => {
    |        ^^^^^^^^^^^^
 
 error: expected one of: `*`, `+`, or `?`
-  --> $DIR/syntax-errors.rs:94:8
+  --> $DIR/syntax-errors.rs:95:8
    |
 LL |     ( ${ length() } ) => {
    |        ^^^^^^^^^^^^
 
 error: expected identifier
-  --> $DIR/syntax-errors.rs:101:33
+  --> $DIR/syntax-errors.rs:102:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ ignore() } };
    |                                 ^^^^^^
 
 error: only unsuffixes integer literals are supported in meta-variable expressions
-  --> $DIR/syntax-errors.rs:107:33
+  --> $DIR/syntax-errors.rs:108:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(1u32) } };
    |                                 ^^^^^
 
 error: meta-variable expression parameter must be wrapped in parentheses
-  --> $DIR/syntax-errors.rs:113:33
+  --> $DIR/syntax-errors.rs:114:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ count{i} } };
    |                                 ^^^^^
 
 error: expected identifier
-  --> $DIR/syntax-errors.rs:119:31
+  --> $DIR/syntax-errors.rs:120:31
    |
 LL |     ( $( $i:ident ),* ) => { ${ {} } };
    |                               ^^^^^^
 
 error: unrecognized meta-variable expression
-  --> $DIR/syntax-errors.rs:125:33
+  --> $DIR/syntax-errors.rs:140:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
    |                                 ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and length
 
+error: `count` can not be placed inside the inner-most repetition
+  --> $DIR/syntax-errors.rs:12:24
+   |
+LL |     ( $i:ident ) => { ${ count(i) } };
+   |                        ^^^^^^^^^^^^
+
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:16:30
+  --> $DIR/syntax-errors.rs:17:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ count($i) } };
    |                              ^ expected expression
@@ -208,7 +214,7 @@ LL |     curly__rhs_dollar__round!(a, b, c);
    = note: this error originates in the macro `curly__rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:22:23
+  --> $DIR/syntax-errors.rs:23:23
    |
 LL |     ( $i:ident ) => { ${ count($i) } };
    |                       ^ expected expression
@@ -219,13 +225,13 @@ LL |     curly__rhs_dollar__no_round!(a);
    = note: this error originates in the macro `curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: variable 'i' is still repeating at this depth
-  --> $DIR/syntax-errors.rs:40:36
+  --> $DIR/syntax-errors.rs:41:36
    |
 LL |     ( $( $i:ident ),* ) => { count($i) };
    |                                    ^^
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:59:9
+  --> $DIR/syntax-errors.rs:60:9
    |
 LL |         ${count() a b c}
    |         ^ expected expression
@@ -236,29 +242,18 @@ LL |     extra_garbage_after_metavar!(a);
    = note: this error originates in the macro `extra_garbage_after_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:125:30
+  --> $DIR/syntax-errors.rs:89:30
    |
-LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
-   |                              ^ expected expression
-...
-LL |     unknown_metavar!(a);
-   |     ------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:113:30
-   |
-LL |     ( $( $i:ident ),* ) => { ${ count{i} } };
+LL |     ( $( $i:ident ),* ) => { ${ index(IDX) } };
    |                              ^ expected expression
 ...
-LL |     metavar_without_parens!(a);
-   |     -------------------------- in this macro invocation
+LL |     metavar_depth_is_not_literal!(a);
+   |     -------------------------------- in this macro invocation
    |
-   = note: this error originates in the macro `metavar_without_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `metavar_depth_is_not_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:101:30
+  --> $DIR/syntax-errors.rs:102:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ ignore() } };
    |                              ^ expected expression
@@ -269,40 +264,63 @@ LL |     metavar_token_without_ident!(a);
    = note: this error originates in the macro `metavar_token_without_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:88:30
+  --> $DIR/syntax-errors.rs:108:30
    |
-LL |     ( $( $i:ident ),* ) => { ${ index(IDX) } };
+LL |     ( $( $i:ident ),* ) => { ${ index(1u32) } };
    |                              ^ expected expression
 ...
-LL |     metavar_depth_is_not_literal!(a);
-   |     -------------------------------- in this macro invocation
+LL |     metavar_with_literal_suffix!(a);
+   |     ------------------------------- in this macro invocation
    |
-   = note: this error originates in the macro `metavar_depth_is_not_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `metavar_with_literal_suffix` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:107:30
+  --> $DIR/syntax-errors.rs:114:30
    |
-LL |     ( $( $i:ident ),* ) => { ${ index(1u32) } };
+LL |     ( $( $i:ident ),* ) => { ${ count{i} } };
    |                              ^ expected expression
 ...
-LL |     metavar_with_literal_suffix!(a);
-   |     ------------------------------- in this macro invocation
+LL |     metavar_without_parens!(a);
+   |     -------------------------- in this macro invocation
    |
-   = note: this error originates in the macro `metavar_with_literal_suffix` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `metavar_without_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:119:30
+  --> $DIR/syntax-errors.rs:120:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ {} } };
    |                              ^ expected expression
 ...
-LL |     open_brackets_without_tokens!(a)
+LL |     open_brackets_without_tokens!(a);
    |     -------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `open_brackets_without_tokens` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error: variable `foo` is not recognized in meta-variable expression
+  --> $DIR/syntax-errors.rs:127:17
+   |
+LL |         ${count(foo)}
+   |                 ^^^
+
+error: variable `bar` is not recognized in meta-variable expression
+  --> $DIR/syntax-errors.rs:134:18
+   |
+LL |         ${ignore(bar)}
+   |                  ^^^
+
+error: expected expression, found `$`
+  --> $DIR/syntax-errors.rs:140:30
+   |
+LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
+   |                              ^ expected expression
+...
+LL |     unknown_metavar!(a);
+   |     ------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error[E0425]: cannot find function `count` in this scope
-  --> $DIR/syntax-errors.rs:28:30
+  --> $DIR/syntax-errors.rs:29:30
    |
 LL |     ( $( $i:ident ),* ) => { count(i) };
    |                              ^^^^^ not found in this scope
@@ -313,7 +331,7 @@ LL |     no_curly__no_rhs_dollar__round!(a, b, c);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `i` in this scope
-  --> $DIR/syntax-errors.rs:28:36
+  --> $DIR/syntax-errors.rs:29:36
    |
 LL |     ( $( $i:ident ),* ) => { count(i) };
    |                                    ^ not found in this scope
@@ -324,7 +342,7 @@ LL |     no_curly__no_rhs_dollar__round!(a, b, c);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find function `count` in this scope
-  --> $DIR/syntax-errors.rs:34:23
+  --> $DIR/syntax-errors.rs:35:23
    |
 LL |     ( $i:ident ) => { count(i) };
    |                       ^^^^^ not found in this scope
@@ -335,7 +353,7 @@ LL |     no_curly__no_rhs_dollar__no_round!(a);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `i` in this scope
-  --> $DIR/syntax-errors.rs:34:29
+  --> $DIR/syntax-errors.rs:35:29
    |
 LL |     ( $i:ident ) => { count(i) };
    |                             ^ not found in this scope
@@ -346,7 +364,7 @@ LL |     no_curly__no_rhs_dollar__no_round!(a);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find function `count` in this scope
-  --> $DIR/syntax-errors.rs:45:23
+  --> $DIR/syntax-errors.rs:46:23
    |
 LL |     ( $i:ident ) => { count($i) };
    |                       ^^^^^ not found in this scope
@@ -357,11 +375,11 @@ LL |     no_curly__rhs_dollar__no_round!(a);
    = note: this error originates in the macro `no_curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `a` in this scope
-  --> $DIR/syntax-errors.rs:138:37
+  --> $DIR/syntax-errors.rs:153:37
    |
 LL |     no_curly__rhs_dollar__no_round!(a);
    |                                     ^ not found in this scope
 
-error: aborting due to 37 previous errors
+error: aborting due to 40 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/methods/issues/issue-84495.rs b/src/test/ui/methods/issues/issue-84495.rs
new file mode 100644 (file)
index 0000000..28c094b
--- /dev/null
@@ -0,0 +1,4 @@
+fn main() {
+    let x: i32 = 1;
+    println!("{:?}", x.count()); //~ ERROR is not an iterator
+}
diff --git a/src/test/ui/methods/issues/issue-84495.stderr b/src/test/ui/methods/issues/issue-84495.stderr
new file mode 100644 (file)
index 0000000..b0217a7
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0599]: `i32` is not an iterator
+  --> $DIR/issue-84495.rs:3:24
+   |
+LL |     println!("{:?}", x.count());
+   |                        ^^^^^ `i32` is not an iterator
+   |
+   = note: the following trait bounds were not satisfied:
+           `i32: Iterator`
+           which is required by `&mut i32: Iterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
index 0252ba2eb04606e860492fec1757de88a3015de4..17d2292baaf683298c17e48edb0474e1b311f438 100644 (file)
@@ -5,6 +5,6 @@
 use std::iter::once;
 fn main() {
     once::<&str>("str").fuse().filter(|a: &str| true).count();
-    //~^ ERROR not an iterator
+    //~^ ERROR the method
     //~| ERROR type mismatch in closure arguments
 }
index b1010171eb23560fee29e2c705c15b8a6b55f736..a8bcdf5efe91e30214a5f24f844e1d80dfd2f79a 100644 (file)
@@ -12,11 +12,11 @@ note: required by a bound in `filter`
 LL |         P: FnMut(&Self::Item) -> bool,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `filter`
 
-error[E0599]: `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` is not an iterator
+error[E0599]: the method `count` exists for struct `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>`, but its trait bounds were not satisfied
   --> $DIR/issue-36053-2.rs:7:55
    |
 LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
-   |                                       --------------  ^^^^^ `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` is not an iterator
+   |                                       --------------  ^^^^^ method cannot be called on `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` due to unsatisfied trait bounds
    |                                       |
    |                                       doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
    |                                       doesn't satisfy `_: FnMut<(&&str,)>`
index 742b7e82c16b076339b377ff8cabefdd48c18ffe..364514ba1d3b057bc58d882b282d8fc885ea2142 100644 (file)
@@ -1,6 +1,14 @@
-pub enum Foo {
+pub enum HiddenEnum {
     A,
     B,
     #[doc(hidden)]
     C,
 }
+
+#[derive(Default)]
+pub struct HiddenStruct {
+    pub one: u8,
+    pub two: bool,
+    #[doc(hidden)]
+    pub hide: usize,
+}
index 3142489c86103bc7f17656b0ca76ca411b420ad8..a06b3a6e4e5abbd07dce48c05309d979cb53f417 100644 (file)
@@ -2,7 +2,7 @@
 #![stable(feature = "stable_test_feature", since = "1.0.0")]
 
 #[stable(feature = "stable_test_feature", since = "1.0.0")]
-pub enum Foo {
+pub enum UnstableEnum {
     #[stable(feature = "stable_test_feature", since = "1.0.0")]
     Stable,
     #[stable(feature = "stable_test_feature", since = "1.0.0")]
@@ -10,3 +10,14 @@ pub enum Foo {
     #[unstable(feature = "unstable_test_feature", issue = "none")]
     Unstable,
 }
+
+#[derive(Default)]
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub struct UnstableStruct {
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    pub stable: bool,
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    pub stable2: usize,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable: u8,
+}
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-fields.rs b/src/test/ui/pattern/usefulness/doc-hidden-fields.rs
new file mode 100644 (file)
index 0000000..4163b87
--- /dev/null
@@ -0,0 +1,26 @@
+// aux-build:hidden.rs
+
+extern crate hidden;
+
+use hidden::HiddenStruct;
+
+struct InCrate {
+    a: usize,
+    b: bool,
+    #[doc(hidden)]
+    im_hidden: u8
+}
+
+fn main() {
+    let HiddenStruct { one, two } = HiddenStruct::default();
+    //~^ pattern requires `..` due to inaccessible fields
+
+    let HiddenStruct { one } = HiddenStruct::default();
+    //~^ pattern does not mention field `two` and inaccessible fields
+
+    let HiddenStruct { one, hide } = HiddenStruct::default();
+    //~^ pattern does not mention field `two`
+
+    let InCrate { a, b } = InCrate { a: 0, b: false, im_hidden: 0 };
+    //~^ pattern does not mention field `im_hidden`
+}
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-fields.stderr b/src/test/ui/pattern/usefulness/doc-hidden-fields.stderr
new file mode 100644 (file)
index 0000000..f277bfb
--- /dev/null
@@ -0,0 +1,59 @@
+error: pattern requires `..` due to inaccessible fields
+  --> $DIR/doc-hidden-fields.rs:15:9
+   |
+LL |     let HiddenStruct { one, two } = HiddenStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: ignore the inaccessible and unused fields
+   |
+LL |     let HiddenStruct { one, two, .. } = HiddenStruct::default();
+   |                                ++++
+
+error[E0027]: pattern does not mention field `two` and inaccessible fields
+  --> $DIR/doc-hidden-fields.rs:18:9
+   |
+LL |     let HiddenStruct { one } = HiddenStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^ missing field `two` and inaccessible fields
+   |
+help: include the missing field in the pattern and ignore the inaccessible fields
+   |
+LL |     let HiddenStruct { one, two, .. } = HiddenStruct::default();
+   |                           ~~~~~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let HiddenStruct { one, .. } = HiddenStruct::default();
+   |                           ~~~~~~
+
+error[E0027]: pattern does not mention field `two`
+  --> $DIR/doc-hidden-fields.rs:21:9
+   |
+LL |     let HiddenStruct { one, hide } = HiddenStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `two`
+   |
+help: include the missing field in the pattern
+   |
+LL |     let HiddenStruct { one, hide, two } = HiddenStruct::default();
+   |                                 ~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let HiddenStruct { one, hide, .. } = HiddenStruct::default();
+   |                                 ~~~~~~
+
+error[E0027]: pattern does not mention field `im_hidden`
+  --> $DIR/doc-hidden-fields.rs:24:9
+   |
+LL |     let InCrate { a, b } = InCrate { a: 0, b: false, im_hidden: 0 };
+   |         ^^^^^^^^^^^^^^^^ missing field `im_hidden`
+   |
+help: include the missing field in the pattern
+   |
+LL |     let InCrate { a, b, im_hidden } = InCrate { a: 0, b: false, im_hidden: 0 };
+   |                       ~~~~~~~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let InCrate { a, b, .. } = InCrate { a: 0, b: false, im_hidden: 0 };
+   |                       ~~~~~~
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0027`.
index a1dcab093142335b9cc8dfe8d7153f36b324fa28..d968c48fb1ab78b3b733363c53c9d90dc97ebd5e 100644 (file)
@@ -2,29 +2,42 @@
 
 extern crate hidden;
 
-use hidden::Foo;
+use hidden::HiddenEnum;
+
+enum InCrate {
+    A,
+    B,
+    #[doc(hidden)]
+    C,
+}
 
 fn main() {
-    match Foo::A {
-        Foo::A => {}
-        Foo::B => {}
+    match HiddenEnum::A {
+        HiddenEnum::A => {}
+        HiddenEnum::B => {}
     }
     //~^^^^ non-exhaustive patterns: `_` not covered
 
-    match Foo::A {
-        Foo::A => {}
-        Foo::C => {}
+    match HiddenEnum::A {
+        HiddenEnum::A => {}
+        HiddenEnum::C => {}
     }
     //~^^^^ non-exhaustive patterns: `B` not covered
 
-    match Foo::A {
-        Foo::A => {}
+    match HiddenEnum::A {
+        HiddenEnum::A => {}
     }
     //~^^^ non-exhaustive patterns: `B` and `_` not covered
 
     match None {
         None => {}
-        Some(Foo::A) => {}
+        Some(HiddenEnum::A) => {}
     }
     //~^^^^ non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
+
+    match InCrate::A {
+        InCrate::A => {}
+        InCrate::B => {}
+    }
+    //~^^^^ non-exhaustive patterns: `C` not covered
 }
index 7d0b71a497ec2f91f0fb290bf18f9f74a77cb900..296465eb81838f6056d6dd75b3701d356a028ec1 100644 (file)
@@ -1,36 +1,36 @@
 error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/doc-hidden-non-exhaustive.rs:8:11
+  --> $DIR/doc-hidden-non-exhaustive.rs:15:11
    |
-LL |     match Foo::A {
-   |           ^^^^^^ pattern `_` not covered
+LL |     match HiddenEnum::A {
+   |           ^^^^^^^^^^^^^ pattern `_` not covered
    |
-note: `Foo` defined here
+note: `HiddenEnum` defined here
   --> $DIR/auxiliary/hidden.rs:1:1
    |
-LL | / pub enum Foo {
+LL | / pub enum HiddenEnum {
 LL | |     A,
 LL | |     B,
 LL | |     #[doc(hidden)]
 LL | |     C,
 LL | | }
    | |_^
-   = note: the matched value is of type `Foo`
+   = note: the matched value is of type `HiddenEnum`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         Foo::B => {}
+LL ~         HiddenEnum::B => {}
 LL +         _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `B` not covered
-  --> $DIR/doc-hidden-non-exhaustive.rs:14:11
+  --> $DIR/doc-hidden-non-exhaustive.rs:21:11
    |
-LL |     match Foo::A {
-   |           ^^^^^^ pattern `B` not covered
+LL |     match HiddenEnum::A {
+   |           ^^^^^^^^^^^^^ pattern `B` not covered
    |
-note: `Foo` defined here
+note: `HiddenEnum` defined here
   --> $DIR/auxiliary/hidden.rs:3:5
    |
-LL | / pub enum Foo {
+LL | / pub enum HiddenEnum {
 LL | |     A,
 LL | |     B,
    | |     ^ not covered
@@ -38,23 +38,23 @@ LL | |     #[doc(hidden)]
 LL | |     C,
 LL | | }
    | |_-
-   = note: the matched value is of type `Foo`
+   = note: the matched value is of type `HiddenEnum`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         Foo::C => {}
+LL ~         HiddenEnum::C => {}
 LL +         B => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `B` and `_` not covered
-  --> $DIR/doc-hidden-non-exhaustive.rs:20:11
+  --> $DIR/doc-hidden-non-exhaustive.rs:27:11
    |
-LL |     match Foo::A {
-   |           ^^^^^^ patterns `B` and `_` not covered
+LL |     match HiddenEnum::A {
+   |           ^^^^^^^^^^^^^ patterns `B` and `_` not covered
    |
-note: `Foo` defined here
+note: `HiddenEnum` defined here
   --> $DIR/auxiliary/hidden.rs:3:5
    |
-LL | / pub enum Foo {
+LL | / pub enum HiddenEnum {
 LL | |     A,
 LL | |     B,
    | |     ^ not covered
@@ -62,20 +62,20 @@ LL | |     #[doc(hidden)]
 LL | |     C,
 LL | | }
    | |_-
-   = note: the matched value is of type `Foo`
+   = note: the matched value is of type `HiddenEnum`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
-LL ~         Foo::A => {}
+LL ~         HiddenEnum::A => {}
 LL +         B | _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
-  --> $DIR/doc-hidden-non-exhaustive.rs:25:11
+  --> $DIR/doc-hidden-non-exhaustive.rs:32:11
    |
 LL |     match None {
    |           ^^^^ patterns `Some(B)` and `Some(_)` not covered
    |
-note: `Option<Foo>` defined here
+note: `Option<HiddenEnum>` defined here
   --> $SRC_DIR/core/src/option.rs:LL:COL
    |
 LL | / pub enum Option<T> {
@@ -87,13 +87,34 @@ LL | |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    | |     ^^^^ not covered
 LL | | }
    | |_-
-   = note: the matched value is of type `Option<Foo>`
+   = note: the matched value is of type `Option<HiddenEnum>`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
-LL ~         Some(Foo::A) => {}
+LL ~         Some(HiddenEnum::A) => {}
 LL +         Some(B) | Some(_) => todo!()
    |
 
-error: aborting due to 4 previous errors
+error[E0004]: non-exhaustive patterns: `C` not covered
+  --> $DIR/doc-hidden-non-exhaustive.rs:38:11
+   |
+LL |     match InCrate::A {
+   |           ^^^^^^^^^^ pattern `C` not covered
+   |
+note: `InCrate` defined here
+  --> $DIR/doc-hidden-non-exhaustive.rs:11:5
+   |
+LL | enum InCrate {
+   |      -------
+...
+LL |     C,
+   |     ^ not covered
+   = note: the matched value is of type `InCrate`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         InCrate::B => {}
+LL +         C => todo!()
+   |
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/stable-gated-fields.rs b/src/test/ui/pattern/usefulness/stable-gated-fields.rs
new file mode 100644 (file)
index 0000000..90f40a8
--- /dev/null
@@ -0,0 +1,16 @@
+// aux-build:unstable.rs
+
+extern crate unstable;
+
+use unstable::UnstableStruct;
+
+fn main() {
+    let UnstableStruct { stable } = UnstableStruct::default();
+    //~^ pattern does not mention field `stable2` and inaccessible fields
+
+    let UnstableStruct { stable, stable2 } = UnstableStruct::default();
+    //~^ pattern requires `..` due to inaccessible fields
+
+    // OK: stable field is matched
+    let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
+}
diff --git a/src/test/ui/pattern/usefulness/stable-gated-fields.stderr b/src/test/ui/pattern/usefulness/stable-gated-fields.stderr
new file mode 100644 (file)
index 0000000..cf98c51
--- /dev/null
@@ -0,0 +1,29 @@
+error[E0027]: pattern does not mention field `stable2` and inaccessible fields
+  --> $DIR/stable-gated-fields.rs:8:9
+   |
+LL |     let UnstableStruct { stable } = UnstableStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `stable2` and inaccessible fields
+   |
+help: include the missing field in the pattern and ignore the inaccessible fields
+   |
+LL |     let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
+   |                                ~~~~~~~~~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let UnstableStruct { stable, .. } = UnstableStruct::default();
+   |                                ~~~~~~
+
+error: pattern requires `..` due to inaccessible fields
+  --> $DIR/stable-gated-fields.rs:11:9
+   |
+LL |     let UnstableStruct { stable, stable2 } = UnstableStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: ignore the inaccessible and unused fields
+   |
+LL |     let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
+   |                                         ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0027`.
index 2e023a3be4a5ea5f25529a3947d43e0bb611e752..ff1c472e24fd6292a06845e9c7bae9c3f4ecc388 100644 (file)
@@ -2,17 +2,17 @@
 
 extern crate unstable;
 
-use unstable::Foo;
+use unstable::UnstableEnum;
 
 fn main() {
-    match Foo::Stable {
-        Foo::Stable => {}
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
     }
     //~^^^ non-exhaustive patterns: `Stable2` and `_` not covered
 
-    match Foo::Stable {
-        Foo::Stable => {}
-        Foo::Stable2 => {}
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        UnstableEnum::Stable2 => {}
     }
     //~^^^^ non-exhaustive patterns: `_` not covered
 }
index 696ef9d8de9362d2ef539a56217077ec87403782..559539178cbe3931f486006010b19f2612d1f877 100644 (file)
@@ -1,13 +1,13 @@
 error[E0004]: non-exhaustive patterns: `Stable2` and `_` not covered
   --> $DIR/stable-gated-patterns.rs:8:11
    |
-LL |     match Foo::Stable {
-   |           ^^^^^^^^^^^ patterns `Stable2` and `_` not covered
+LL |     match UnstableEnum::Stable {
+   |           ^^^^^^^^^^^^^^^^^^^^ patterns `Stable2` and `_` not covered
    |
-note: `Foo` defined here
+note: `UnstableEnum` defined here
   --> $DIR/auxiliary/unstable.rs:9:5
    |
-LL | / pub enum Foo {
+LL | / pub enum UnstableEnum {
 LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
 LL | |     Stable,
 LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
@@ -17,23 +17,23 @@ LL | |     #[unstable(feature = "unstable_test_feature", issue = "none")]
 LL | |     Unstable,
 LL | | }
    | |_-
-   = note: the matched value is of type `Foo`
+   = note: the matched value is of type `UnstableEnum`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
-LL ~         Foo::Stable => {}
+LL ~         UnstableEnum::Stable => {}
 LL +         Stable2 | _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/stable-gated-patterns.rs:13:11
    |
-LL |     match Foo::Stable {
-   |           ^^^^^^^^^^^ pattern `_` not covered
+LL |     match UnstableEnum::Stable {
+   |           ^^^^^^^^^^^^^^^^^^^^ pattern `_` not covered
    |
-note: `Foo` defined here
+note: `UnstableEnum` defined here
   --> $DIR/auxiliary/unstable.rs:5:1
    |
-LL | / pub enum Foo {
+LL | / pub enum UnstableEnum {
 LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
 LL | |     Stable,
 LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
@@ -41,10 +41,10 @@ LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
 LL | |     Unstable,
 LL | | }
    | |_^
-   = note: the matched value is of type `Foo`
+   = note: the matched value is of type `UnstableEnum`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         Foo::Stable2 => {}
+LL ~         UnstableEnum::Stable2 => {}
 LL +         _ => todo!()
    |
 
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-fields.rs b/src/test/ui/pattern/usefulness/unstable-gated-fields.rs
new file mode 100644 (file)
index 0000000..2b473ae
--- /dev/null
@@ -0,0 +1,18 @@
+#![feature(unstable_test_feature)]
+
+// aux-build:unstable.rs
+
+extern crate unstable;
+
+use unstable::UnstableStruct;
+
+fn main() {
+    let UnstableStruct { stable, stable2, } = UnstableStruct::default();
+    //~^ pattern does not mention field `unstable`
+
+    let UnstableStruct { stable, unstable, } = UnstableStruct::default();
+    //~^ pattern does not mention field `stable2`
+
+    // OK: stable field is matched
+    let UnstableStruct { stable, stable2, unstable } = UnstableStruct::default();
+}
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-fields.stderr b/src/test/ui/pattern/usefulness/unstable-gated-fields.stderr
new file mode 100644 (file)
index 0000000..e4f5fa0
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0027]: pattern does not mention field `unstable`
+  --> $DIR/unstable-gated-fields.rs:10:9
+   |
+LL |     let UnstableStruct { stable, stable2, } = UnstableStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `unstable`
+   |
+help: include the missing field in the pattern
+   |
+LL |     let UnstableStruct { stable, stable2, unstable } = UnstableStruct::default();
+   |                                         ~~~~~~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
+   |                                         ~~~~~~
+
+error[E0027]: pattern does not mention field `stable2`
+  --> $DIR/unstable-gated-fields.rs:13:9
+   |
+LL |     let UnstableStruct { stable, unstable, } = UnstableStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `stable2`
+   |
+help: include the missing field in the pattern
+   |
+LL |     let UnstableStruct { stable, unstable, stable2 } = UnstableStruct::default();
+   |                                          ~~~~~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let UnstableStruct { stable, unstable, .. } = UnstableStruct::default();
+   |                                          ~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0027`.
index b9804b0ffe77ade22fbb91ea2d57da1e71cabd99..bdab327fd57ac71dfee91b905da810e49c429465 100644 (file)
@@ -4,19 +4,19 @@
 
 extern crate unstable;
 
-use unstable::Foo;
+use unstable::UnstableEnum;
 
 fn main() {
-    match Foo::Stable {
-        Foo::Stable => {}
-        Foo::Stable2 => {}
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        UnstableEnum::Stable2 => {}
     }
     //~^^^^ non-exhaustive patterns: `Unstable` not covered
 
     // Ok: all variants are explicitly matched
-    match Foo::Stable {
-        Foo::Stable => {}
-        Foo::Stable2 => {}
-        Foo::Unstable => {}
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        UnstableEnum::Stable2 => {}
+        UnstableEnum::Unstable => {}
     }
 }
index 8487c9725da8332f6935291b7ec28b33454786a0..b5f1805deef118b893f06a5e4d331eed07837ae1 100644 (file)
@@ -1,13 +1,13 @@
 error[E0004]: non-exhaustive patterns: `Unstable` not covered
   --> $DIR/unstable-gated-patterns.rs:10:11
    |
-LL |     match Foo::Stable {
-   |           ^^^^^^^^^^^ pattern `Unstable` not covered
+LL |     match UnstableEnum::Stable {
+   |           ^^^^^^^^^^^^^^^^^^^^ pattern `Unstable` not covered
    |
-note: `Foo` defined here
+note: `UnstableEnum` defined here
   --> $DIR/auxiliary/unstable.rs:11:5
    |
-LL | / pub enum Foo {
+LL | / pub enum UnstableEnum {
 LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
 LL | |     Stable,
 LL | |     #[stable(feature = "stable_test_feature", since = "1.0.0")]
@@ -16,10 +16,10 @@ LL | |     Unstable,
    | |     ^^^^^^^^ not covered
 LL | | }
    | |_-
-   = note: the matched value is of type `Foo`
+   = note: the matched value is of type `UnstableEnum`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         Foo::Stable2 => {}
+LL ~         UnstableEnum::Stable2 => {}
 LL +         Unstable => todo!()
    |
 
index de9d6f65945cd375334d32f6ba65c1aef9cc6f6b..11df44461e36bb36a1f5fc698db649c9b7453c2d 100644 (file)
@@ -27,3 +27,34 @@ pub fn new() -> Self {
         Self::Unstable
     }
 }
+
+#[derive(Default)]
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[non_exhaustive]
+pub struct UnstableStruct {
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    pub stable: bool,
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    pub stable2: usize,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable: u8,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[non_exhaustive]
+pub struct OnlyUnstableStruct {
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable: u8,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable2: bool,
+}
+
+impl OnlyUnstableStruct {
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    pub fn new() -> Self {
+        Self {
+            unstable: 0,
+            unstable2: false,
+        }
+    }
+}
index fe9734fdc08f66e28943703316c39333df6d5007..d8f07bb8f24d1b44f165421fc86739b09884c772 100644 (file)
@@ -13,7 +13,7 @@
     EmptyNonExhaustiveEnum, NestedNonExhaustive, NonExhaustiveEnum, NonExhaustiveSingleVariant,
     VariantNonExhaustive,
 };
-use unstable::{UnstableEnum, OnlyUnstableEnum};
+use unstable::{UnstableEnum, OnlyUnstableEnum, UnstableStruct, OnlyUnstableStruct};
 use structs::{FunctionalRecord, MixedVisFields, NestedStruct, NormalStruct};
 
 #[non_exhaustive]
@@ -145,6 +145,7 @@ fn main() {
     }
     //~^^ some variants are not matched explicitly
 
+    // Ok: the feature is on and all variants are matched
     #[deny(non_exhaustive_omitted_patterns)]
     match UnstableEnum::Stable {
         UnstableEnum::Stable => {}
@@ -167,4 +168,20 @@ fn main() {
         _ => {}
     }
     //~^^ some variants are not matched explicitly
+
+    #[warn(non_exhaustive_omitted_patterns)]
+    let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new();
+    //~^ some fields are not explicitly listed
+
+    // OK: both unstable fields are matched with feature on
+    #[warn(non_exhaustive_omitted_patterns)]
+    let OnlyUnstableStruct { unstable, unstable2, .. } = OnlyUnstableStruct::new();
+
+    #[warn(non_exhaustive_omitted_patterns)]
+    let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
+    //~^ some fields are not explicitly listed
+
+    // OK: both unstable and stable fields are matched with feature on
+    #[warn(non_exhaustive_omitted_patterns)]
+    let UnstableStruct { stable, stable2, unstable, .. } = UnstableStruct::default();
 }
index 30f3f88ad9161b31fac24ea7dcd7023ac876c596..a9885449f3f0297fb3f506a20a9c95e8389858c7 100644 (file)
@@ -49,6 +49,34 @@ LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested
    = help: ensure that all fields are mentioned explicitly by adding the suggested fields
    = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
+warning: some fields are not explicitly listed
+  --> $DIR/omitted-patterns.rs:173:9
+   |
+LL |     let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable2` not listed
+   |
+note: the lint level is defined here
+  --> $DIR/omitted-patterns.rs:172:12
+   |
+LL |     #[warn(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
+
+warning: some fields are not explicitly listed
+  --> $DIR/omitted-patterns.rs:181:9
+   |
+LL |     let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable` not listed
+   |
+note: the lint level is defined here
+  --> $DIR/omitted-patterns.rs:180:12
+   |
+LL |     #[warn(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
+
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:58:9
    |
@@ -143,18 +171,18 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/omitted-patterns.rs:167:9
+  --> $DIR/omitted-patterns.rs:168:9
    |
 LL |         _ => {}
    |         ^ pattern `Unstable2` not covered
    |
 note: the lint level is defined here
-  --> $DIR/omitted-patterns.rs:164:12
+  --> $DIR/omitted-patterns.rs:165:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: ensure that all variants are matched explicitly by adding the suggested match arms
    = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
-error: aborting due to 8 previous errors; 4 warnings emitted
+error: aborting due to 8 previous errors; 6 warnings emitted
 
index 9621d28f8e22bf68e1af52c09ef6355af557fb11..82ee68687ed00b12127aeb4a13ce707f080f1e4f 100644 (file)
@@ -6,7 +6,7 @@
 // aux-build:unstable.rs
 extern crate unstable;
 
-use unstable::{UnstableEnum, OnlyUnstableEnum};
+use unstable::{UnstableEnum, OnlyUnstableEnum, UnstableStruct, OnlyUnstableStruct};
 
 fn main() {
     // OK: this matches all the stable variants
@@ -30,4 +30,16 @@ fn main() {
     match OnlyUnstableEnum::new() {
         _ => {}
     }
+
+    // Ok: Same as the above enum (no fields can be matched on)
+    #[warn(non_exhaustive_omitted_patterns)]
+    let OnlyUnstableStruct { .. } = OnlyUnstableStruct::new();
+
+    #[warn(non_exhaustive_omitted_patterns)]
+    let UnstableStruct { stable, .. } = UnstableStruct::default();
+    //~^ some fields are not explicitly listed
+
+    // OK: stable field is matched
+    #[warn(non_exhaustive_omitted_patterns)]
+    let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
 }
index b9a281974faf4ad52ea383156974ed3eed93184e..7cce178988aa9f069bbb1f1f7f63771b6ceae3ea 100644 (file)
@@ -1,3 +1,17 @@
+warning: some fields are not explicitly listed
+  --> $DIR/stable-omitted-patterns.rs:39:9
+   |
+LL |     let UnstableStruct { stable, .. } = UnstableStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `stable2` not listed
+   |
+note: the lint level is defined here
+  --> $DIR/stable-omitted-patterns.rs:38:12
+   |
+LL |     #[warn(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
+
 error: some variants are not matched explicitly
   --> $DIR/stable-omitted-patterns.rs:23:9
    |
@@ -12,5 +26,5 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = help: ensure that all variants are matched explicitly by adding the suggested match arms
    = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
-error: aborting due to previous error
+error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/suggestions/constrain-suggest-ice.rs b/src/test/ui/suggestions/constrain-suggest-ice.rs
new file mode 100644 (file)
index 0000000..69b874b
--- /dev/null
@@ -0,0 +1,11 @@
+struct Bug<S>{ //~ ERROR parameter `S` is never used [E0392]
+    A: [(); {
+        let x: [u8; Self::W] = [0; Self::W]; //~ ERROR generic `Self` types are currently not permitted in anonymous constants
+        //~^ ERROR generic `Self` types are currently not permitted in anonymous constants
+        //~^^ ERROR the size for values of type `S` cannot be known at compilation time [E0277]
+        F //~ ERROR cannot find value `F` in this scope [E0425]
+    }
+} //~ ERROR mismatched closing delimiter: `}`
+//~^ ERROR mismatched closing delimiter: `}`
+
+fn main() {}
diff --git a/src/test/ui/suggestions/constrain-suggest-ice.stderr b/src/test/ui/suggestions/constrain-suggest-ice.stderr
new file mode 100644 (file)
index 0000000..477eb27
--- /dev/null
@@ -0,0 +1,81 @@
+error: mismatched closing delimiter: `}`
+  --> $DIR/constrain-suggest-ice.rs:2:8
+   |
+LL | struct Bug<S>{
+   |              - closing delimiter possibly meant for this
+LL |     A: [(); {
+   |        ^ unclosed delimiter
+...
+LL | }
+   | ^ mismatched closing delimiter
+
+error: mismatched closing delimiter: `}`
+  --> $DIR/constrain-suggest-ice.rs:2:8
+   |
+LL | struct Bug<S>{
+   |              - closing delimiter possibly meant for this
+LL |     A: [(); {
+   |        ^ unclosed delimiter
+...
+LL | }
+   | ^ mismatched closing delimiter
+
+error[E0425]: cannot find value `F` in this scope
+  --> $DIR/constrain-suggest-ice.rs:6:9
+   |
+LL |         F
+   |         ^
+   |
+help: a local variable with a similar name exists
+   |
+LL |         x
+   |         ~
+help: you might be missing a type parameter
+   |
+LL | struct Bug<S, F>{
+   |             +++
+
+error: generic `Self` types are currently not permitted in anonymous constants
+  --> $DIR/constrain-suggest-ice.rs:3:21
+   |
+LL |         let x: [u8; Self::W] = [0; Self::W];
+   |                     ^^^^
+
+error: generic `Self` types are currently not permitted in anonymous constants
+  --> $DIR/constrain-suggest-ice.rs:3:36
+   |
+LL |         let x: [u8; Self::W] = [0; Self::W];
+   |                                    ^^^^
+
+error[E0277]: the size for values of type `S` cannot be known at compilation time
+  --> $DIR/constrain-suggest-ice.rs:3:36
+   |
+LL | struct Bug<S>{
+   |            - this type parameter needs to be `std::marker::Sized`
+LL |     A: [(); {
+LL |         let x: [u8; Self::W] = [0; Self::W];
+   |                                    ^^^^^^^ doesn't have a size known at compile-time
+   |
+note: required by a bound in `Bug`
+  --> $DIR/constrain-suggest-ice.rs:1:12
+   |
+LL | struct Bug<S>{
+   |            ^ required by this bound in `Bug`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | struct Bug<S: ?Sized>{
+   |             ++++++++
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/constrain-suggest-ice.rs:1:12
+   |
+LL | struct Bug<S>{
+   |            ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `S` to be a const parameter, use `const S: usize` instead
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0277, E0392, E0425.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/struct-field-type-including-single-colon.rs b/src/test/ui/suggestions/struct-field-type-including-single-colon.rs
new file mode 100644 (file)
index 0000000..b7ad6d9
--- /dev/null
@@ -0,0 +1,20 @@
+mod foo {
+    struct A;
+    mod bar {
+        struct B;
+    }
+}
+
+struct Foo {
+    a: foo:A,
+    //~^ ERROR found single colon in a struct field type path
+    //~| expected `,`, or `}`, found `:`
+}
+
+struct Bar {
+    b: foo::bar:B,
+    //~^ ERROR found single colon in a struct field type path
+    //~| expected `,`, or `}`, found `:`
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/struct-field-type-including-single-colon.stderr b/src/test/ui/suggestions/struct-field-type-including-single-colon.stderr
new file mode 100644 (file)
index 0000000..189759d
--- /dev/null
@@ -0,0 +1,36 @@
+error: found single colon in a struct field type path
+  --> $DIR/struct-field-type-including-single-colon.rs:9:11
+   |
+LL |     a: foo:A,
+   |           ^
+   |
+help: write a path separator here
+   |
+LL |     a: foo::A,
+   |           ~~
+
+error: expected `,`, or `}`, found `:`
+  --> $DIR/struct-field-type-including-single-colon.rs:9:11
+   |
+LL |     a: foo:A,
+   |           ^
+
+error: found single colon in a struct field type path
+  --> $DIR/struct-field-type-including-single-colon.rs:15:16
+   |
+LL |     b: foo::bar:B,
+   |                ^
+   |
+help: write a path separator here
+   |
+LL |     b: foo::bar::B,
+   |                ~~
+
+error: expected `,`, or `}`, found `:`
+  --> $DIR/struct-field-type-including-single-colon.rs:15:16
+   |
+LL |     b: foo::bar:B,
+   |                ^
+
+error: aborting due to 4 previous errors
+
index f0979840ff8d8ab9d55d0a1426b5905ee10d23ec..4592ca7274888dd97b13552ea01ac9c75dd8bf50 100644 (file)
@@ -149,7 +149,7 @@ fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
 fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
     for ty_cause in ty_causes {
         if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
-            if is_mutex_guard(cx, adt.did) {
+            if is_mutex_guard(cx, adt.did()) {
                 span_lint_and_then(
                     cx,
                     AWAIT_HOLDING_LOCK,
@@ -167,7 +167,7 @@ fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorType
                     },
                 );
             }
-            if is_refcell_ref(cx, adt.did) {
+            if is_refcell_ref(cx, adt.did()) {
                 span_lint_and_then(
                     cx,
                     AWAIT_HOLDING_REFCELL_REF,
index 7637666d059ef319be896210e2e7e0c6cb0feca5..df780747a0c759d5857bb924db6c99a66ddbf00f 100644 (file)
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
+use rustc_data_structures::intern::Interned;
 use rustc_hir::{Expr, ExprKind, PathSegment};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -55,7 +56,7 @@ fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: &
                 ty::Str => {
                     return Some(span);
                 },
-                ty::Adt(&ty::AdtDef { did, .. }, _) => {
+                ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) => {
                     if ctx.tcx.is_diagnostic_item(sym::String, did) {
                         return Some(span);
                     }
index 9b189ea1ef8fb102396b7cefa76829bcff426ee5..421bd6f53f71b4a78f37788f2a16b61301c76a44 100644 (file)
@@ -116,15 +116,15 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
                 && let Res::Def(DefKind::Ctor(..), id) = cx.qpath_res(p, cast_expr.hir_id)
             {
                 let i = def.variant_index_with_ctor_id(id);
-                let variant = &def.variants[i];
-                let nbits = utils::enum_value_nbits(get_discriminant_value(cx.tcx, def, i));
+                let variant = def.variant(i);
+                let nbits = utils::enum_value_nbits(get_discriminant_value(cx.tcx, *def, i));
                 (nbits, Some(variant))
             } else {
-                (utils::enum_ty_to_nbits(def, cx.tcx), None)
+                (utils::enum_ty_to_nbits(*def, cx.tcx), None)
             };
             let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
 
-            let cast_from_ptr_size = def.repr.int.map_or(true, |ty| {
+            let cast_from_ptr_size = def.repr().int.map_or(true, |ty| {
                 matches!(
                     ty,
                     IntType::SignedInt(ast::IntTy::Isize) | IntType::UnsignedInt(ast::UintTy::Usize)
index bbed766c47a8526f45c9ec90fd34b3b6b57b18e9..5a4f20f099060c7f911c3cf4e5e10937b59547f4 100644 (file)
@@ -34,10 +34,10 @@ pub(super) fn enum_value_nbits(value: EnumValue) -> u64 {
     .into()
 }
 
-pub(super) fn enum_ty_to_nbits(adt: &AdtDef, tcx: TyCtxt<'_>) -> u64 {
+pub(super) fn enum_ty_to_nbits(adt: AdtDef<'_>, tcx: TyCtxt<'_>) -> u64 {
     let mut explicit = 0i128;
     let (start, end) = adt
-        .variants
+        .variants()
         .iter()
         .fold((0, i128::MIN), |(start, end), variant| match variant.discr {
             VariantDiscr::Relative(x) => match explicit.checked_add(i128::from(x)) {
index 06e6bf986c2a9458e6417ec0ec9fe2991bed7626..f7e4bc24321c5a8ac58461d41ef60683a3bc9102 100644 (file)
@@ -96,7 +96,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
             then {
                 // TODO: Work out a way to put "whatever the imported way of referencing
                 // this type in this file" rather than a fully-qualified type.
-                let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did));
+                let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did()));
                 span_lint_and_sugg(
                     cx,
                     DEFAULT_TRAIT_ACCESS,
@@ -137,7 +137,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
                 if let Some(adt) = binding_type.ty_adt_def();
                 if adt.is_struct();
                 let variant = adt.non_enum_variant();
-                if adt.did.is_local() || !variant.is_field_list_non_exhaustive();
+                if adt.did().is_local() || !variant.is_field_list_non_exhaustive();
                 let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id();
                 if variant
                     .fields
@@ -216,7 +216,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
                     if let ty::Adt(adt_def, substs) = binding_type.kind();
                     if !substs.is_empty();
                     then {
-                        let adt_def_ty_name = cx.tcx.item_name(adt_def.did);
+                        let adt_def_ty_name = cx.tcx.item_name(adt_def.did());
                         let generic_args = substs.iter().collect::<Vec<_>>();
                         let tys_str = generic_args
                             .iter()
index b80d55dd192a10201dc0fa67c4c49fd7cbdbdbea..f3996e5b44d74c6ad52f87a8938393b718cd4185 100644 (file)
@@ -148,7 +148,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
                 if_chain! {
                     if let Some(adt_def) = ty.ty_adt_def();
                     if adt_def.is_struct();
-                    if let Some(variant) = adt_def.variants.iter().next();
+                    if let Some(variant) = adt_def.variants().iter().next();
                     then {
                         let fields_def = &variant.fields;
 
index eccb18982f30da8a74e4f8a8626a94ef7c5e3189..14098340745b10b9a9654c0ccbd2d8684f5d8b3d 100644 (file)
@@ -103,7 +103,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
                     _ => false,
                 };
                 if should_emit {
-                    let path_string = cx.tcx.def_path_str(adt_def.did);
+                    let path_string = cx.tcx.def_path_str(adt_def.did());
                     span_lint_and_help(
                         cx,
                         DERIVABLE_IMPLS,
index 7277e4080c5c0763ffa132a28a48dc4fd394486d..557e101494e3acd87c9188336c3198cdb89fd639 100644 (file)
@@ -315,7 +315,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &T
             let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
                 impls
                     .iter()
-                    .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did == adt.did))
+                    .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did()))
             });
             if !has_copy_impl {
                 return;
@@ -357,10 +357,10 @@ fn has_unsafe<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>) -> bool {
         if let Some(trait_def_id) = trait_ref.trait_def_id();
         if match_def_path(cx, trait_def_id, &paths::SERDE_DESERIALIZE);
         if let ty::Adt(def, _) = ty.kind();
-        if let Some(local_def_id) = def.did.as_local();
+        if let Some(local_def_id) = def.did().as_local();
         let adt_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_def_id);
         if !is_lint_allowed(cx, UNSAFE_DERIVE_DESERIALIZE, adt_hir_id);
-        if cx.tcx.inherent_impls(def.did)
+        if cx.tcx.inherent_impls(def.did())
             .iter()
             .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
             .any(|imp| has_unsafe(cx, imp));
index af9e65e636135d8fb186f7390bb89d8047e46230..b5d6b3c7524baad8f64bea9069054624c990707e 100644 (file)
@@ -52,7 +52,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         if let ItemKind::Enum(..) = item.kind {
             let ty = cx.tcx.type_of(item.def_id);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
-            if adt.variants.is_empty() {
+            if adt.variants().is_empty() {
                 span_lint_and_help(
                     cx,
                     EMPTY_ENUM,
index 3b6661c817be7677fe01941e096af0e4f786c1ac..e2a5430da08c8c16bcfd1fdccbae12defb886b37 100644 (file)
@@ -55,7 +55,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
                     if let Some(Constant::Int(val)) = constant.and_then(miri_to_const) {
                         if let ty::Adt(adt, _) = ty.kind() {
                             if adt.is_enum() {
-                                ty = adt.repr.discr_type().to_ty(cx.tcx);
+                                ty = adt.repr().discr_type().to_ty(cx.tcx);
                             }
                         }
                         match ty.kind() {
index 6490231fed8a7195ee6c1b9cd62ed1554d43cac0..51c811b304cae663f71853125f579b5ea2e25576 100644 (file)
@@ -306,7 +306,7 @@ fn in_impl<'tcx>(
 fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
     if_chain! {
         if let ty::Adt(adt_def, _) = middle_ty.kind();
-        if let Some(local_did) = adt_def.did.as_local();
+        if let Some(local_did) = adt_def.did().as_local();
         let item = cx.tcx.hir().expect_item(local_did);
         let middle_ty_id = item.def_id.to_def_id();
         if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
index d23c0c225e192e84fc4ad27b0e6a5d3ac613713d..845863bd209c6ef4cc9696b68341bf9fee537437 100644 (file)
@@ -224,7 +224,7 @@ fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: DefId) -> String {
         ty::ImplContainer(def_id) => {
             let ty = cx.tcx.type_of(def_id);
             match ty.kind() {
-                ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did),
+                ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()),
                 _ => ty.to_string(),
             }
         },
index 395c920c9974c0a525772f0e5ae88c108458b40e..64c41b565878b36772fe2d2e5d17882c2f867314 100644 (file)
@@ -72,7 +72,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
             if_chain! {
                 if format_args.format_string_parts == [kw::Empty];
                 if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
-                    ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did),
+                    ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
                     ty::Str => true,
                     _ => false,
                 };
index ea9b68d1a40e3982a01dfa16b56541b940691cd3..0709580c8adfdd2ad66a15af13efcf76ebc98d94 100644 (file)
@@ -189,8 +189,8 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &m
         // primitive types are never mutable
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
         ty::Adt(adt, substs) => {
-            tys.insert(adt.did) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
-                || KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did, path))
+            tys.insert(adt.did()) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
+                || KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did(), path))
                     && substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
         },
         ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, span, tys)),
index 3d44a669d8f0507ed1870a6fe81a4bea12aa38d7..c8ec2f45137072539afbba571cb87541eb34bff7 100644 (file)
@@ -71,7 +71,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
             let ty = cx.typeck_results().expr_ty(expr);
             if let Some(adt_def) = ty.ty_adt_def();
             if adt_def.is_struct();
-            if let Some(variant) = adt_def.variants.iter().next();
+            if let Some(variant) = adt_def.variants().iter().next();
             if fields.iter().all(|f| f.is_shorthand);
             then {
                 let mut def_order_map = FxHashMap::default();
index d1dc6b775c567ed467214db9d66683f9d506a7b9..0f3889a2936188a8ffdb83aea483ce7504727785 100644 (file)
@@ -81,11 +81,11 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         if let ItemKind::Enum(ref def, _) = item.kind {
             let ty = cx.tcx.type_of(item.def_id);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
-            if adt.variants.len() <= 1 {
+            if adt.variants().len() <= 1 {
                 return;
             }
             let mut variants_size: Vec<VariantInfo> = Vec::new();
-            for (i, variant) in adt.variants.iter().enumerate() {
+            for (i, variant) in adt.variants().iter().enumerate() {
                 let mut fields_size = Vec::new();
                 for (i, f) in variant.fields.iter().enumerate() {
                     let ty = cx.tcx.type_of(f.did);
index 35d10d53112ec6c3591555833dcace76f3c9ed6c..dabbb8375f0a6ff97b030379624a2d3861cd8e7b 100644 (file)
@@ -248,13 +248,13 @@ enum LenOutput<'tcx> {
 fn parse_len_output<'tcx>(cx: &LateContext<'_>, sig: FnSig<'tcx>) -> Option<LenOutput<'tcx>> {
     match *sig.output().kind() {
         ty::Int(_) | ty::Uint(_) => Some(LenOutput::Integral),
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Option, adt.did) => {
-            subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did))
+        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) => {
+            subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did()))
         },
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did) => subs
+        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => subs
             .type_at(0)
             .is_integral()
-            .then(|| LenOutput::Result(adt.did, subs.type_at(1))),
+            .then(|| LenOutput::Result(adt.did(), subs.type_at(1))),
         _ => None,
     }
 }
@@ -263,8 +263,8 @@ impl LenOutput<'_> {
     fn matches_is_empty_output(self, ty: Ty<'_>) -> bool {
         match (self, ty.kind()) {
             (_, &ty::Bool) => true,
-            (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did => subs.type_at(0).is_bool(),
-            (Self::Result(id, err_ty), &ty::Adt(adt, subs)) if id == adt.did => {
+            (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(),
+            (Self::Result(id, err_ty), &ty::Adt(adt, subs)) if id == adt.did() => {
                 subs.type_at(0).is_bool() && subs.type_at(1) == err_ty
             },
             _ => false,
@@ -488,7 +488,7 @@ fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
                 .any(|item| is_is_empty(cx, item))
         }),
         ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
-        ty::Adt(id, _) => has_is_empty_impl(cx, id.did),
+        ty::Adt(id, _) => has_is_empty_impl(cx, id.did()),
         ty::Array(..) | ty::Slice(..) | ty::Str => true,
         _ => false,
     }
index f6ef87264c0a6f3b8f2a70cf3f3e3a44164c3f85..b31015d195b52007211e0bf97b04b39f9c19733e 100644 (file)
@@ -334,7 +334,7 @@ struct Start<'hir> {
 
 fn get_slice_like_element_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     match ty.kind() {
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Vec, adt.did) => Some(subs.type_at(0)),
+        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Vec, adt.did()) => Some(subs.type_at(0)),
         ty::Ref(_, subty, _) => get_slice_like_element_ty(cx, *subty),
         ty::Slice(ty) | ty::Array(ty, _) => Some(*ty),
         _ => None,
index 3515286d5b4af8e45596abfc7dd98ce51a1b2521..93bf0dc62e076707e4228e784a016a96b80c2f61 100644 (file)
@@ -45,8 +45,8 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
 
     // Accumulate the variants which should be put in place of the wildcard because they're not
     // already covered.
-    let has_hidden = adt_def.variants.iter().any(|x| is_hidden(cx, x));
-    let mut missing_variants: Vec<_> = adt_def.variants.iter().filter(|x| !is_hidden(cx, x)).collect();
+    let has_hidden = adt_def.variants().iter().any(|x| is_hidden(cx, x));
+    let mut missing_variants: Vec<_> = adt_def.variants().iter().filter(|x| !is_hidden(cx, x)).collect();
 
     let mut path_prefix = CommonPrefixSearcher::None;
     for arm in arms {
@@ -118,7 +118,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
                 }
                 s
             } else {
-                let mut s = cx.tcx.def_path_str(adt_def.did);
+                let mut s = cx.tcx.def_path_str(adt_def.did());
                 s.push_str("::");
                 s
             },
index ce958b8ac9f5991a82de380f4ce71575ac60381c..eec232e6d0989dd731c44b47902780d8f66a6076 100644 (file)
@@ -145,7 +145,7 @@ fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg:
         if_chain! {
             if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
             if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
-            if Some(adt.did) == cx.tcx.parent(vid);
+            if Some(adt.did()) == cx.tcx.parent(vid);
             then {} else { return false; }
         }
 
index 67a585edc2550615aa610d2c958f0a2591582c14..6d30bb5a278bb42ca9606aceed73bee80b46c5c1 100644 (file)
@@ -15,7 +15,7 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span,
     let inner_ty = match recv_ty.kind() {
         // `Option<T>` -> `T`
         ty::Adt(adt, subst)
-            if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && meets_msrv(msrv, &msrvs::OPTION_COPIED) =>
+            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, &msrvs::OPTION_COPIED) =>
         {
             subst.type_at(0)
         },
index 30c68186b3aef1468033f63161c9c5a7f1d1d724..558cb6bd64e7275a04e2ba49e27acb706eef8049 100644 (file)
@@ -119,9 +119,9 @@ pub(super) fn check<'tcx>(
             if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind;
             if let ExprKind::MethodCall(path, [filter_arg], _) = filter_body.value.kind;
             if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).ty_adt_def();
-            if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did) {
+            if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did()) {
                 Some(false)
-            } else if cx.tcx.is_diagnostic_item(sym::Result, opt_ty.did) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, opt_ty.did()) {
                 Some(true)
             } else {
                 None
index 7a255baffd745aa7855fb9a78be1f0762bbb0080..6e64e7f62220704fa6759a79d690428a38f63664 100644 (file)
@@ -17,7 +17,7 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
         let return_type = cx.typeck_results().expr_ty(expr);
         let input_type = cx.typeck_results().expr_ty(recv);
         let (input_type, ref_count) = peel_mid_ty_refs(input_type);
-        if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did));
+        if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did()));
         if return_type == input_type;
         then {
             let mut app = Applicability::MachineApplicable;
index c0f66feb48ae8c067ef1b006fb1e075cfda25bc4..06ead144afa24b459a406639721ea06fdf7a7f1a 100644 (file)
@@ -60,7 +60,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     }
 
     if let ty::Adt(adt, substs) = ty.kind() {
-        match_def_path(cx, adt.did, &paths::COW) && substs.type_at(1).is_str()
+        match_def_path(cx, adt.did(), &paths::COW) && substs.type_at(1).is_str()
     } else {
         false
     }
index 6782f64f2ca41f78a2128587741524dbd8cb2caa..e1212c31cfb021e561bbbb81a0cdf03c801eb1ef 100644 (file)
@@ -55,9 +55,9 @@ pub(super) fn check<'tcx>(
     // lint if caller of `.map().flatten()` is an Option or Result
     let caller_type = match cx.typeck_results().expr_ty(recv).kind() {
         ty::Adt(adt, _) => {
-            if cx.tcx.is_diagnostic_item(sym::Option, adt.did) {
+            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) {
                 "Option"
-            } else if cx.tcx.is_diagnostic_item(sym::Result, adt.did) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) {
                 "Result"
             } else {
                 return;
index 926c25b4b40a5c7aa2bd7c5003384ed5951fa857..8125930b3046144053a7ab4bf8e4063e2ef42675 100644 (file)
@@ -152,7 +152,7 @@ fn parse_iter_usage<'tcx>(
                     return if_chain! {
                         if match_def_path(cx, did, &paths::ITERTOOLS_NEXT_TUPLE);
                         if let ty::Adt(adt_def, subs) = cx.typeck_results().expr_ty(e).kind();
-                        if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did);
+                        if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did());
                         if let ty::Tuple(subs) = subs.type_at(0).kind();
                         if subs.len() == 2;
                         then {
index 12ad3d8d69038d3016ebf021f0fa7895603fa749..a307e33875ebb08b6a7b6ca9a0c73105e3177c66 100644 (file)
@@ -33,7 +33,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
         } else if !found_mapping && !mutates_arg {
             let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
             match cx.typeck_results().expr_ty(&body.value).kind() {
-                ty::Adt(adt, subst) if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && in_ty == subst.type_at(0) => {
+                ty::Adt(adt, subst) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && in_ty == subst.type_at(0) => {
                     "filter"
                 },
                 _ => return,
index ce9ca15430e421cd16455c52b80508ebda522b59..cba54e14212d0d18949213c00db27d684eea1237 100644 (file)
@@ -125,7 +125,7 @@ fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
     if let Adt(def, substs) = ty.kind() {
         let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
             .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did));
+            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
         if is_keyed_type && is_interior_mutable_type(cx, substs.type_at(0), span) {
             span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
         }
@@ -159,8 +159,8 @@ fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Sp
                 sym::Arc,
             ]
             .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did));
-            let is_box = Some(def.did) == cx.tcx.lang_items().owned_box();
+            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
+            let is_box = Some(def.did()) == cx.tcx.lang_items().owned_box();
             if is_std_collection || is_box {
                 // The type is mutable if any of its type parameters are
                 substs.types().any(|ty| is_interior_mutable_type(cx, ty, span))
index ebfd908a6fb741692149fe5a491bf1612680221a..a57dc2b27986f93a294af0f03f9597ccb9e12574 100644 (file)
@@ -198,7 +198,7 @@ fn check_fn(
                     // Dereference suggestion
                     let sugg = |diag: &mut Diagnostic| {
                         if let ty::Adt(def, ..) = ty.kind() {
-                            if let Some(span) = cx.tcx.hir().span_if_local(def.did) {
+                            if let Some(span) = cx.tcx.hir().span_if_local(def.did()) {
                                 if can_type_implement_copy(cx.tcx, cx.param_env, ty, traits::ObligationCause::dummy_with_span(span)).is_ok() {
                                     diag.span_help(span, "consider marking this type as `Copy`");
                                 }
index ed315efaa2fa7c546de3a7fabce42dc2997a80f5..c87c174ef732cb71824640bd7932ee874402c0b4 100644 (file)
@@ -54,7 +54,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
             let ty = cx.typeck_results().expr_ty(expr);
             if let ty::Adt(def, _) = ty.kind() {
                 if fields.len() == def.non_enum_variant().fields.len()
-                    && !def.variants[0_usize.into()].is_field_list_non_exhaustive()
+                    && !def.variant(0_usize.into()).is_field_list_non_exhaustive()
                 {
                     span_lint(
                         cx,
index 6c68c1bc48df88777a836650052e09f551eb0c00..9419056be14325a39b7912c51dfbbdcbe9604fc2 100644 (file)
@@ -113,7 +113,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
                                     let mut impls = HirIdSet::default();
                                     cx.tcx.for_each_impl(default_trait_id, |d| {
                                         if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
-                                            if let Some(local_def_id) = ty_def.did.as_local() {
+                                            if let Some(local_def_id) = ty_def.did().as_local() {
                                                 impls.insert(cx.tcx.hir().local_def_id_to_hir_id(local_def_id));
                                             }
                                         }
@@ -126,7 +126,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
                                 if_chain! {
                                     if let Some(ref impling_types) = self.impling_types;
                                     if let Some(self_def) = cx.tcx.type_of(self_def_id).ty_adt_def();
-                                    if let Some(self_local_did) = self_def.did.as_local();
+                                    if let Some(self_local_did) = self_def.did().as_local();
                                     let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
                                     if impling_types.contains(&self_id);
                                     then {
index 3ba99403f06d005645138f6511fd9e1c3d5418e9..8db41ba6ee296f399877221d2c24b77d6c0e6e06 100644 (file)
@@ -140,7 +140,7 @@ fn inner<'tcx>(cx: &LateContext<'tcx>, val: Const<'tcx>) -> bool {
         match val.ty().kind() {
             // the fact that we have to dig into every structs to search enums
             // leads us to the point checking `UnsafeCell` directly is the only option.
-            ty::Adt(ty_def, ..) if Some(ty_def.did) == cx.tcx.lang_items().unsafe_cell_type() => true,
+            ty::Adt(ty_def, ..) if Some(ty_def.did()) == cx.tcx.lang_items().unsafe_cell_type() => true,
             ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
                 let val = cx.tcx.destructure_const(cx.param_env.and(val));
                 val.fields.iter().any(|field| inner(cx, *field))
index 5168ca67b6abb86c135264f6bb7b273474e2db20..ddef7352de8891075d5a38ee8a6ae0f286e8d720 100644 (file)
@@ -96,7 +96,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
                 let mut non_send_fields = Vec::new();
 
                 let hir_map = cx.tcx.hir();
-                for variant in &adt_def.variants {
+                for variant in adt_def.variants() {
                     for field in &variant.fields {
                         if_chain! {
                             if let Some(field_hir_id) = field
@@ -233,7 +233,7 @@ fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> b
                     return true;
                 },
                 ty::Adt(adt_def, _) => {
-                    if match_def_path(cx, adt_def.did, &paths::PTR_NON_NULL) {
+                    if match_def_path(cx, adt_def.did(), &paths::PTR_NON_NULL) {
                         return true;
                     }
                 },
index 2c328195f24e1af1a6cc792f960d568e09b3b837..9c776437d7fe5554efb0032f27930c6660854a21 100644 (file)
@@ -405,13 +405,13 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                 // Check that the name as typed matches the actual name of the type.
                 // e.g. `fn foo(_: &Foo)` shouldn't trigger the lint when `Foo` is an alias for `Vec`
                 if let [.., name] = path.segments;
-                if cx.tcx.item_name(adt.did) == name.ident.name;
+                if cx.tcx.item_name(adt.did()) == name.ident.name;
 
                 if !is_lint_allowed(cx, PTR_ARG, hir_ty.hir_id);
                 if params.get(i).map_or(true, |p| !is_lint_allowed(cx, PTR_ARG, p.hir_id));
 
                 then {
-                    let (method_renames, deref_ty, deref_impl_id) = match cx.tcx.get_diagnostic_name(adt.did) {
+                    let (method_renames, deref_ty, deref_impl_id) = match cx.tcx.get_diagnostic_name(adt.did()) {
                         Some(sym::Vec) => (
                             [("clone", ".to_owned()")].as_slice(),
                             DerefTy::Slice(
@@ -462,7 +462,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                     return Some(PtrArg {
                         idx: i,
                         span: hir_ty.span,
-                        ty_did: adt.did,
+                        ty_did: adt.did(),
                         ty_name: name.ident.name,
                         method_renames,
                         ref_prefix: RefPrefix {
@@ -570,7 +570,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
                             .map(|sig| sig.input(i).skip_binder().peel_refs())
                             .map_or(true, |ty| match *ty.kind() {
                                 ty::Param(_) => true,
-                                ty::Adt(def, _) => def.did == args.ty_did,
+                                ty::Adt(def, _) => def.did() == args.ty_did,
                                 _ => false,
                             })
                         {
@@ -607,7 +607,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
                             // If the types match check for methods which exist on both types. e.g. `Vec::len` and
                             // `slice::len`
                             ty::Adt(def, _)
-                                if def.did == args.ty_did
+                                if def.did() == args.ty_did
                                     && (i != 0
                                         || self.cx.tcx.trait_of_item(id).is_some()
                                         || !args.deref_assoc_items.map_or(false, |(id, items)| {
index 123d0ad0457d1f1d5c2dff1f13c3f5eee0f6eb28..d07c26d7c8975da63108f5ec5e9af7efd2ab8ebd 100644 (file)
@@ -72,7 +72,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
 
         if_chain! {
             if let Some(self_def) = self_ty.ty_adt_def();
-            if let Some(self_local_did) = self_def.did.as_local();
+            if let Some(self_local_did) = self_def.did().as_local();
             let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
             if let Some(Node::Item(x)) = cx.tcx.hir().find(self_id);
             let type_name = x.ident.name.as_str().to_lowercase();
index 81076776ed3d333ad00dc1271fa17ff199a6fc70..6edff2240920f3665568ea762e39561de0e9be80 100644 (file)
@@ -141,7 +141,7 @@ pub(super) fn check<'tcx>(
                                 then {
                                     diag.note(&format!(
                                         "two instances of the same generic type (`{}`) may have different layouts",
-                                        cx.tcx.item_name(from_def.did)
+                                        cx.tcx.item_name(from_def.did())
                                     ));
                                 } else {
                                     if from_ty_orig.peel_refs() != from_ty {
@@ -304,13 +304,13 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
                     ty = sized_ty;
                     continue;
                 }
-                if def.repr.inhibit_struct_field_reordering_opt() {
+                if def.repr().inhibit_struct_field_reordering_opt() {
                     ReducedTy::OrderedFields(ty)
                 } else {
                     ReducedTy::UnorderedFields(ty)
                 }
             },
-            ty::Adt(def, _) if def.is_enum() && (def.variants.is_empty() || is_c_void(cx, ty)) => {
+            ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
                 ReducedTy::TypeErasure
             },
             ty::Foreign(_) => ReducedTy::TypeErasure,
index 2d67401a15f2d65b96cacdbaa0f92e69c6ae7fce..831b0d450d20a7f933a6bd380dc370db37710a9e 100644 (file)
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
         (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
-            if from_adt.did != to_adt.did {
+            if from_adt.did() != to_adt.did() {
                 return false;
             }
             if !matches!(
-                cx.tcx.get_diagnostic_name(to_adt.did),
+                cx.tcx.get_diagnostic_name(to_adt.did()),
                 Some(
                     sym::BTreeMap
                         | sym::BTreeSet
index 4da32c52e750a06e47e1c68a840a83df0c429b8d..80d6f3c633670dc207c315c15b667cdbc78f6da7 100644 (file)
@@ -151,11 +151,11 @@ fn result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
 fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     if_chain! {
         if let ty::Adt(def, subst) = ty.kind();
-        if match_def_path(cx, def.did, &paths::POLL);
+        if match_def_path(cx, def.did(), &paths::POLL);
         let ready_ty = subst.type_at(0);
 
         if let ty::Adt(ready_def, ready_subst) = ready_ty.kind();
-        if cx.tcx.is_diagnostic_item(sym::Result, ready_def.did);
+        if cx.tcx.is_diagnostic_item(sym::Result, ready_def.did());
         then {
             Some(ready_subst.type_at(1))
         } else {
@@ -168,15 +168,15 @@ fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<
 fn poll_option_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     if_chain! {
         if let ty::Adt(def, subst) = ty.kind();
-        if match_def_path(cx, def.did, &paths::POLL);
+        if match_def_path(cx, def.did(), &paths::POLL);
         let ready_ty = subst.type_at(0);
 
         if let ty::Adt(ready_def, ready_subst) = ready_ty.kind();
-        if cx.tcx.is_diagnostic_item(sym::Option, ready_def.did);
+        if cx.tcx.is_diagnostic_item(sym::Option, ready_def.did());
         let some_ty = ready_subst.type_at(0);
 
         if let ty::Adt(some_def, some_subst) = some_ty.kind();
-        if cx.tcx.is_diagnostic_item(sym::Result, some_def.did);
+        if cx.tcx.is_diagnostic_item(sym::Result, some_def.did());
         then {
             Some(some_subst.type_at(1))
         } else {
index 1728533f18b858caeb6b9814f37ff2dcdbbc5e78..f4f5a4336a39ec7ad4ae0800207e429f986f1f4d 100644 (file)
@@ -102,9 +102,9 @@ fn check_fn(
 
         // Get the wrapper and inner types, if can't, abort.
         let (return_type_label, lang_item, inner_type) = if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id).kind() {
-            if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did) {
+            if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) {
                 ("Option", OptionSome, subst.type_at(0))
-            } else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) {
                 ("Result", ResultOk, subst.type_at(0))
             } else {
                 return;
index eb9efec3f1612a8f7af66888ba3b3534e726f400..a6ef6d79fc023f33a83896292a35dec6db694103 100644 (file)
@@ -73,7 +73,7 @@ fn fn_eagerness<'tcx>(
         // than marker traits.
         // Due to the limited operations on these types functions should be fairly cheap.
         if def
-            .variants
+            .variants()
             .iter()
             .flat_map(|v| v.fields.iter())
             .any(|x| matches!(cx.tcx.type_of(x.did).peel_refs().kind(), ty::Param(_)))
index 8c14f0dd761a20be5e0dd7a318aa53085a8911fe..cd20abd94ed256811487649df709158ec74f4a01 100644 (file)
@@ -268,7 +268,7 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str])
 pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
     if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
         if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
-            return cx.tcx.is_diagnostic_item(diag_item, adt.did);
+            return cx.tcx.is_diagnostic_item(diag_item, adt.did());
         }
     }
     false
@@ -657,7 +657,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
                 if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
                     return std_types_symbols
                         .iter()
-                        .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did));
+                        .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()));
                 }
             }
         }
index 0646d1524a767310ee26d879649a16a441d8ee5e..3645a9a5228cc9da4fcdcd98532c44c9700cd915 100644 (file)
@@ -51,7 +51,7 @@ pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool {
 
 /// Walks into `ty` and returns `true` if any inner type is an instance of the given adt
 /// constructor.
-pub fn contains_adt_constructor(ty: Ty<'_>, adt: &AdtDef) -> bool {
+pub fn contains_adt_constructor(ty: Ty<'_>, adt: AdtDef<'_>) -> bool {
     ty.walk().any(|inner| match inner.unpack() {
         GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt),
         GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
@@ -112,7 +112,7 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<
     let def_id = match ty_to_check.kind() {
         ty::Array(..) => return Some(sym::array),
         ty::Slice(..) => return Some(sym::slice),
-        ty::Adt(adt, _) => adt.did,
+        ty::Adt(adt, _) => adt.did(),
         _ => return None,
     };
 
@@ -164,7 +164,7 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 // Returns whether the type has #[must_use] attribute
 pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => must_use_attr(cx.tcx.get_attrs(adt.did)).is_some(),
+        ty::Adt(adt, _) => must_use_attr(cx.tcx.get_attrs(adt.did())).is_some(),
         ty::Foreign(ref did) => must_use_attr(cx.tcx.get_attrs(*did)).is_some(),
         ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
             // for the Array case we don't need to care for the len == 0 case
@@ -220,7 +220,7 @@ fn is_normalizable_helper<'tcx>(
         let cause = rustc_middle::traits::ObligationCause::dummy();
         if infcx.at(&cause, param_env).normalize(ty).is_ok() {
             match ty.kind() {
-                ty::Adt(def, substs) => def.variants.iter().all(|variant| {
+                ty::Adt(def, substs) => def.variants().iter().all(|variant| {
                     variant
                         .fields
                         .iter()
@@ -264,7 +264,7 @@ pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
 pub fn is_type_ref_to_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool {
     match ty.kind() {
         ty::Ref(_, ref_ty, _) => match ref_ty.kind() {
-            ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did),
+            ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did()),
             _ => false,
         },
         _ => false,
@@ -284,7 +284,7 @@ pub fn is_type_ref_to_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_ite
 /// [Diagnostic Items]: https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html
 pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did),
+        ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did()),
         _ => false,
     }
 }
@@ -294,7 +294,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
 /// Returns `false` if the `LangItem` is not defined.
 pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).map_or(false, |li| li == adt.did),
+        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).map_or(false, |li| li == adt.did()),
         _ => false,
     }
 }
@@ -310,7 +310,7 @@ pub fn is_isize_or_usize(typ: Ty<'_>) -> bool {
 /// If you change the signature, remember to update the internal lint `MatchTypeOnDiagItem`
 pub fn match_type(cx: &LateContext<'_>, ty: Ty<'_>, path: &[&str]) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
+        ty::Adt(adt, _) => match_def_path(cx, adt.did(), path),
         _ => false,
     }
 }
@@ -398,7 +398,7 @@ pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     match *ty.kind() {
         ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component),
         ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
-        ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did),
+        ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did()),
         _ => false,
     }
 }
@@ -562,11 +562,11 @@ pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue>
 }
 
 /// Gets the value of the given variant.
-pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: &'_ AdtDef, i: VariantIdx) -> EnumValue {
-    let variant = &adt.variants[i];
+pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: AdtDef<'_>, i: VariantIdx) -> EnumValue {
+    let variant = &adt.variant(i);
     match variant.discr {
         VariantDiscr::Explicit(id) => read_explicit_enum_value(tcx, id).unwrap(),
-        VariantDiscr::Relative(x) => match adt.variants[(i.as_usize() - x as usize).into()].discr {
+        VariantDiscr::Relative(x) => match adt.variant((i.as_usize() - x as usize).into()).discr {
             VariantDiscr::Explicit(id) => read_explicit_enum_value(tcx, id).unwrap() + x,
             VariantDiscr::Relative(_) => EnumValue::Unsigned(x.into()),
         },
@@ -577,7 +577,7 @@ pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: &'_ AdtDef, i: VariantIdx) -
 /// platform specific `libc::<platform>::c_void` types in libc.
 pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     if let ty::Adt(adt, _) = ty.kind()
-        && let &[krate, .., name] = &*cx.get_def_path(adt.did)
+        && let &[krate, .., name] = &*cx.get_def_path(adt.did())
         && let sym::libc | sym::core | sym::std = krate
         && name.as_str() == "c_void"
     {
index 722475ccc143d2dbf9fad5891207dcb5576e3d17..a12a48bf723e0e13f043979a7f79861d975e7187 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 722475ccc143d2dbf9fad5891207dcb5576e3d17
+Subproject commit a12a48bf723e0e13f043979a7f79861d975e7187