Skip to content

Commit 0765999

Browse files
committed
add eq constraints on associated constants
1 parent a34c079 commit 0765999

File tree

23 files changed

+195
-113
lines changed

23 files changed

+195
-113
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ pub enum AngleBracketedArg {
224224
/// Argument for a generic parameter.
225225
Arg(GenericArg),
226226
/// Constraint for an associated item.
227-
Constraint(AssocTyConstraint),
227+
Constraint(AssocConstraint),
228228
}
229229

230230
impl AngleBracketedArg {
@@ -1843,19 +1843,21 @@ impl UintTy {
18431843
/// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
18441844
/// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
18451845
#[derive(Clone, Encodable, Decodable, Debug)]
1846-
pub struct AssocTyConstraint {
1846+
pub struct AssocConstraint {
18471847
pub id: NodeId,
18481848
pub ident: Ident,
18491849
pub gen_args: Option<GenericArgs>,
1850-
pub kind: AssocTyConstraintKind,
1850+
pub kind: AssocConstraintKind,
18511851
pub span: Span,
18521852
}
18531853

1854-
/// The kinds of an `AssocTyConstraint`.
1854+
/// The kinds of an `AssocConstraint`.
18551855
#[derive(Clone, Encodable, Decodable, Debug)]
1856-
pub enum AssocTyConstraintKind {
1857-
/// E.g., `A = Bar` in `Foo<A = Bar>`.
1856+
pub enum AssocConstraintKind {
1857+
/// E.g., `A = Bar` in `Foo<A = Bar>` where A is an associated type.
18581858
Equality { ty: P<Ty> },
1859+
/// E.g., `A = 3` in `Foo<N = 3>` where N is an associated const.
1860+
ConstEquality { c: AnonConst },
18591861
/// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
18601862
Bound { bounds: GenericBounds },
18611863
}

Diff for: compiler/rustc_ast/src/mut_visit.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ pub trait MutVisitor: Sized {
165165
noop_visit_lifetime(l, self);
166166
}
167167

168-
fn visit_ty_constraint(&mut self, t: &mut AssocTyConstraint) {
169-
noop_visit_ty_constraint(t, self);
168+
fn visit_constraint(&mut self, t: &mut AssocConstraint) {
169+
noop_visit_constraint(t, self);
170170
}
171171

172172
fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
@@ -430,8 +430,8 @@ pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[
430430
smallvec![arm]
431431
}
432432

433-
pub fn noop_visit_ty_constraint<T: MutVisitor>(
434-
AssocTyConstraint { id, ident, gen_args, kind, span }: &mut AssocTyConstraint,
433+
pub fn noop_visit_constraint<T: MutVisitor>(
434+
AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint,
435435
vis: &mut T,
436436
) {
437437
vis.visit_id(id);
@@ -440,12 +440,9 @@ pub fn noop_visit_ty_constraint<T: MutVisitor>(
440440
vis.visit_generic_args(gen_args);
441441
}
442442
match kind {
443-
AssocTyConstraintKind::Equality { ref mut ty } => {
444-
vis.visit_ty(ty);
445-
}
446-
AssocTyConstraintKind::Bound { ref mut bounds } => {
447-
visit_bounds(bounds, vis);
448-
}
443+
AssocConstraintKind::Equality { ref mut ty } => vis.visit_ty(ty),
444+
AssocConstraintKind::ConstEquality { ref mut c } => vis.visit_anon_const(c),
445+
AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis),
449446
}
450447
vis.visit_span(span);
451448
}
@@ -555,7 +552,7 @@ pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>(
555552
let AngleBracketedArgs { args, span } = data;
556553
visit_vec(args, |arg| match arg {
557554
AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
558-
AngleBracketedArg::Constraint(constraint) => vis.visit_ty_constraint(constraint),
555+
AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint),
559556
});
560557
vis.visit_span(span);
561558
}

Diff for: compiler/rustc_ast/src/visit.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ pub trait Visitor<'ast>: Sized {
190190
fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) {
191191
walk_generic_arg(self, generic_arg)
192192
}
193-
fn visit_assoc_ty_constraint(&mut self, constraint: &'ast AssocTyConstraint) {
194-
walk_assoc_ty_constraint(self, constraint)
193+
fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) {
194+
walk_assoc_constraint(self, constraint)
195195
}
196196
fn visit_attribute(&mut self, attr: &'ast Attribute) {
197197
walk_attribute(self, attr)
@@ -464,7 +464,7 @@ where
464464
for arg in &data.args {
465465
match arg {
466466
AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a),
467-
AngleBracketedArg::Constraint(c) => visitor.visit_assoc_ty_constraint(c),
467+
AngleBracketedArg::Constraint(c) => visitor.visit_assoc_constraint(c),
468468
}
469469
}
470470
}
@@ -486,19 +486,15 @@ where
486486
}
487487
}
488488

489-
pub fn walk_assoc_ty_constraint<'a, V: Visitor<'a>>(
490-
visitor: &mut V,
491-
constraint: &'a AssocTyConstraint,
492-
) {
489+
pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'a AssocConstraint) {
493490
visitor.visit_ident(constraint.ident);
494491
if let Some(ref gen_args) = constraint.gen_args {
495492
visitor.visit_generic_args(gen_args.span(), gen_args);
496493
}
497494
match constraint.kind {
498-
AssocTyConstraintKind::Equality { ref ty } => {
499-
visitor.visit_ty(ty);
500-
}
501-
AssocTyConstraintKind::Bound { ref bounds } => {
495+
AssocConstraintKind::Equality { ref ty } => visitor.visit_ty(ty),
496+
AssocConstraintKind::ConstEquality { ref c } => visitor.visit_anon_const(c),
497+
AssocConstraintKind::Bound { ref bounds } => {
502498
walk_list!(visitor, visit_param_bound, bounds);
503499
}
504500
}

Diff for: compiler/rustc_ast_lowering/src/lib.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
960960
/// returns a `hir::TypeBinding` representing `Item`.
961961
fn lower_assoc_ty_constraint(
962962
&mut self,
963-
constraint: &AssocTyConstraint,
963+
constraint: &AssocConstraint,
964964
mut itctx: ImplTraitContext<'_, 'hir>,
965965
) -> hir::TypeBinding<'hir> {
966966
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
@@ -997,10 +997,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
997997
};
998998

999999
let kind = match constraint.kind {
1000-
AssocTyConstraintKind::Equality { ref ty } => {
1000+
AssocConstraintKind::Equality { ref ty } => {
10011001
hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) }
10021002
}
1003-
AssocTyConstraintKind::Bound { ref bounds } => {
1003+
AssocConstraintKind::ConstEquality { ref c } => {
1004+
hir::TypeBindingKind::Const { c: self.lower_anon_const(c) }
1005+
}
1006+
AssocConstraintKind::Bound { ref bounds } => {
10041007
let mut capturable_lifetimes;
10051008
let mut parent_def_id = self.current_hir_id_owner;
10061009
// Piggy-back on the `impl Trait` context to figure out the correct behavior.

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,11 @@ impl<'a> AstValidator<'a> {
138138
self.outer_impl_trait = old;
139139
}
140140

141-
fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) {
141+
fn visit_assoc_constraint_from_generic_args(&mut self, constraint: &'a AssocConstraint) {
142142
match constraint.kind {
143-
AssocTyConstraintKind::Equality { .. } => {}
144-
AssocTyConstraintKind::Bound { .. } => {
143+
AssocConstraintKind::Equality { .. } => {}
144+
AssocConstraintKind::ConstEquality { .. } => {}
145+
AssocConstraintKind::Bound { .. } => {
145146
if self.is_assoc_ty_bound_banned {
146147
self.err_handler().span_err(
147148
constraint.span,
@@ -150,7 +151,7 @@ impl<'a> AstValidator<'a> {
150151
}
151152
}
152153
}
153-
self.visit_assoc_ty_constraint(constraint);
154+
self.visit_assoc_constraint(constraint);
154155
}
155156

156157
// Mirrors `visit::walk_ty`, but tracks relevant state.
@@ -1277,7 +1278,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12771278
// are allowed to contain nested `impl Trait`.
12781279
AngleBracketedArg::Constraint(constraint) => {
12791280
self.with_impl_trait(None, |this| {
1280-
this.visit_assoc_ty_constraint_from_generic_args(constraint);
1281+
this.visit_assoc_constraint_from_generic_args(constraint);
12811282
});
12821283
}
12831284
}
@@ -1586,11 +1587,11 @@ fn deny_equality_constraints(
15861587
let len = assoc_path.segments.len() - 1;
15871588
let gen_args = args.as_ref().map(|p| (**p).clone());
15881589
// Build `<Bar = RhsTy>`.
1589-
let arg = AngleBracketedArg::Constraint(AssocTyConstraint {
1590+
let arg = AngleBracketedArg::Constraint(AssocConstraint {
15901591
id: rustc_ast::node_id::DUMMY_NODE_ID,
15911592
ident: *ident,
15921593
gen_args,
1593-
kind: AssocTyConstraintKind::Equality {
1594+
kind: AssocConstraintKind::Equality {
15941595
ty: predicate.rhs_ty.clone(),
15951596
},
15961597
span: ident.span,

Diff for: compiler/rustc_ast_passes/src/feature_gate.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast as ast;
22
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
3-
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
3+
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
44
use rustc_ast::{PatKind, RangeEnd, VariantData};
55
use rustc_errors::struct_span_err;
66
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
@@ -622,16 +622,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
622622
visit::walk_fn(self, fn_kind, span)
623623
}
624624

625-
fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
626-
if let AssocTyConstraintKind::Bound { .. } = constraint.kind {
625+
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
626+
if let AssocConstraintKind::Bound { .. } = constraint.kind {
627627
gate_feature_post!(
628628
&self,
629629
associated_type_bounds,
630630
constraint.span,
631631
"associated type bounds are unstable"
632632
)
633633
}
634-
visit::walk_assoc_ty_constraint(self, constraint)
634+
visit::walk_assoc_constraint(self, constraint)
635635
}
636636

637637
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {

Diff for: compiler/rustc_ast_passes/src/node_count.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
126126
self.count += 1;
127127
walk_generic_args(self, path_span, generic_args)
128128
}
129-
fn visit_assoc_ty_constraint(&mut self, constraint: &AssocTyConstraint) {
129+
fn visit_assoc_constraint(&mut self, constraint: &AssocConstraint) {
130130
self.count += 1;
131-
walk_assoc_ty_constraint(self, constraint)
131+
walk_assoc_constraint(self, constraint)
132132
}
133133
fn visit_attribute(&mut self, _attr: &Attribute) {
134134
self.count += 1;

Diff for: compiler/rustc_ast_pretty/src/pprust/state.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -952,16 +952,20 @@ impl<'a> State<'a> {
952952
}
953953
}
954954

955-
pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
955+
pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocConstraint) {
956956
self.print_ident(constraint.ident);
957957
constraint.gen_args.as_ref().map(|args| self.print_generic_args(args, false));
958958
self.space();
959959
match &constraint.kind {
960-
ast::AssocTyConstraintKind::Equality { ty } => {
960+
ast::AssocConstraintKind::Equality { ty } => {
961961
self.word_space("=");
962962
self.print_type(ty);
963963
}
964-
ast::AssocTyConstraintKind::Bound { bounds } => {
964+
ast::AssocConstraintKind::ConstEquality { c } => {
965+
self.word_space("=");
966+
self.print_expr_anon_const(c);
967+
}
968+
ast::AssocConstraintKind::Bound { bounds } => {
965969
self.print_type_bounds(":", &*bounds);
966970
}
967971
}

Diff for: compiler/rustc_hir/src/hir.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,8 @@ pub enum TypeBindingKind<'hir> {
21362136
Constraint { bounds: &'hir [GenericBound<'hir>] },
21372137
/// E.g., `Foo<Bar = ()>`.
21382138
Equality { ty: &'hir Ty<'hir> },
2139+
/// E.g., `Foo<N = 3>`.
2140+
Const { c: AnonConst },
21392141
}
21402142

21412143
impl TypeBinding<'_> {

Diff for: compiler/rustc_hir/src/intravisit.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -827,9 +827,8 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
827827
visitor.visit_ident(type_binding.ident);
828828
visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
829829
match type_binding.kind {
830-
TypeBindingKind::Equality { ref ty } => {
831-
visitor.visit_ty(ty);
832-
}
830+
TypeBindingKind::Equality { ref ty } => visitor.visit_ty(ty),
831+
TypeBindingKind::Const { ref c } => visitor.visit_anon_const(c),
833832
TypeBindingKind::Constraint { bounds } => {
834833
walk_list!(visitor, visit_param_bound, bounds);
835834
}

Diff for: compiler/rustc_hir_pretty/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1756,6 +1756,10 @@ impl<'a> State<'a> {
17561756
self.word_space("=");
17571757
self.print_type(ty);
17581758
}
1759+
hir::TypeBindingKind::Const { ref c } => {
1760+
self.word_space("=");
1761+
self.print_anon_const(c);
1762+
}
17591763
hir::TypeBindingKind::Constraint { bounds } => {
17601764
self.print_bounds(":", bounds);
17611765
}

Diff for: compiler/rustc_interface/src/util.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -738,8 +738,9 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
738738
| ast::GenericArg::Const(_) => false,
739739
},
740740
ast::AngleBracketedArg::Constraint(c) => match c.kind {
741-
ast::AssocTyConstraintKind::Bound { .. } => true,
742-
ast::AssocTyConstraintKind::Equality { ref ty } => {
741+
ast::AssocConstraintKind::Bound { .. } => true,
742+
ast::AssocConstraintKind::ConstEquality { .. } => false,
743+
ast::AssocConstraintKind::Equality { ref ty } => {
743744
involves_impl_trait(ty)
744745
}
745746
},

Diff for: compiler/rustc_middle/src/ty/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,25 @@ pub struct ProjectionPredicate<'tcx> {
814814
pub ty: Ty<'tcx>,
815815
}
816816

817+
/// This kind of predicate has no *direct* correspondent in the
818+
/// syntax, but it roughly corresponds to the syntactic forms:
819+
///
820+
/// 1. `T: TraitRef<..., Item = Const>`
821+
/// 2. `<T as TraitRef<...>>::Item == Const` (NYI)
822+
///
823+
/// In particular, form #1 is "desugared" to the combination of a
824+
/// normal trait predicate (`T: TraitRef<...>`) and one of these
825+
/// predicates. Form #2 is a broader form in that it also permits
826+
/// equality between arbitrary types. Processing an instance of
827+
/// Form #2 eventually yields one of these `ProjectionPredicate`
828+
/// instances to normalize the LHS.
829+
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug)]
830+
#[derive(HashStable, TypeFoldable)]
831+
pub struct ConstPredicate<'tcx> {
832+
pub projection: ProjectionTy<'tcx>,
833+
pub c: &'tcx Const<'tcx>,
834+
}
835+
817836
pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
818837

819838
impl<'tcx> PolyProjectionPredicate<'tcx> {

0 commit comments

Comments
 (0)