1
Fork 0

Rollup merge of #110791 - compiler-errors:negative-bounds, r=oli-obk

Implement negative bounds for internal testing purposes

Implements partial support the `!` negative polarity on trait bounds. This is incomplete, but should allow us to at least be able to play with the feature.

Not even gonna consider them as a public-facing feature, but I'm implementing them because would've been nice to have in UI tests, for example in #110671.
This commit is contained in:
Dylan DPC 2023-05-04 00:17:23 +05:30 committed by GitHub
commit 80df4ab403
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 481 additions and 188 deletions

View file

@ -1168,12 +1168,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}
(_, TraitBoundModifier::MaybeConstMaybe) => {
self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span()});
self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "?" });
}
(_, TraitBoundModifier::MaybeConstNegative) => {
self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "!" });
}
_ => {}
}
}
// Negative trait bounds are not allowed to have associated constraints
if let GenericBound::Trait(trait_ref, TraitBoundModifier::Negative) = bound
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref()
{
for arg in &args.args {
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
self.err_handler().emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
}
}
}
visit::walk_param_bound(self, bound)
}

View file

@ -567,6 +567,7 @@ pub enum TildeConstReason {
pub struct OptionalConstExclusive {
#[primary_span]
pub span: Span,
pub modifier: &'static str,
}
#[derive(Diagnostic)]
@ -693,3 +694,17 @@ pub struct ShowSpan {
pub span: Span,
pub msg: &'static str,
}
#[derive(Diagnostic)]
#[diag(ast_passes_negative_bound_not_supported)]
pub struct NegativeBoundUnsupported {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_passes_constraint_on_negative_bound)]
pub struct ConstraintOnNegativeBound {
#[primary_span]
pub span: Span,
}

View file

@ -603,6 +603,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
gate_all!(const_closures, "const closures are experimental");
if !visitor.features.negative_bounds {
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
sess.emit_err(errors::NegativeBoundUnsupported { span });
}
}
// All uses of `gate_all!` below this point were added in #65742,
// and subsequently disabled (with the non-early gating readded).
// We emit an early future-incompatible warning for these.