Skip to content

Commit 2573b5c

Browse files
Rollup merge of rust-lang#161443 - khyperia:abbys-tests, r=BoxyUwU
add internal DSL for testing binders implements rust-lang/project-assumptions-on-binders#8 apologies to the inevitable swarm of people who get pinged for this... basically the only interesting diff is `compiler/rustc_hir_analysis/src/check/wfcheck.rs`, which actually implements the test. there's probably still features we want to add to this DSL (e.g. `RegionConstraint::AliasTyOutlivesViaEnv`), and there might be some bugs lurking, but this is at least a base to work off of. It's perma-unstable and for internal use only, so support and quality doesn't have to be incredibly high. For example, parser recovery and whatnot is just, bad, but whatever. r? BoxyUwU
2 parents cc05892 + 210fd61 commit 2573b5c

74 files changed

Lines changed: 1431 additions & 158 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_ast/src/ast.rs

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,29 +3733,7 @@ impl Item {
37333733
}
37343734

37353735
pub fn opt_generics(&self) -> Option<&Generics> {
3736-
match &self.kind {
3737-
ItemKind::ExternCrate(..)
3738-
| ItemKind::ConstBlock(_)
3739-
| ItemKind::Use(_)
3740-
| ItemKind::Mod(..)
3741-
| ItemKind::ForeignMod(_)
3742-
| ItemKind::GlobalAsm(_)
3743-
| ItemKind::MacCall(_)
3744-
| ItemKind::Delegation(_)
3745-
| ItemKind::DelegationMac(_)
3746-
| ItemKind::MacroDef(..) => None,
3747-
ItemKind::Static(_) => None,
3748-
ItemKind::Const(i) => Some(&i.generics),
3749-
ItemKind::Fn(i) => Some(&i.generics),
3750-
ItemKind::TyAlias(i) => Some(&i.generics),
3751-
ItemKind::TraitAlias(i) => Some(&i.generics),
3752-
3753-
ItemKind::Enum(_, generics, _)
3754-
| ItemKind::Struct(_, generics, _)
3755-
| ItemKind::Union(_, generics, _) => Some(&generics),
3756-
ItemKind::Trait(i) => Some(&i.generics),
3757-
ItemKind::Impl(i) => Some(&i.generics),
3758-
}
3736+
self.kind.generics()
37593737
}
37603738
}
37613739

@@ -4092,6 +4070,57 @@ impl Guard {
40924070
}
40934071
}
40944072

4073+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
4074+
pub struct TestBinderConstraints {
4075+
pub generics: Generics,
4076+
pub body: Box<TestBinderBody>,
4077+
}
4078+
4079+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
4080+
pub struct TestBinderBody {
4081+
pub foralls: ThinVec<TestBinderForall>,
4082+
pub exists: ThinVec<TestBinderExists>,
4083+
pub constraints: Vec<TestBinderConstraint>,
4084+
}
4085+
4086+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
4087+
pub struct TestBinderForall {
4088+
pub span: Span,
4089+
pub node_id: NodeId,
4090+
pub generics: Generics,
4091+
pub body: TestBinderBody,
4092+
pub assert_on_exit: Option<ThinVec<TestBinderConstraint>>,
4093+
}
4094+
4095+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
4096+
pub struct TestBinderExists {
4097+
pub span: Span,
4098+
pub node_id: NodeId,
4099+
pub params: ThinVec<GenericParam>,
4100+
pub body: TestBinderBody,
4101+
}
4102+
4103+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
4104+
pub enum TestBinderConstraint {
4105+
And {
4106+
items: ThinVec<TestBinderConstraint>,
4107+
},
4108+
Or {
4109+
items: ThinVec<TestBinderConstraint>,
4110+
},
4111+
Lifetime {
4112+
#[visitable(extra = LifetimeCtxt::Bound)]
4113+
lhs: Lifetime,
4114+
#[visitable(extra = LifetimeCtxt::Bound)]
4115+
rhs: Lifetime,
4116+
},
4117+
Type {
4118+
lhs: Box<Ty>,
4119+
#[visitable(extra = LifetimeCtxt::Bound)]
4120+
rhs: Lifetime,
4121+
},
4122+
}
4123+
40954124
// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
40964125
#[derive(Clone, Encodable, Decodable, Debug)]
40974126
pub enum ItemKind {
@@ -4173,6 +4202,8 @@ pub enum ItemKind {
41734202
/// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`).
41744203
/// Treated similarly to a macro call and expanded early.
41754204
DelegationMac(Box<DelegationMac>),
4205+
/// A `test_binder_constraints!()`. Perma-unstable, used only for rustc tests.
4206+
TestBinderConstraints(Box<TestBinderConstraints>),
41764207
}
41774208

41784209
impl ItemKind {
@@ -4199,17 +4230,31 @@ impl ItemKind {
41994230
| ItemKind::GlobalAsm(_)
42004231
| ItemKind::Impl(_)
42014232
| ItemKind::MacCall(_)
4202-
| ItemKind::DelegationMac(_) => None,
4233+
| ItemKind::DelegationMac(_)
4234+
| ItemKind::TestBinderConstraints(_) => None,
42034235
}
42044236
}
42054237

42064238
/// "a" or "an"
42074239
pub fn article(&self) -> &'static str {
42084240
use ItemKind::*;
42094241
match self {
4210-
Use(..) | Static(..) | Const(..) | ConstBlock(..) | Fn(..) | Mod(..)
4211-
| GlobalAsm(..) | TyAlias(..) | Struct(..) | Union(..) | Trait(..) | TraitAlias(..)
4212-
| MacroDef(..) | Delegation(..) | DelegationMac(..) => "a",
4242+
Use(..)
4243+
| Static(..)
4244+
| Const(..)
4245+
| ConstBlock(..)
4246+
| Fn(..)
4247+
| Mod(..)
4248+
| GlobalAsm(..)
4249+
| TyAlias(..)
4250+
| Struct(..)
4251+
| Union(..)
4252+
| Trait(..)
4253+
| TraitAlias(..)
4254+
| MacroDef(..)
4255+
| Delegation(..)
4256+
| DelegationMac(..)
4257+
| TestBinderConstraints(..) => "a",
42134258
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
42144259
}
42154260
}
@@ -4236,6 +4281,7 @@ impl ItemKind {
42364281
ItemKind::Impl { .. } => "implementation",
42374282
ItemKind::Delegation(..) => "delegated function",
42384283
ItemKind::DelegationMac(..) => "delegation",
4284+
ItemKind::TestBinderConstraints(..) => "test_binder_constraints!",
42394285
}
42404286
}
42414287

@@ -4249,7 +4295,8 @@ impl ItemKind {
42494295
| Self::Union(_, generics, _)
42504296
| Self::Trait(Trait { generics, .. })
42514297
| Self::TraitAlias(TraitAlias { generics, .. })
4252-
| Self::Impl(Impl { generics, .. }) => Some(generics),
4298+
| Self::Impl(Impl { generics, .. })
4299+
| Self::TestBinderConstraints(TestBinderConstraints { generics, .. }) => Some(generics),
42534300

42544301
Self::ExternCrate(..)
42554302
| Self::Use(..)

compiler/rustc_ast/src/visit.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ macro_rules! common_visitor_and_walkers {
399399
ThinVec<PathSegment>,
400400
ThinVec<PreciseCapturingArg>,
401401
ThinVec<Pat>,
402+
ThinVec<TestBinderConstraint>,
403+
ThinVec<TestBinderExists>,
404+
ThinVec<TestBinderForall>,
402405
ThinVec<Box<Ty>>,
403406
ThinVec<TyPat>,
404407
ThinVec<EiiImpl>,
@@ -605,6 +608,11 @@ macro_rules! common_visitor_and_walkers {
605608
fn visit_poly_trait_ref(PolyTraitRef);
606609
fn visit_precise_capturing_arg(PreciseCapturingArg);
607610
fn visit_qself(QSelf);
611+
fn visit_test_binder_body(TestBinderBody);
612+
fn visit_test_binder_constraint(TestBinderConstraint);
613+
fn visit_test_binder_constraints(TestBinderConstraints);
614+
fn visit_test_binder_exists(TestBinderExists);
615+
fn visit_test_binder_forall(TestBinderForall);
608616
fn visit_trait_ref(TraitRef);
609617
fn visit_ty_pat(TyPat);
610618
fn visit_ty(Ty);
@@ -870,6 +878,8 @@ macro_rules! common_visitor_and_walkers {
870878
visit_visitable!($($mut)? vis, delegation),
871879
ItemKind::DelegationMac(dm) =>
872880
visit_visitable!($($mut)? vis, dm),
881+
ItemKind::TestBinderConstraints(item) =>
882+
visit_visitable!($($mut)? vis, item),
873883
}
874884
V::Result::output()
875885
}
@@ -1133,6 +1143,10 @@ macro_rules! common_visitor_and_walkers {
11331143
pub fn walk_poly_trait_ref(PolyTraitRef);
11341144
pub fn walk_precise_capturing_arg(PreciseCapturingArg);
11351145
pub fn walk_qself(QSelf);
1146+
pub fn walk_test_binder_body(TestBinderBody);
1147+
pub fn walk_test_binder_constraint(TestBinderConstraint);
1148+
pub fn walk_test_binder_exists(TestBinderExists);
1149+
pub fn walk_test_binder_forall(TestBinderForall);
11361150
pub fn walk_trait_ref(TraitRef);
11371151
pub fn walk_ty_pat(TyPat);
11381152
pub fn walk_ty(Ty);

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
431431
}
432432
intravisit::walk_precise_capturing_arg(self, arg);
433433
}
434+
435+
fn visit_test_binder_forall(&mut self, forall: &'hir TestBinderForall<'hir>) -> Self::Result {
436+
self.insert(forall.span, forall.hir_id, Node::TestBinderForall(forall));
437+
self.with_parent(forall.hir_id, |this| intravisit::walk_test_binder_forall(this, forall))
438+
}
439+
440+
fn visit_test_binder_exists(&mut self, exists: &'hir TestBinderExists<'hir>) -> Self::Result {
441+
self.insert(exists.span, exists.hir_id, Node::TestBinderExists(exists));
442+
self.with_parent(exists.hir_id, |this| intravisit::walk_test_binder_exists(this, exists))
443+
}
434444
}

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
200200
| ItemKind::MacCall(..)
201201
| ItemKind::MacroDef(..)
202202
| ItemKind::Delegation(..)
203-
| ItemKind::DelegationMac(..) => Vec::new(),
203+
| ItemKind::DelegationMac(..)
204+
| ItemKind::TestBinderConstraints(..) => Vec::new(),
204205
}
205206
}
206207

@@ -574,6 +575,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
574575
ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
575576
panic!("macros should have been expanded by now")
576577
}
578+
ItemKind::TestBinderConstraints(TestBinderConstraints { generics, body }) => {
579+
let (generics, body) = self.lower_generics(
580+
generics,
581+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
582+
|this| this.lower_test_binder_body(body),
583+
);
584+
hir::ItemKind::TestBinderConstraints { generics, body: self.arena.alloc(body) }
585+
}
577586
}
578587
}
579588

@@ -2095,4 +2104,103 @@ impl<'hir> LoweringContext<'_, 'hir> {
20952104
});
20962105
hir::WherePredicate { hir_id, span, kind }
20972106
}
2107+
2108+
fn lower_test_binder_body(&mut self, body: &TestBinderBody) -> hir::TestBinderBody<'hir> {
2109+
let foralls = self.arena.alloc_from_iter(
2110+
body.foralls.iter().map(|forall| self.lower_test_binder_forall(forall)),
2111+
);
2112+
let exists = self.arena.alloc_from_iter(
2113+
body.exists.iter().map(|exists| self.lower_test_binder_exists(exists)),
2114+
);
2115+
let constraints = self.lower_test_binder_constraints_as_and(&body.constraints);
2116+
hir::TestBinderBody { foralls, exists, constraints }
2117+
}
2118+
2119+
fn lower_test_binder_forall(
2120+
&mut self,
2121+
forall: &TestBinderForall,
2122+
) -> hir::TestBinderForall<'hir> {
2123+
let (generics, body) = self.lower_generics(
2124+
&forall.generics,
2125+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
2126+
|this| this.lower_test_binder_body(&forall.body),
2127+
);
2128+
let assert_on_exit = forall.assert_on_exit.as_ref().map(|assert_on_exit| {
2129+
self.arena.alloc(self.lower_test_binder_constraints_as_and(assert_on_exit)) as &_
2130+
});
2131+
hir::TestBinderForall {
2132+
span: self.lower_span(forall.span),
2133+
hir_id: self.lower_node_id(forall.node_id),
2134+
generics,
2135+
body: self.arena.alloc(body),
2136+
assert_on_exit,
2137+
}
2138+
}
2139+
2140+
fn lower_test_binder_exists(
2141+
&mut self,
2142+
exists: &TestBinderExists,
2143+
) -> hir::TestBinderExists<'hir> {
2144+
let (generics, body) = self.lower_generics(
2145+
&Generics {
2146+
params: exists.params.clone(),
2147+
where_clause: Default::default(),
2148+
span: exists.span,
2149+
},
2150+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
2151+
|this| this.lower_test_binder_body(&exists.body),
2152+
);
2153+
let params = generics.params;
2154+
hir::TestBinderExists {
2155+
span: self.lower_span(exists.span),
2156+
hir_id: self.lower_node_id(exists.node_id),
2157+
params,
2158+
body: self.arena.alloc(body),
2159+
}
2160+
}
2161+
2162+
// if there are multiple constraints in a block body, automatically wrap them in an `and {}`
2163+
fn lower_test_binder_constraints_as_and(
2164+
&mut self,
2165+
constraints: &[TestBinderConstraint],
2166+
) -> hir::TestBinderConstraint<'hir> {
2167+
if constraints.len() == 1 {
2168+
self.lower_test_binder_constraint(&constraints[0])
2169+
} else {
2170+
hir::TestBinderConstraint::And {
2171+
items: self.arena.alloc_from_iter(
2172+
constraints.iter().map(|item| self.lower_test_binder_constraint(item)),
2173+
),
2174+
}
2175+
}
2176+
}
2177+
2178+
fn lower_test_binder_constraint(
2179+
&mut self,
2180+
constraint: &TestBinderConstraint,
2181+
) -> hir::TestBinderConstraint<'hir> {
2182+
match constraint {
2183+
TestBinderConstraint::And { items } => hir::TestBinderConstraint::And {
2184+
items: self.arena.alloc_from_iter(
2185+
items.iter().map(|item| self.lower_test_binder_constraint(item)),
2186+
),
2187+
},
2188+
TestBinderConstraint::Or { items } => hir::TestBinderConstraint::Or {
2189+
items: self.arena.alloc_from_iter(
2190+
items.iter().map(|item| self.lower_test_binder_constraint(item)),
2191+
),
2192+
},
2193+
TestBinderConstraint::Lifetime { lhs, rhs } => {
2194+
let lhs = self.lower_lifetime(lhs, LifetimeSource::Other, lhs.ident.into());
2195+
let rhs = self.lower_lifetime(rhs, LifetimeSource::OutlivesBound, rhs.ident.into());
2196+
hir::TestBinderConstraint::Lifetime { lhs, rhs }
2197+
}
2198+
TestBinderConstraint::Type { lhs, rhs } => {
2199+
let lhs = self
2200+
.lower_ty_alloc(lhs, ImplTraitContext::Disallowed(ImplTraitPosition::Bound));
2201+
let rhs = self.lower_lifetime(rhs, LifetimeSource::OutlivesBound, rhs.ident.into());
2202+
hir::TestBinderConstraint::Type { lhs, rhs }
2203+
}
2204+
}
2205+
}
20982206
}

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
413413
}
414414
visit::walk_assoc_item(self, i, ctxt)
415415
}
416+
417+
fn visit_test_binder_forall(&mut self, forall: &'a ast::TestBinderForall) {
418+
self.check_late_bound_lifetime_defs(&forall.generics.params);
419+
visit::walk_test_binder_forall(self, forall)
420+
}
421+
422+
fn visit_test_binder_exists(&mut self, exists: &'a ast::TestBinderExists) {
423+
self.check_late_bound_lifetime_defs(&exists.params);
424+
visit::walk_test_binder_exists(self, exists)
425+
}
416426
}
417427

418428
// -----------------------------------------------------------------------------

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ impl<'a> State<'a> {
450450
},
451451
&deleg.body,
452452
),
453+
ast::ItemKind::TestBinderConstraints(_) => {
454+
self.word("test_binder_constraints!(/* pretty-printing not supported */)")
455+
}
453456
}
454457
self.ann.post(self, AnnNode::Item(item))
455458
}

compiler/rustc_attr_ir/src/target.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ impl Target {
143143
ast::ItemKind::MacroDef(..) => Target::MacroDef,
144144
ast::ItemKind::Delegation(..) => Target::Delegation { mac: false },
145145
ast::ItemKind::DelegationMac(..) => Target::Delegation { mac: true },
146+
ast::ItemKind::TestBinderConstraints(..) => Target::MacroCall,
146147
}
147148
}
148149

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ mod offload;
4747
mod pattern_type;
4848
mod source_util;
4949
mod test;
50+
mod test_binder_constraints;
5051
mod trace_macros;
5152
mod view_type;
5253

@@ -100,6 +101,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
100101
pattern_type: pattern_type::expand,
101102
std_panic: edition_panic::expand_panic,
102103
stringify: source_util::expand_stringify,
104+
test_binder_constraints: test_binder_constraints::expand,
103105
trace_macros: trace_macros::expand_trace_macros,
104106
unreachable: edition_panic::expand_unreachable,
105107
view_type: view_type::expand,

0 commit comments

Comments
 (0)