mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-06 08:36:52 -04:00
Rollup merge of #155675 - zedddie:disallow-non_exhaustive-adt-const-params, r=BoxyUwU
Disallow non_exhaustive structs and enums with non_exhaustive variants from implementing `ConstParamTy` tracking issue rust-lang/rust#154042 r? BoxyUwU
This commit is contained in:
@@ -911,6 +911,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
|
||||
// Can never implement `ConstParamTy`, don't suggest anything.
|
||||
Err(
|
||||
ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed
|
||||
| ConstParamTyImplementationError::NonExhaustive(..)
|
||||
| ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(..),
|
||||
) => None,
|
||||
Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => {
|
||||
|
||||
@@ -221,6 +221,12 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
|
||||
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span }))
|
||||
}
|
||||
Err(ConstParamTyImplementationError::NonExhaustive(attr_span)) => {
|
||||
let defn_span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(tcx
|
||||
.dcx()
|
||||
.emit_err(errors::ConstParamTyImplOnNonExhaustive { defn_span, attr_span }))
|
||||
}
|
||||
Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => {
|
||||
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(infringing_fields_error(
|
||||
|
||||
@@ -317,6 +317,16 @@ pub(crate) struct ConstParamTyImplOnNonAdt {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the trait `ConstParamTy` may not be implemented for this type")]
|
||||
pub(crate) struct ConstParamTyImplOnNonExhaustive {
|
||||
#[primary_span]
|
||||
#[label("non exhaustive const params are forbidden")]
|
||||
pub defn_span: Span,
|
||||
#[label("caused by this attribute")]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the trait `ConstParamTy` may not be implemented for this struct")]
|
||||
pub(crate) struct ConstParamTyFieldVisMismatch {
|
||||
|
||||
@@ -4,8 +4,9 @@ use hir::LangItem;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized};
|
||||
use rustc_span::sym;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
use crate::regions::InferCtxtRegionExt;
|
||||
use crate::traits::{self, FulfillmentError, Obligation, ObligationCause};
|
||||
@@ -22,6 +23,7 @@ pub enum ConstParamTyImplementationError<'tcx> {
|
||||
InvalidInnerTyOfBuiltinTy(Vec<(Ty<'tcx>, InfringingFieldsReason<'tcx>)>),
|
||||
InfrigingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>),
|
||||
NotAnAdtOrBuiltinAllowed,
|
||||
NonExhaustive(Span),
|
||||
}
|
||||
|
||||
pub enum InfringingFieldsReason<'tcx> {
|
||||
@@ -124,6 +126,19 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
||||
ty::Tuple(inner_tys) => inner_tys.into_iter().collect(),
|
||||
|
||||
ty::Adt(adt, args) if adt.is_enum() || adt.is_struct() => {
|
||||
if !tcx.features().adt_const_params() {
|
||||
for variant in adt.variants() {
|
||||
if variant.is_field_list_non_exhaustive() {
|
||||
let attr_span = match hir::find_attr!(tcx, variant.def_id, hir::attrs::AttributeKind::NonExhaustive(span) => *span)
|
||||
{
|
||||
Some(sp) => sp,
|
||||
None => bug!("non_exhaustive variant missing NonExhaustive attribute"),
|
||||
};
|
||||
return Err(ConstParamTyImplementationError::NonExhaustive(attr_span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
all_fields_implement_trait(
|
||||
tcx,
|
||||
param_env,
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
error: the trait `ConstParamTy` may not be implemented for this type
|
||||
--> $DIR/forbid-non_exhaustive-const-param-ty.rs:13:12
|
||||
|
|
||||
LL | #[non_exhaustive]
|
||||
| ----------------- caused by this attribute
|
||||
LL | #[derive(PartialEq, Eq, ConstParamTy)]
|
||||
| ------------ in this derive macro expansion
|
||||
LL | pub struct Miow;
|
||||
| ^^^^ non exhaustive const params are forbidden
|
||||
|
||||
error: the trait `ConstParamTy` may not be implemented for this type
|
||||
--> $DIR/forbid-non_exhaustive-const-param-ty.rs:17:10
|
||||
|
|
||||
LL | #[derive(PartialEq, Eq, ConstParamTy)]
|
||||
| ------------ in this derive macro expansion
|
||||
LL | pub enum Enumiow {
|
||||
| ^^^^^^^ non exhaustive const params are forbidden
|
||||
LL |
|
||||
LL | #[non_exhaustive] NonExhaustiveThingie,
|
||||
| ----------------- caused by this attribute
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//! Ensure that non exhaustive structs and enums with non exhaustive variants
|
||||
//! aren't allowed to implement ConstParamTy under min_adt_const_params feature
|
||||
//@ revisions: full min
|
||||
//@[full] check-pass
|
||||
#![cfg_attr(min, feature(min_adt_const_params))]
|
||||
#![cfg_attr(full, feature(adt_const_params))]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::marker::ConstParamTy;
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(PartialEq, Eq, ConstParamTy)]
|
||||
pub struct Miow;
|
||||
//[min]~^ ERROR: the trait `ConstParamTy` may not be implemented for this type
|
||||
|
||||
#[derive(PartialEq, Eq, ConstParamTy)]
|
||||
pub enum Enumiow {
|
||||
//[min]~^ ERROR: the trait `ConstParamTy` may not be implemented for this type
|
||||
#[non_exhaustive] NonExhaustiveThingie,
|
||||
ExhaustiveThingie,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(PartialEq, Eq, ConstParamTy)]
|
||||
pub enum EnumiowButFine {
|
||||
ExhaustiveThingie,
|
||||
AlsoExhaustiveThingie,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user