Check representability in adt_sized_constraint
This commit is contained in:
parent
0265a3e93b
commit
d933092dc5
@ -380,7 +380,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
def.destructor(tcx); // force the destructor to be evaluated
|
def.destructor(tcx); // force the destructor to be evaluated
|
||||||
let _ = tcx.representability(def_id);
|
|
||||||
|
|
||||||
if def.repr().simd() {
|
if def.repr().simd() {
|
||||||
check_simd(tcx, span, def_id);
|
check_simd(tcx, span, def_id);
|
||||||
@ -394,7 +393,6 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
def.destructor(tcx); // force the destructor to be evaluated
|
def.destructor(tcx); // force the destructor to be evaluated
|
||||||
let _ = tcx.representability(def_id);
|
|
||||||
check_transparent(tcx, span, def);
|
check_transparent(tcx, span, def);
|
||||||
check_union_fields(tcx, span, def_id);
|
check_union_fields(tcx, span, def_id);
|
||||||
check_packed(tcx, span, def);
|
check_packed(tcx, span, def);
|
||||||
@ -1487,7 +1485,6 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
|
|||||||
|
|
||||||
detect_discriminant_duplicate(tcx, def.discriminants(tcx).collect(), vs, sp);
|
detect_discriminant_duplicate(tcx, def.discriminants(tcx).collect(), vs, sp);
|
||||||
|
|
||||||
let _ = tcx.representability(def_id);
|
|
||||||
check_transparent(tcx, sp, def);
|
check_transparent(tcx, sp, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,6 +1041,8 @@ fn check_type_defn<'tcx, F>(
|
|||||||
) where
|
) where
|
||||||
F: FnMut(&WfCheckingCtxt<'_, 'tcx>) -> Vec<AdtVariant<'tcx>>,
|
F: FnMut(&WfCheckingCtxt<'_, 'tcx>) -> Vec<AdtVariant<'tcx>>,
|
||||||
{
|
{
|
||||||
|
let _ = tcx.representability(item.def_id.def_id);
|
||||||
|
|
||||||
enter_wf_checking_ctxt(tcx, item.span, item.def_id.def_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, item.span, item.def_id.def_id, |wfcx| {
|
||||||
let variants = lookup_fields(wfcx);
|
let variants = lookup_fields(wfcx);
|
||||||
let packed = tcx.adt_def(item.def_id).repr().packed();
|
let packed = tcx.adt_def(item.def_id).repr().packed();
|
||||||
|
@ -613,16 +613,8 @@ rustc_queries! {
|
|||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
// The cycle error here should be reported as an error by `check_representable`.
|
query adt_sized_constraint(key: DefId) -> &'tcx [Ty<'tcx>] {
|
||||||
// We consider the type as Sized in the meanwhile to avoid
|
|
||||||
// further errors (done in impl Value for AdtSizedConstraint).
|
|
||||||
// Use `cycle_delay_bug` to delay the cycle error here to be emitted later
|
|
||||||
// in case we accidentally otherwise don't emit an error.
|
|
||||||
query adt_sized_constraint(
|
|
||||||
key: DefId
|
|
||||||
) -> AdtSizedConstraint<'tcx> {
|
|
||||||
desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) }
|
||||||
cycle_delay_bug
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query adt_dtorck_constraint(
|
query adt_dtorck_constraint(
|
||||||
|
@ -26,9 +26,6 @@ use super::{
|
|||||||
Destructor, FieldDef, GenericPredicates, ReprOptions, Ty, TyCtxt, VariantDef, VariantDiscr,
|
Destructor, FieldDef, GenericPredicates, ReprOptions, Ty, TyCtxt, VariantDef, VariantDiscr,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone, HashStable, Debug)]
|
|
||||||
pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);
|
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(HashStable, TyEncodable, TyDecodable)]
|
#[derive(HashStable, TyEncodable, TyDecodable)]
|
||||||
pub struct AdtFlags: u32 {
|
pub struct AdtFlags: u32 {
|
||||||
@ -563,7 +560,7 @@ impl<'tcx> AdtDef<'tcx> {
|
|||||||
/// Due to normalization being eager, this applies even if
|
/// Due to normalization being eager, this applies even if
|
||||||
/// the associated type is behind a pointer (e.g., issue #31299).
|
/// the associated type is behind a pointer (e.g., issue #31299).
|
||||||
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
|
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
|
||||||
ty::EarlyBinder(tcx.adt_sized_constraint(self.did()).0)
|
ty::EarlyBinder(tcx.adt_sized_constraint(self.did()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ use crate::ty::layout::TyAndLayout;
|
|||||||
use crate::ty::subst::{GenericArg, SubstsRef};
|
use crate::ty::subst::{GenericArg, SubstsRef};
|
||||||
use crate::ty::util::AlwaysRequiresDrop;
|
use crate::ty::util::AlwaysRequiresDrop;
|
||||||
use crate::ty::GeneratorDiagnosticData;
|
use crate::ty::GeneratorDiagnosticData;
|
||||||
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
|
use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::expand::allocator::AllocatorKind;
|
use rustc_ast::expand::allocator::AllocatorKind;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
|
@ -3,7 +3,7 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_middle::ty::Representability;
|
use rustc_middle::ty::Representability;
|
||||||
use rustc_middle::ty::{self, AdtSizedConstraint, DefIdTree, Ty, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
|
||||||
use rustc_query_system::query::QueryInfo;
|
use rustc_query_system::query::QueryInfo;
|
||||||
use rustc_query_system::Value;
|
use rustc_query_system::Value;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
@ -31,18 +31,6 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Value<TyCtxt<'tcx>> for AdtSizedConstraint<'_> {
|
|
||||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo]) -> Self {
|
|
||||||
// SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
|
|
||||||
// FIXME: Represent the above fact in the trait system somehow.
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute::<AdtSizedConstraint<'tcx>, AdtSizedConstraint<'_>>(
|
|
||||||
AdtSizedConstraint(tcx.intern_type_list(&[tcx.ty_error()])),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
|
impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
|
||||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo]) -> Self {
|
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo]) -> Self {
|
||||||
let err = tcx.ty_error();
|
let err = tcx.ty_error();
|
||||||
|
@ -85,9 +85,13 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
|
|||||||
/// - a type parameter or projection whose Sizedness can't be known
|
/// - a type parameter or projection whose Sizedness can't be known
|
||||||
/// - a tuple of type parameters or projections, if there are multiple
|
/// - a tuple of type parameters or projections, if there are multiple
|
||||||
/// such.
|
/// such.
|
||||||
/// - an Error, if a type contained itself. The representability
|
/// - an Error, if a type is infinitely sized
|
||||||
/// check should catch this case.
|
fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
|
||||||
fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstraint<'_> {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
|
if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
|
||||||
|
return tcx.intern_type_list(&[tcx.ty_error()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
|
|
||||||
let result = tcx.mk_type_list(
|
let result = tcx.mk_type_list(
|
||||||
@ -99,7 +103,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstrain
|
|||||||
|
|
||||||
debug!("adt_sized_constraint: {:?} => {:?}", def, result);
|
debug!("adt_sized_constraint: {:?} => {:?}", def, result);
|
||||||
|
|
||||||
ty::AdtSizedConstraint(result)
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See `ParamEnv` struct definition for details.
|
/// See `ParamEnv` struct definition for details.
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
|
// check-pass
|
||||||
// normalize-stderr-test: "`.*`" -> "`DEF_ID`"
|
// normalize-stderr-test: "`.*`" -> "`DEF_ID`"
|
||||||
// normalize-stdout-test: "`.*`" -> "`DEF_ID`"
|
// normalize-stdout-test: "`.*`" -> "`DEF_ID`"
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
|
||||||
pub async fn f() -> impl std::fmt::Debug {
|
pub async fn f() -> impl std::fmt::Debug {
|
||||||
|
// rustdoc doesn't care that this is infinitely sized
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum E {
|
enum E {
|
||||||
//~^ ERROR recursive type `f::{closure#0}::E` has infinite size
|
|
||||||
This(E),
|
This(E),
|
||||||
Unit,
|
Unit,
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
error[E0072]: recursive type `DEF_ID` has infinite size
|
|
||||||
--> $DIR/infinite-recursive-type-impl-trait-return.rs:7:5
|
|
||||||
|
|
|
||||||
LL | enum E {
|
|
||||||
| ^^^^^^
|
|
||||||
LL |
|
|
||||||
LL | This(E),
|
|
||||||
| - recursive without indirection
|
|
||||||
|
|
|
||||||
help: insert some indirection (e.g., a `DEF_ID`) to break the cycle
|
|
||||||
|
|
|
||||||
LL | This(Box<E>),
|
|
||||||
| ++++ +
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `DEF_ID`.
|
|
@ -1,6 +1,8 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
fn f() -> impl Sized {
|
fn f() -> impl Sized {
|
||||||
|
// rustdoc doesn't care that this is infinitely sized
|
||||||
enum E {
|
enum E {
|
||||||
//~^ ERROR recursive type `f::E` has infinite size
|
|
||||||
V(E),
|
V(E),
|
||||||
}
|
}
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
error[E0072]: recursive type `f::E` has infinite size
|
|
||||||
--> $DIR/infinite-recursive-type-impl-trait.rs:2:5
|
|
||||||
|
|
|
||||||
LL | enum E {
|
|
||||||
| ^^^^^^
|
|
||||||
LL |
|
|
||||||
LL | V(E),
|
|
||||||
| - recursive without indirection
|
|
||||||
|
|
|
||||||
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
|
||||||
|
|
|
||||||
LL | V(Box<E>),
|
|
||||||
| ++++ +
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0072`.
|
|
@ -3,7 +3,6 @@ use std::collections::BTreeSet;
|
|||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
pub enum ElemDerived {
|
pub enum ElemDerived {
|
||||||
//~^ ERROR recursive type `ElemDerived` has infinite size
|
//~^ ERROR recursive type `ElemDerived` has infinite size
|
||||||
//~| ERROR cycle detected when computing drop-check constraints for `ElemDerived`
|
|
||||||
A(ElemDerived)
|
A(ElemDerived)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ error[E0072]: recursive type `ElemDerived` has infinite size
|
|||||||
|
|
|
|
||||||
LL | pub enum ElemDerived {
|
LL | pub enum ElemDerived {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
...
|
LL |
|
||||||
LL | A(ElemDerived)
|
LL | A(ElemDerived)
|
||||||
| ----------- recursive without indirection
|
| ----------- recursive without indirection
|
||||||
|
|
|
|
||||||
@ -12,20 +12,6 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
|||||||
LL | A(Box<ElemDerived>)
|
LL | A(Box<ElemDerived>)
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing drop-check constraints for `ElemDerived`
|
error: aborting due to previous error
|
||||||
--> $DIR/issue-72554.rs:4:1
|
|
||||||
|
|
|
||||||
LL | pub enum ElemDerived {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: ...which immediately requires computing drop-check constraints for `ElemDerived` again
|
|
||||||
note: cycle used when computing drop-check constraints for `Elem`
|
|
||||||
--> $DIR/issue-72554.rs:11:1
|
|
||||||
|
|
|
||||||
LL | pub enum Elem {
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0072`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0072, E0391.
|
|
||||||
For more information about an error, try `rustc --explain E0072`.
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Test that disallow lifetime parameters that are unused.
|
// Test that disallow lifetime parameters that are unused.
|
||||||
|
|
||||||
enum Foo<'a> { //~ ERROR parameter `'a` is never used
|
enum Foo<'a> { //~ ERROR parameter `'a` is never used
|
||||||
|
//~^ ERROR recursive types `Foo` and `Bar` have infinite size
|
||||||
Foo1(Bar<'a>)
|
Foo1(Bar<'a>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,26 @@
|
|||||||
|
error[E0072]: recursive types `Foo` and `Bar` have infinite size
|
||||||
|
--> $DIR/variance-regions-unused-indirect.rs:3:1
|
||||||
|
|
|
||||||
|
LL | enum Foo<'a> {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | Foo1(Bar<'a>)
|
||||||
|
| ------- recursive without indirection
|
||||||
|
...
|
||||||
|
LL | enum Bar<'a> {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
LL | Bar1(Foo<'a>)
|
||||||
|
| ------- recursive without indirection
|
||||||
|
|
|
||||||
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
||||||
|
|
|
||||||
|
LL ~ Foo1(Box<Bar<'a>>)
|
||||||
|
LL | }
|
||||||
|
LL |
|
||||||
|
LL | enum Bar<'a> {
|
||||||
|
LL ~ Bar1(Box<Foo<'a>>)
|
||||||
|
|
|
||||||
|
|
||||||
error[E0392]: parameter `'a` is never used
|
error[E0392]: parameter `'a` is never used
|
||||||
--> $DIR/variance-regions-unused-indirect.rs:3:10
|
--> $DIR/variance-regions-unused-indirect.rs:3:10
|
||||||
|
|
|
|
||||||
@ -7,13 +30,14 @@ LL | enum Foo<'a> {
|
|||||||
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
error[E0392]: parameter `'a` is never used
|
error[E0392]: parameter `'a` is never used
|
||||||
--> $DIR/variance-regions-unused-indirect.rs:7:10
|
--> $DIR/variance-regions-unused-indirect.rs:8:10
|
||||||
|
|
|
|
||||||
LL | enum Bar<'a> {
|
LL | enum Bar<'a> {
|
||||||
| ^^ unused parameter
|
| ^^ unused parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0392`.
|
Some errors have detailed explanations: E0072, E0392.
|
||||||
|
For more information about an error, try `rustc --explain E0072`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user