Instead of having a separate enum variant for types and consts have one but have either a const
or type.
This commit is contained in:
kadmin 2022-01-07 03:58:32 +00:00
parent 0765999622
commit fb57b7518d
11 changed files with 68 additions and 37 deletions

View File

@ -1851,13 +1851,30 @@ pub struct AssocConstraint {
pub span: Span,
}
/// The kinds of an `AssocConstraint`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum Term {
Ty(P<Ty>),
Const(AnonConst),
}
impl From<P<Ty>> for Term {
fn from(v: P<Ty>) -> Self {
Term::Ty(v)
}
}
impl From<AnonConst> for Term {
fn from(v: AnonConst) -> Self {
Term::Const(v)
}
}
/// The kinds of an `AssocConstraint`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AssocConstraintKind {
/// E.g., `A = Bar` in `Foo<A = Bar>` where A is an associated type.
Equality { ty: P<Ty> },
/// E.g., `A = 3` in `Foo<N = 3>` where N is an associated const.
ConstEquality { c: AnonConst },
/// E.g., `A = Bar`, `A = 3` in `Foo<A = Bar>` where A is an associated type.
Equality { term: Term },
/// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
Bound { bounds: GenericBounds },
}

View File

@ -440,8 +440,10 @@ pub fn noop_visit_constraint<T: MutVisitor>(
vis.visit_generic_args(gen_args);
}
match kind {
AssocConstraintKind::Equality { ref mut ty } => vis.visit_ty(ty),
AssocConstraintKind::ConstEquality { ref mut c } => vis.visit_anon_const(c),
AssocConstraintKind::Equality { ref mut term } => match term {
Term::Ty(ty) => vis.visit_ty(ty),
Term::Const(c) => vis.visit_anon_const(c),
},
AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis),
}
vis.visit_span(span);

View File

@ -492,8 +492,10 @@ pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'
visitor.visit_generic_args(gen_args.span(), gen_args);
}
match constraint.kind {
AssocConstraintKind::Equality { ref ty } => visitor.visit_ty(ty),
AssocConstraintKind::ConstEquality { ref c } => visitor.visit_anon_const(c),
AssocConstraintKind::Equality { ref term } => match term {
Term::Ty(ty) => visitor.visit_ty(ty),
Term::Const(c) => visitor.visit_anon_const(c),
},
AssocConstraintKind::Bound { ref bounds } => {
walk_list!(visitor, visit_param_bound, bounds);
}

View File

@ -997,12 +997,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
let kind = match constraint.kind {
AssocConstraintKind::Equality { ref ty } => {
hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) }
}
AssocConstraintKind::ConstEquality { ref c } => {
hir::TypeBindingKind::Const { c: self.lower_anon_const(c) }
}
AssocConstraintKind::Equality { ref term } => match term {
Term::Ty(ref ty) => hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) },
Term::Const(ref c) => hir::TypeBindingKind::Const { c: self.lower_anon_const(c) },
},
AssocConstraintKind::Bound { ref bounds } => {
let mut capturable_lifetimes;
let mut parent_def_id = self.current_hir_id_owner;

View File

@ -141,7 +141,6 @@ impl<'a> AstValidator<'a> {
fn visit_assoc_constraint_from_generic_args(&mut self, constraint: &'a AssocConstraint) {
match constraint.kind {
AssocConstraintKind::Equality { .. } => {}
AssocConstraintKind::ConstEquality { .. } => {}
AssocConstraintKind::Bound { .. } => {
if self.is_assoc_ty_bound_banned {
self.err_handler().span_err(
@ -1592,7 +1591,7 @@ fn deny_equality_constraints(
ident: *ident,
gen_args,
kind: AssocConstraintKind::Equality {
ty: predicate.rhs_ty.clone(),
term: predicate.rhs_ty.clone().into(),
},
span: ident.span,
});

View File

@ -1,7 +1,6 @@
use crate::pp::Breaks::{Consistent, Inconsistent};
use crate::pp::{self, Breaks};
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, BinOpToken, CommentKind, DelimToken, Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
@ -9,6 +8,7 @@ use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser::{self, AssocOp, Fixity};
use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
use rustc_ast::{attr, Term};
use rustc_ast::{GenericArg, MacArgs, ModKind};
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
@ -957,13 +957,12 @@ impl<'a> State<'a> {
constraint.gen_args.as_ref().map(|args| self.print_generic_args(args, false));
self.space();
match &constraint.kind {
ast::AssocConstraintKind::Equality { ty } => {
ast::AssocConstraintKind::Equality { term } => {
self.word_space("=");
self.print_type(ty);
}
ast::AssocConstraintKind::ConstEquality { c } => {
self.word_space("=");
self.print_expr_anon_const(c);
match term {
Term::Ty(ty) => self.print_type(ty),
Term::Const(c) => self.print_expr_anon_const(c),
}
}
ast::AssocConstraintKind::Bound { bounds } => {
self.print_type_bounds(":", &*bounds);

View File

@ -1,7 +1,7 @@
use libloading::Library;
use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, BlockCheckMode};
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Term};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
#[cfg(parallel_compiler)]
@ -739,9 +739,11 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
},
ast::AngleBracketedArg::Constraint(c) => match c.kind {
ast::AssocConstraintKind::Bound { .. } => true,
ast::AssocConstraintKind::ConstEquality { .. } => false,
ast::AssocConstraintKind::Equality { ref ty } => {
involves_impl_trait(ty)
ast::AssocConstraintKind::Equality { ref term } => {
match term {
Term::Ty(ty) => involves_impl_trait(ty),
Term::Const(_) => false,
}
}
},
})

View File

@ -799,6 +799,7 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
/// syntax, but it roughly corresponds to the syntactic forms:
///
/// 1. `T: TraitRef<..., Item = Type>`
/// - Or `T: TraitRef<..., Item = Const>`
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
///
/// In particular, form #1 is "desugared" to the combination of a

View File

@ -505,7 +505,9 @@ impl<'a> Parser<'a> {
let span = ident.span.to(self.prev_token.span);
let ty = match arg {
Some(GenericArg::Type(ty)) => ty,
Some(GenericArg::Const(c)) => return Ok(AssocConstraintKind::ConstEquality { c }),
Some(GenericArg::Const(c)) => {
return Ok(AssocConstraintKind::Equality { term: c.into() });
}
Some(GenericArg::Lifetime(lt)) => {
self.struct_span_err(span, "associated lifetimes are not supported")
.span_label(lt.ident.span, "the lifetime is given here")
@ -540,7 +542,7 @@ impl<'a> Parser<'a> {
return Err(err);
}
};
Ok(AssocConstraintKind::Equality { ty })
Ok(AssocConstraintKind::Equality { term: ty.into() })
}
/// We do not permit arbitrary expressions as const arguments. They must be one of:

View File

@ -645,13 +645,20 @@ pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
}
}
fn eq_term(l: &Term, r: &Term) -> bool {
match (l, r) {
(Term::Ty(l), Term::Ty(r)) => eq_ty(l,r),
(Term::Const(l), Term::Const(r)) => eq_anon_const(l,r),
_ => false,
}
}
pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool {
use AssocConstraintKind::*;
eq_id(l.ident, r.ident)
&& match (&l.kind, &r.kind) {
(Equality { ty: l }, Equality { ty: r }) => eq_ty(l, r),
(Equality { term: l }, Equality { term: r }) => eq_term(l, r),
(Bound { bounds: l }, Bound { bounds: r }) => over(l, r, eq_generic_bound),
(ConstEquality { c: l }, ConstEquality { c: r }) => eq_anon_const(l, r),
_ => false,
}
}

View File

@ -1,7 +1,7 @@
use std::iter::ExactSizeIterator;
use std::ops::Deref;
use rustc_ast::ast::{self, FnRetTy, Mutability};
use rustc_ast::ast::{self, FnRetTy, Mutability, Term};
use rustc_ast::ptr;
use rustc_span::{symbol::kw, BytePos, Pos, Span};
@ -178,7 +178,7 @@ impl<'a> Rewrite for SegmentParam<'a> {
impl Rewrite for ast::AssocConstraint {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
use ast::AssocConstraintKind::{Bound, Equality, ConstEquality};
use ast::AssocConstraintKind::{Bound, Equality};
let mut result = String::with_capacity(128);
result.push_str(rewrite_ident(context, self.ident));
@ -192,8 +192,8 @@ impl Rewrite for ast::AssocConstraint {
let infix = match (&self.kind, context.config.type_punctuation_density()) {
(Bound { .. }, _) => ": ",
(ConstEquality { .. } | Equality { .. }, TypeDensity::Wide) => " = ",
(ConstEquality { .. } | Equality { .. }, TypeDensity::Compressed) => "=",
(Equality { .. }, TypeDensity::Wide) => " = ",
(Equality { .. }, TypeDensity::Compressed) => "=",
};
result.push_str(infix);
@ -209,8 +209,10 @@ impl Rewrite for ast::AssocConstraint {
impl Rewrite for ast::AssocConstraintKind {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
match self {
ast::AssocConstraintKind::Equality { ty } => ty.rewrite(context, shape),
ast::AssocConstraintKind::ConstEquality { c } => c.rewrite(context, shape),
ast::AssocConstraintKind::Equality { term } => match term {
Term::Ty(ty) => ty.rewrite(context, shape),
Term::Const(c) => c.rewrite(context,shape),
},
ast::AssocConstraintKind::Bound { bounds } => bounds.rewrite(context, shape),
}
}