1
Fork 0

Make traits with GATs not object safe

This commit is contained in:
Jack Huey 2021-04-27 14:34:23 -04:00
parent 1919b3f227
commit 857cb4de20
15 changed files with 179 additions and 25 deletions

View file

@ -670,6 +670,9 @@ pub enum ObjectSafetyViolation {
/// Associated const.
AssocConst(Symbol, Span),
/// GAT
GAT(Symbol, Span),
}
impl ObjectSafetyViolation {
@ -715,6 +718,9 @@ impl ObjectSafetyViolation {
format!("it contains associated `const` `{}`", name).into()
}
ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(),
ObjectSafetyViolation::GAT(name, _) => {
format!("it contains the generic associated type `{}`", name).into()
}
}
}
@ -773,6 +779,7 @@ impl ObjectSafetyViolation {
);
}
ObjectSafetyViolation::AssocConst(name, _)
| ObjectSafetyViolation::GAT(name, _)
| ObjectSafetyViolation::Method(name, ..) => {
err.help(&format!("consider moving `{}` to another trait", name));
}
@ -786,6 +793,7 @@ impl ObjectSafetyViolation {
ObjectSafetyViolation::SupertraitSelf(spans)
| ObjectSafetyViolation::SizedSelf(spans) => spans.clone(),
ObjectSafetyViolation::AssocConst(_, span)
| ObjectSafetyViolation::GAT(_, span)
| ObjectSafetyViolation::Method(_, _, span)
if *span != DUMMY_SP =>
{

View file

@ -132,6 +132,14 @@ fn object_safety_violations_for_trait(
.map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)),
);
violations.extend(
tcx.associated_items(trait_def_id)
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
.map(|item| ObjectSafetyViolation::GAT(item.ident.name, item.ident.span)),
);
debug!(
"object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
trait_def_id, violations

View file

@ -462,12 +462,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
for assoc_type in assoc_types {
if !tcx.generics_of(assoc_type).params.is_empty() {
// FIXME(generic_associated_types) generate placeholders to
// extend the trait substs.
tcx.sess.span_fatal(
tcx.sess.delay_span_bug(
obligation.cause.span,
"generic associated types in trait objects are not supported yet",
"GATs in trait object shouldn't have been considered",
);
return Err(SelectionError::Unimplemented);
}
// This maybe belongs in wf, but that can't (doesn't) handle
// higher-ranked things.