Skip to content

Commit bba9785

Browse files
committed
Auto merge of #100720 - camsteffen:representable, r=cjgillot
Rewrite representability * Improve placement of `Box` in the suggestion * Multiple items in a cycle emit 1 error instead of an error for each item in the cycle * Introduce `representability` query to avoid traversing an item every time it is used. * Also introduce `params_in_repr` query to avoid traversing generic items every time it is used.
2 parents a688a03 + ff940db commit bba9785

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+529
-736
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3552,7 +3552,6 @@ dependencies = [
35523552
"rustc_span",
35533553
"rustc_target",
35543554
"rustc_trait_selection",
3555-
"rustc_ty_utils",
35563555
"rustc_type_ir",
35573556
"smallvec",
35583557
"tracing",

compiler/rustc_hir_analysis/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ rustc_span = { path = "../rustc_span" }
2626
rustc_index = { path = "../rustc_index" }
2727
rustc_infer = { path = "../rustc_infer" }
2828
rustc_trait_selection = { path = "../rustc_trait_selection" }
29-
rustc_ty_utils = { path = "../rustc_ty_utils" }
3029
rustc_lint = { path = "../rustc_lint" }
3130
rustc_serialize = { path = "../rustc_serialize" }
3231
rustc_type_ir = { path = "../rustc_type_ir" }

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ use rustc_span::{self, Span};
3131
use rustc_target::spec::abi::Abi;
3232
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
3333
use rustc_trait_selection::traits::{self, ObligationCtxt};
34-
use rustc_ty_utils::representability::{self, Representability};
3534

3635
use std::ops::ControlFlow;
3736

@@ -381,7 +380,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
381380
let def = tcx.adt_def(def_id);
382381
let span = tcx.def_span(def_id);
383382
def.destructor(tcx); // force the destructor to be evaluated
384-
check_representable(tcx, span, def_id);
383+
let _ = tcx.representability(def_id);
385384

386385
if def.repr().simd() {
387386
check_simd(tcx, span, def_id);
@@ -395,7 +394,7 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
395394
let def = tcx.adt_def(def_id);
396395
let span = tcx.def_span(def_id);
397396
def.destructor(tcx); // force the destructor to be evaluated
398-
check_representable(tcx, span, def_id);
397+
let _ = tcx.representability(def_id);
399398
check_transparent(tcx, span, def);
400399
check_union_fields(tcx, span, def_id);
401400
check_packed(tcx, span, def);
@@ -1151,27 +1150,6 @@ fn check_impl_items_against_trait<'tcx>(
11511150
}
11521151
}
11531152

1154-
/// Checks whether a type can be represented in memory. In particular, it
1155-
/// identifies types that contain themselves without indirection through a
1156-
/// pointer, which would mean their size is unbounded.
1157-
pub(super) fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
1158-
let rty = tcx.type_of(item_def_id);
1159-
1160-
// Check that it is possible to represent this type. This call identifies
1161-
// (1) types that contain themselves and (2) types that contain a different
1162-
// recursive type. It is only necessary to throw an error on those that
1163-
// contain themselves. For case 2, there must be an inner type that will be
1164-
// caught by case 1.
1165-
match representability::ty_is_representable(tcx, rty, sp, None) {
1166-
Representability::SelfRecursive(spans) => {
1167-
recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
1168-
return false;
1169-
}
1170-
Representability::Representable | Representability::ContainsRecursive => (),
1171-
}
1172-
true
1173-
}
1174-
11751153
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
11761154
let t = tcx.type_of(def_id);
11771155
if let ty::Adt(def, substs) = t.kind()
@@ -1509,7 +1487,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
15091487

15101488
detect_discriminant_duplicate(tcx, def.discriminants(tcx).collect(), vs, sp);
15111489

1512-
check_representable(tcx, sp, def_id);
1490+
let _ = tcx.representability(def_id);
15131491
check_transparent(tcx, sp, def);
15141492
}
15151493

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ use rustc_span::{self, BytePos, Span, Symbol};
123123
use rustc_target::abi::VariantIdx;
124124
use rustc_target::spec::abi::Abi;
125125
use rustc_trait_selection::traits;
126-
use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
127126
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
128127
use std::cell::RefCell;
129128
use std::num::NonZeroU32;

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ macro_rules! pluralize {
2525
($x:expr) => {
2626
if $x != 1 { "s" } else { "" }
2727
};
28+
("has", $x:expr) => {
29+
if $x == 1 { "has" } else { "have" }
30+
};
2831
("is", $x:expr) => {
2932
if $x == 1 { "is" } else { "are" }
3033
};

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ provide! { tcx, def_id, other, cdata,
210210
lookup_const_stability => { table }
211211
lookup_default_body_stability => { table }
212212
lookup_deprecation_entry => { table }
213+
params_in_repr => { table }
213214
unused_generic_params => { table }
214215
opt_def_kind => { table_direct }
215216
impl_parent => { table }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
11561156
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
11571157
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
11581158
}
1159+
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
1160+
let params_in_repr = self.tcx.params_in_repr(def_id);
1161+
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
1162+
}
11591163
if should_encode_trait_impl_trait_tys(tcx, def_id)
11601164
&& let Ok(table) = self.tcx.collect_trait_impl_trait_tys(def_id)
11611165
{

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use rustc_hir::def::{CtorKind, DefKind};
1313
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
1414
use rustc_hir::definitions::DefKey;
1515
use rustc_hir::lang_items;
16-
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
16+
use rustc_index::bit_set::{BitSet, FiniteBitSet};
17+
use rustc_index::vec::IndexVec;
1718
use rustc_middle::metadata::ModChild;
1819
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
1920
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
@@ -383,6 +384,7 @@ define_tables! {
383384
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
384385
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
385386
unused_generic_params: Table<DefIndex, LazyValue<FiniteBitSet<u32>>>,
387+
params_in_repr: Table<DefIndex, LazyValue<BitSet<u32>>>,
386388
repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
387389
// `def_keys` and `def_path_hashes` represent a lazy version of a
388390
// `DefPathTable`. This allows us to avoid deserializing an entire

compiler/rustc_middle/src/arena.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ macro_rules! arena_types {
103103
[] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>,
104104

105105
[decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
106+
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
106107
]);
107108
)
108109
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,32 @@ rustc_queries! {
301301
separate_provide_extern
302302
}
303303

304+
/// Checks whether a type is representable or infinitely sized
305+
query representability(_: LocalDefId) -> rustc_middle::ty::Representability {
306+
desc { "checking if {:?} is representable", tcx.def_path_str(key.to_def_id()) }
307+
// infinitely sized types will cause a cycle
308+
cycle_delay_bug
309+
// we don't want recursive representability calls to be forced with
310+
// incremental compilation because, if a cycle occurs, we need the
311+
// entire cycle to be in memory for diagnostics
312+
anon
313+
}
314+
315+
/// An implementation detail for the `representability` query
316+
query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability {
317+
desc { "checking if {:?} is representable", key }
318+
cycle_delay_bug
319+
anon
320+
}
321+
322+
/// Set of param indexes for type params that are in the type's representation
323+
query params_in_repr(key: DefId) -> rustc_index::bit_set::BitSet<u32> {
324+
desc { "finding type parameters in the representation" }
325+
arena_cache
326+
no_hash
327+
separate_provide_extern
328+
}
329+
304330
/// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
305331
query thir_body(key: ty::WithOptConstParam<LocalDefId>)
306332
-> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed>

0 commit comments

Comments
 (0)