1
Fork 0
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, 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`. /// The kinds of an `AssocConstraint`.
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum AssocConstraintKind { pub enum AssocConstraintKind {
/// E.g., `A = Bar` in `Foo<A = Bar>` where A is an associated type. /// E.g., `A = Bar`, `A = 3` in `Foo<A = Bar>` where A is an associated type.
Equality { ty: P<Ty> }, Equality { term: Term },
/// E.g., `A = 3` in `Foo<N = 3>` where N is an associated const.
ConstEquality { c: AnonConst },
/// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`. /// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
Bound { bounds: GenericBounds }, Bound { bounds: GenericBounds },
} }

View file

@ -440,8 +440,10 @@ pub fn noop_visit_constraint<T: MutVisitor>(
vis.visit_generic_args(gen_args); vis.visit_generic_args(gen_args);
} }
match kind { match kind {
AssocConstraintKind::Equality { ref mut ty } => vis.visit_ty(ty), AssocConstraintKind::Equality { ref mut term } => match term {
AssocConstraintKind::ConstEquality { ref mut c } => vis.visit_anon_const(c), Term::Ty(ty) => vis.visit_ty(ty),
Term::Const(c) => vis.visit_anon_const(c),
},
AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis), AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis),
} }
vis.visit_span(span); 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); visitor.visit_generic_args(gen_args.span(), gen_args);
} }
match constraint.kind { match constraint.kind {
AssocConstraintKind::Equality { ref ty } => visitor.visit_ty(ty), AssocConstraintKind::Equality { ref term } => match term {
AssocConstraintKind::ConstEquality { ref c } => visitor.visit_anon_const(c), Term::Ty(ty) => visitor.visit_ty(ty),
Term::Const(c) => visitor.visit_anon_const(c),
},
AssocConstraintKind::Bound { ref bounds } => { AssocConstraintKind::Bound { ref bounds } => {
walk_list!(visitor, visit_param_bound, 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 { let kind = match constraint.kind {
AssocConstraintKind::Equality { ref ty } => { AssocConstraintKind::Equality { ref term } => match term {
hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) } 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::ConstEquality { ref c } => { },
hir::TypeBindingKind::Const { c: self.lower_anon_const(c) }
}
AssocConstraintKind::Bound { ref bounds } => { AssocConstraintKind::Bound { ref bounds } => {
let mut capturable_lifetimes; let mut capturable_lifetimes;
let mut parent_def_id = self.current_hir_id_owner; 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) { fn visit_assoc_constraint_from_generic_args(&mut self, constraint: &'a AssocConstraint) {
match constraint.kind { match constraint.kind {
AssocConstraintKind::Equality { .. } => {} AssocConstraintKind::Equality { .. } => {}
AssocConstraintKind::ConstEquality { .. } => {}
AssocConstraintKind::Bound { .. } => { AssocConstraintKind::Bound { .. } => {
if self.is_assoc_ty_bound_banned { if self.is_assoc_ty_bound_banned {
self.err_handler().span_err( self.err_handler().span_err(
@ -1592,7 +1591,7 @@ fn deny_equality_constraints(
ident: *ident, ident: *ident,
gen_args, gen_args,
kind: AssocConstraintKind::Equality { kind: AssocConstraintKind::Equality {
ty: predicate.rhs_ty.clone(), term: predicate.rhs_ty.clone().into(),
}, },
span: ident.span, span: ident.span,
}); });

View file

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

View file

@ -1,7 +1,7 @@
use libloading::Library; use libloading::Library;
use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *}; use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *};
use rustc_ast::ptr::P; 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_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
#[cfg(parallel_compiler)] #[cfg(parallel_compiler)]
@ -739,9 +739,11 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
}, },
ast::AngleBracketedArg::Constraint(c) => match c.kind { ast::AngleBracketedArg::Constraint(c) => match c.kind {
ast::AssocConstraintKind::Bound { .. } => true, ast::AssocConstraintKind::Bound { .. } => true,
ast::AssocConstraintKind::ConstEquality { .. } => false, ast::AssocConstraintKind::Equality { ref term } => {
ast::AssocConstraintKind::Equality { ref ty } => { match term {
involves_impl_trait(ty) 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: /// syntax, but it roughly corresponds to the syntactic forms:
/// ///
/// 1. `T: TraitRef<..., Item = Type>` /// 1. `T: TraitRef<..., Item = Type>`
/// - Or `T: TraitRef<..., Item = Const>`
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI) /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
/// ///
/// In particular, form #1 is "desugared" to the combination of a /// 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 span = ident.span.to(self.prev_token.span);
let ty = match arg { let ty = match arg {
Some(GenericArg::Type(ty)) => ty, 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)) => { Some(GenericArg::Lifetime(lt)) => {
self.struct_span_err(span, "associated lifetimes are not supported") self.struct_span_err(span, "associated lifetimes are not supported")
.span_label(lt.ident.span, "the lifetime is given here") .span_label(lt.ident.span, "the lifetime is given here")
@ -540,7 +542,7 @@ impl<'a> Parser<'a> {
return Err(err); 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: /// 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 { pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool {
use AssocConstraintKind::*; use AssocConstraintKind::*;
eq_id(l.ident, r.ident) eq_id(l.ident, r.ident)
&& match (&l.kind, &r.kind) { && 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), (Bound { bounds: l }, Bound { bounds: r }) => over(l, r, eq_generic_bound),
(ConstEquality { c: l }, ConstEquality { c: r }) => eq_anon_const(l, r),
_ => false, _ => false,
} }
} }

View file

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