Forbid !Sized
types and references
This commit is contained in:
parent
cb12b52f16
commit
42cc42b942
7 changed files with 167 additions and 39 deletions
|
@ -924,8 +924,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||
|
||||
if tcx.features().adt_const_params {
|
||||
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
|
||||
let trait_def_id =
|
||||
tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span));
|
||||
wfcx.register_bound(
|
||||
ObligationCause::new(
|
||||
hir_ty.span,
|
||||
|
@ -934,7 +932,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||
),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
trait_def_id,
|
||||
tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)),
|
||||
);
|
||||
wfcx.register_bound(
|
||||
ObligationCause::new(hir_ty.span, param.def_id, ObligationCauseCode::Misc),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
|
@ -965,7 +969,11 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||
cause,
|
||||
) {
|
||||
// Can never implement `ConstParamTy`, don't suggest anything.
|
||||
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => false,
|
||||
Err(
|
||||
ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed
|
||||
| ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(..)
|
||||
| ConstParamTyImplementationError::TypeNotSized,
|
||||
) => false,
|
||||
// May be able to implement `ConstParamTy`. Only emit the feature help
|
||||
// if the type is local, since the user may be able to fix the local type.
|
||||
Err(ConstParamTyImplementationError::InfrigingFields(..)) => {
|
||||
|
|
|
@ -103,7 +103,13 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
|
|||
Ok(()) => Ok(()),
|
||||
Err(CopyImplementationError::InfringingFields(fields)) => {
|
||||
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span))
|
||||
Err(infringing_fields_error(
|
||||
tcx,
|
||||
fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
|
||||
LangItem::Copy,
|
||||
impl_did,
|
||||
span,
|
||||
))
|
||||
}
|
||||
Err(CopyImplementationError::NotAnAdt) => {
|
||||
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
|
||||
|
@ -125,7 +131,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
|
|||
|
||||
let param_env = tcx.param_env(impl_did);
|
||||
|
||||
if let ty::ImplPolarity::Negative = header.polarity {
|
||||
if let ty::ImplPolarity::Negative | ty::ImplPolarity::Reservation = header.polarity {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -134,12 +140,32 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
|
|||
Ok(()) => Ok(()),
|
||||
Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
|
||||
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span))
|
||||
Err(infringing_fields_error(
|
||||
tcx,
|
||||
fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
|
||||
LangItem::ConstParamTy,
|
||||
impl_did,
|
||||
span,
|
||||
))
|
||||
}
|
||||
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
|
||||
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span }))
|
||||
}
|
||||
Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => {
|
||||
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(infringing_fields_error(
|
||||
tcx,
|
||||
infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)),
|
||||
LangItem::ConstParamTy,
|
||||
impl_did,
|
||||
span,
|
||||
))
|
||||
}
|
||||
Err(ConstParamTyImplementationError::TypeNotSized) => {
|
||||
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
|
||||
Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnUnsized { span }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -501,9 +527,9 @@ pub fn coerce_unsized_info<'tcx>(
|
|||
Ok(CoerceUnsizedInfo { custom_kind: kind })
|
||||
}
|
||||
|
||||
fn infringing_fields_error(
|
||||
tcx: TyCtxt<'_>,
|
||||
fields: Vec<(&ty::FieldDef, Ty<'_>, InfringingFieldsReason<'_>)>,
|
||||
fn infringing_fields_error<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
infringing_tys: impl Iterator<Item = (Span, Ty<'tcx>, InfringingFieldsReason<'tcx>)>,
|
||||
lang_item: LangItem,
|
||||
impl_did: LocalDefId,
|
||||
impl_span: Span,
|
||||
|
@ -521,13 +547,13 @@ fn infringing_fields_error(
|
|||
|
||||
let mut label_spans = Vec::new();
|
||||
|
||||
for (field, ty, reason) in fields {
|
||||
for (span, ty, reason) in infringing_tys {
|
||||
// Only report an error once per type.
|
||||
if !seen_tys.insert(ty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
label_spans.push(tcx.def_span(field.did));
|
||||
label_spans.push(span);
|
||||
|
||||
match reason {
|
||||
InfringingFieldsReason::Fulfill(fulfillment_errors) => {
|
||||
|
|
|
@ -278,6 +278,14 @@ pub struct CopyImplOnNonAdt {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_const_param_ty_impl_on_unsized)]
|
||||
pub struct ConstParamTyImplOnUnsized {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_const_param_ty_impl_on_non_adt)]
|
||||
pub struct ConstParamTyImplOnNonAdt {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue