add eq constraints on associated constants

This commit is contained in:
kadmin 2021-07-30 08:56:45 +00:00
parent a34c079752
commit 0765999622
23 changed files with 195 additions and 113 deletions

View file

@ -4,8 +4,8 @@ use crate::maybe_whole;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token};
use rustc_ast::{
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocTyConstraint,
AssocTyConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint,
AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
Path, PathSegment, QSelf,
};
use rustc_errors::{pluralize, Applicability, PResult};
@ -469,12 +469,9 @@ impl<'a> Parser<'a> {
// Parse associated type constraint bound.
let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
AssocTyConstraintKind::Bound { bounds }
AssocConstraintKind::Bound { bounds }
} else if self.eat(&token::Eq) {
// Parse associated type equality constraint
let ty = self.parse_assoc_equality_term(ident, self.prev_token.span)?;
AssocTyConstraintKind::Equality { ty }
self.parse_assoc_equality_term(ident, self.prev_token.span)?
} else {
unreachable!();
};
@ -482,11 +479,11 @@ impl<'a> Parser<'a> {
let span = lo.to(self.prev_token.span);
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
if let AssocTyConstraintKind::Bound { .. } = kind {
if let AssocConstraintKind::Bound { .. } = kind {
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
}
let constraint =
AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
Ok(Some(AngleBracketedArg::Constraint(constraint)))
} else {
Ok(Some(AngleBracketedArg::Arg(arg)))
@ -499,22 +496,22 @@ impl<'a> Parser<'a> {
/// Parse the term to the right of an associated item equality constraint.
/// That is, parse `<term>` in `Item = <term>`.
/// Right now, this only admits types in `<term>`.
fn parse_assoc_equality_term(&mut self, ident: Ident, eq: Span) -> PResult<'a, P<ast::Ty>> {
fn parse_assoc_equality_term(
&mut self,
ident: Ident,
eq: Span,
) -> PResult<'a, AssocConstraintKind> {
let arg = self.parse_generic_arg(None)?;
let span = ident.span.to(self.prev_token.span);
match arg {
Some(GenericArg::Type(ty)) => return Ok(ty),
Some(GenericArg::Const(expr)) => {
self.struct_span_err(span, "cannot constrain an associated constant to a value")
.span_label(ident.span, "this associated constant...")
.span_label(expr.value.span, "...cannot be constrained to this value")
.emit();
}
let ty = match arg {
Some(GenericArg::Type(ty)) => ty,
Some(GenericArg::Const(c)) => return Ok(AssocConstraintKind::ConstEquality { c }),
Some(GenericArg::Lifetime(lt)) => {
self.struct_span_err(span, "associated lifetimes are not supported")
.span_label(lt.ident.span, "the lifetime is given here")
.help("if you meant to specify a trait object, write `dyn Trait + 'lifetime`")
.emit();
self.mk_ty(span, ast::TyKind::Err)
}
None => {
let after_eq = eq.shrink_to_hi();
@ -542,8 +539,8 @@ impl<'a> Parser<'a> {
};
return Err(err);
}
}
Ok(self.mk_ty(span, ast::TyKind::Err))
};
Ok(AssocConstraintKind::Equality { ty })
}
/// We do not permit arbitrary expressions as const arguments. They must be one of: