Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f8df298

Browse files
committedMar 25, 2025
Allow defining opaques in statics and consts
1 parent 2bf0c2d commit f8df298

File tree

17 files changed

+315
-163
lines changed

17 files changed

+315
-163
lines changed
 

‎compiler/rustc_ast/src/ast.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3535,6 +3535,7 @@ pub struct StaticItem {
35353535
pub safety: Safety,
35363536
pub mutability: Mutability,
35373537
pub expr: Option<P<Expr>>,
3538+
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
35383539
}
35393540

35403541
#[derive(Clone, Encodable, Decodable, Debug)]
@@ -3543,6 +3544,7 @@ pub struct ConstItem {
35433544
pub generics: Generics,
35443545
pub ty: P<Ty>,
35453546
pub expr: Option<P<Expr>>,
3547+
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
35463548
}
35473549

35483550
// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.

‎compiler/rustc_ast/src/mut_visit.rs

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -987,10 +987,7 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
987987
}
988988
vis.visit_span(span);
989989

990-
for (id, path) in define_opaque.iter_mut().flatten() {
991-
vis.visit_id(id);
992-
vis.visit_path(path)
993-
}
990+
walk_define_opaques(vis, define_opaque);
994991
}
995992
FnKind::Closure(binder, coroutine_kind, decl, body) => {
996993
vis.visit_closure_binder(binder);
@@ -1258,12 +1255,19 @@ impl WalkItemKind for ItemKind {
12581255
match self {
12591256
ItemKind::ExternCrate(_orig_name) => {}
12601257
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
1261-
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
1258+
ItemKind::Static(box StaticItem {
1259+
ty,
1260+
safety: _,
1261+
mutability: _,
1262+
expr,
1263+
define_opaque,
1264+
}) => {
12621265
vis.visit_ty(ty);
12631266
visit_opt(expr, |expr| vis.visit_expr(expr));
1267+
walk_define_opaques(vis, define_opaque);
12641268
}
12651269
ItemKind::Const(item) => {
1266-
visit_const_item(item, vis);
1270+
walk_const_item(vis, item);
12671271
}
12681272
ItemKind::Fn(func) => {
12691273
vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id);
@@ -1382,7 +1386,7 @@ impl WalkItemKind for AssocItemKind {
13821386
) {
13831387
match self {
13841388
AssocItemKind::Const(item) => {
1385-
visit_const_item(item, visitor);
1389+
walk_const_item(visitor, item);
13861390
}
13871391
AssocItemKind::Fn(func) => {
13881392
visitor.visit_fn(
@@ -1442,14 +1446,13 @@ impl WalkItemKind for AssocItemKind {
14421446
}
14431447
}
14441448

1445-
fn visit_const_item<T: MutVisitor>(
1446-
ConstItem { defaultness, generics, ty, expr }: &mut ConstItem,
1447-
visitor: &mut T,
1448-
) {
1449-
visit_defaultness(visitor, defaultness);
1450-
visitor.visit_generics(generics);
1451-
visitor.visit_ty(ty);
1452-
visit_opt(expr, |expr| visitor.visit_expr(expr));
1449+
fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
1450+
let ConstItem { defaultness, generics, ty, expr, define_opaque } = item;
1451+
visit_defaultness(vis, defaultness);
1452+
vis.visit_generics(generics);
1453+
vis.visit_ty(ty);
1454+
visit_opt(expr, |expr| vis.visit_expr(expr));
1455+
walk_define_opaques(vis, define_opaque);
14531456
}
14541457

14551458
fn walk_fn_header<T: MutVisitor>(vis: &mut T, header: &mut FnHeader) {
@@ -1526,9 +1529,16 @@ impl WalkItemKind for ForeignItemKind {
15261529
visitor: &mut impl MutVisitor,
15271530
) {
15281531
match self {
1529-
ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
1532+
ForeignItemKind::Static(box StaticItem {
1533+
ty,
1534+
mutability: _,
1535+
expr,
1536+
safety: _,
1537+
define_opaque,
1538+
}) => {
15301539
visitor.visit_ty(ty);
15311540
visit_opt(expr, |expr| visitor.visit_expr(expr));
1541+
walk_define_opaques(visitor, define_opaque);
15321542
}
15331543
ForeignItemKind::Fn(func) => {
15341544
visitor.visit_fn(
@@ -1929,6 +1939,18 @@ fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
19291939
}
19301940
}
19311941

1942+
fn walk_define_opaques<T: MutVisitor>(
1943+
vis: &mut T,
1944+
define_opaque: &mut Option<ThinVec<(NodeId, Path)>>,
1945+
) {
1946+
if let Some(define_opaque) = define_opaque {
1947+
for (id, path) in define_opaque {
1948+
vis.visit_id(id);
1949+
vis.visit_path(path)
1950+
}
1951+
}
1952+
}
1953+
19321954
/// Some value for the AST node that is valid but possibly meaningless. Similar
19331955
/// to `Default` but not intended for wide use. The value will never be used
19341956
/// meaningfully, it exists just to support unwinding in `visit_clobber` in the

‎compiler/rustc_ast/src/visit.rs

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
pub use rustc_ast_ir::visit::VisitorResult;
1717
pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
1818
use rustc_span::{Ident, Span};
19+
use thin_vec::ThinVec;
1920

2021
use crate::ast::*;
2122
use crate::ptr::P;
@@ -371,14 +372,28 @@ impl WalkItemKind for ItemKind {
371372
match self {
372373
ItemKind::ExternCrate(_rename) => {}
373374
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
374-
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
375+
ItemKind::Static(box StaticItem {
376+
ty,
377+
safety: _,
378+
mutability: _,
379+
expr,
380+
define_opaque,
381+
}) => {
375382
try_visit!(visitor.visit_ty(ty));
376383
visit_opt!(visitor, visit_expr, expr);
384+
try_visit!(walk_define_opaques(visitor, define_opaque));
377385
}
378-
ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
386+
ItemKind::Const(box ConstItem {
387+
defaultness: _,
388+
generics,
389+
ty,
390+
expr,
391+
define_opaque,
392+
}) => {
379393
try_visit!(visitor.visit_generics(generics));
380394
try_visit!(visitor.visit_ty(ty));
381395
visit_opt!(visitor, visit_expr, expr);
396+
try_visit!(walk_define_opaques(visitor, define_opaque));
382397
}
383398
ItemKind::Fn(func) => {
384399
let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func);
@@ -729,9 +744,16 @@ impl WalkItemKind for ForeignItemKind {
729744
visitor: &mut V,
730745
) -> V::Result {
731746
match self {
732-
ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
747+
ForeignItemKind::Static(box StaticItem {
748+
ty,
749+
mutability: _,
750+
expr,
751+
safety: _,
752+
define_opaque,
753+
}) => {
733754
try_visit!(visitor.visit_ty(ty));
734755
visit_opt!(visitor, visit_expr, expr);
756+
try_visit!(walk_define_opaques(visitor, define_opaque));
735757
}
736758
ForeignItemKind::Fn(func) => {
737759
let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func);
@@ -907,9 +929,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
907929
try_visit!(visitor.visit_fn_decl(decl));
908930
visit_opt!(visitor, visit_contract, contract);
909931
visit_opt!(visitor, visit_block, body);
910-
for (id, path) in define_opaque.iter().flatten() {
911-
try_visit!(visitor.visit_path(path, *id))
912-
}
932+
try_visit!(walk_define_opaques(visitor, define_opaque));
913933
}
914934
FnKind::Closure(binder, coroutine_kind, decl, body) => {
915935
try_visit!(visitor.visit_closure_binder(binder));
@@ -933,10 +953,17 @@ impl WalkItemKind for AssocItemKind {
933953
visitor: &mut V,
934954
) -> V::Result {
935955
match self {
936-
AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
956+
AssocItemKind::Const(box ConstItem {
957+
defaultness: _,
958+
generics,
959+
ty,
960+
expr,
961+
define_opaque,
962+
}) => {
937963
try_visit!(visitor.visit_generics(generics));
938964
try_visit!(visitor.visit_ty(ty));
939965
visit_opt!(visitor, visit_expr, expr);
966+
try_visit!(walk_define_opaques(visitor, define_opaque));
940967
}
941968
AssocItemKind::Fn(func) => {
942969
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func);
@@ -1337,3 +1364,15 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
13371364
}
13381365
V::Result::output()
13391366
}
1367+
1368+
fn walk_define_opaques<'a, V: Visitor<'a>>(
1369+
visitor: &mut V,
1370+
define_opaque: &'a Option<ThinVec<(NodeId, Path)>>,
1371+
) -> V::Result {
1372+
if let Some(define_opaque) = define_opaque {
1373+
for (id, path) in define_opaque {
1374+
try_visit!(visitor.visit_path(path, *id));
1375+
}
1376+
}
1377+
V::Result::output()
1378+
}

‎compiler/rustc_ast_lowering/src/item.rs

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
188188

189189
self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
190190
}
191-
ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
191+
ItemKind::Static(box ast::StaticItem {
192+
ty: t,
193+
safety: _,
194+
mutability: m,
195+
expr: e,
196+
define_opaque,
197+
}) => {
192198
debug_assert_ne!(ident.name, kw::Empty);
193199
let ident = self.lower_ident(ident);
194200
let (ty, body_id) =
195201
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
202+
self.lower_define_opaque(hir_id, define_opaque);
196203
hir::ItemKind::Static(ident, ty, *m, body_id)
197204
}
198-
ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
205+
ItemKind::Const(box ast::ConstItem { generics, ty, expr, define_opaque, .. }) => {
199206
debug_assert_ne!(ident.name, kw::Empty);
200207
let ident = self.lower_ident(ident);
201208
let (generics, (ty, body_id)) = self.lower_generics(
@@ -206,6 +213,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
206213
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
207214
},
208215
);
216+
self.lower_define_opaque(hir_id, &define_opaque);
209217
hir::ItemKind::Const(ident, ty, generics, body_id)
210218
}
211219
ItemKind::Fn(box Fn {
@@ -243,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
243251
header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
244252
span: this.lower_span(*fn_sig_span),
245253
};
246-
this.lower_define_opaque(hir_id, &define_opaque);
254+
this.lower_define_opaque(hir_id, define_opaque);
247255
let ident = this.lower_ident(ident);
248256
hir::ItemKind::Fn {
249257
ident,
@@ -662,7 +670,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
662670
owner_id,
663671
ident: self.lower_ident(i.ident),
664672
kind: match &i.kind {
665-
ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
673+
ForeignItemKind::Fn(box Fn { sig, generics, define_opaque, .. }) => {
666674
let fdec = &sig.decl;
667675
let itctx = ImplTraitContext::Universal;
668676
let (generics, (decl, fn_args)) =
@@ -683,17 +691,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
683691
// Unmarked safety in unsafe block defaults to unsafe.
684692
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
685693

694+
if define_opaque.is_some() {
695+
self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
696+
}
697+
686698
hir::ForeignItemKind::Fn(
687699
hir::FnSig { header, decl, span: self.lower_span(sig.span) },
688700
fn_args,
689701
generics,
690702
)
691703
}
692-
ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => {
704+
ForeignItemKind::Static(box StaticItem {
705+
ty,
706+
mutability,
707+
expr: _,
708+
safety,
709+
define_opaque,
710+
}) => {
693711
let ty = self
694712
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
695713
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
696714

715+
if define_opaque.is_some() {
716+
self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
717+
}
718+
697719
hir::ForeignItemKind::Static(ty, *mutability, safety)
698720
}
699721
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@@ -801,7 +823,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
801823
let trait_item_def_id = hir_id.expect_owner();
802824

803825
let (generics, kind, has_default) = match &i.kind {
804-
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => {
826+
AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => {
805827
let (generics, kind) = self.lower_generics(
806828
generics,
807829
i.id,
@@ -814,6 +836,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
814836
hir::TraitItemKind::Const(ty, body)
815837
},
816838
);
839+
840+
if define_opaque.is_some() {
841+
if expr.is_some() {
842+
self.lower_define_opaque(hir_id, &define_opaque);
843+
} else {
844+
self.dcx().span_err(
845+
i.span,
846+
"only trait consts with default bodies can define opaque types",
847+
);
848+
}
849+
}
850+
817851
(generics, kind, expr.is_some())
818852
}
819853
AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => {
@@ -951,18 +985,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
951985
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
952986

953987
let (generics, kind) = match &i.kind {
954-
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
955-
generics,
956-
i.id,
957-
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
958-
|this| {
959-
let ty =
960-
this.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
961-
let body = this.lower_const_body(i.span, expr.as_deref());
962-
963-
hir::ImplItemKind::Const(ty, body)
964-
},
965-
),
988+
AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => self
989+
.lower_generics(
990+
generics,
991+
i.id,
992+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
993+
|this| {
994+
let ty = this
995+
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
996+
let body = this.lower_const_body(i.span, expr.as_deref());
997+
this.lower_define_opaque(hir_id, &define_opaque);
998+
999+
hir::ImplItemKind::Const(ty, body)
1000+
},
1001+
),
9661002
AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => {
9671003
let body_id = self.lower_maybe_coroutine_body(
9681004
sig.span,

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

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,23 @@ impl<'a> State<'a> {
3737
ast::ForeignItemKind::Fn(func) => {
3838
self.print_fn_full(ident, vis, attrs, &*func);
3939
}
40-
ast::ForeignItemKind::Static(box ast::StaticItem { ty, mutability, expr, safety }) => {
41-
self.print_item_const(
42-
ident,
43-
Some(*mutability),
44-
&ast::Generics::default(),
45-
ty,
46-
expr.as_deref(),
47-
vis,
48-
*safety,
49-
ast::Defaultness::Final,
50-
)
51-
}
40+
ast::ForeignItemKind::Static(box ast::StaticItem {
41+
ty,
42+
mutability,
43+
expr,
44+
safety,
45+
define_opaque,
46+
}) => self.print_item_const(
47+
ident,
48+
Some(*mutability),
49+
&ast::Generics::default(),
50+
ty,
51+
expr.as_deref(),
52+
vis,
53+
*safety,
54+
ast::Defaultness::Final,
55+
define_opaque.as_deref(),
56+
),
5257
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
5358
defaultness,
5459
generics,
@@ -86,7 +91,9 @@ impl<'a> State<'a> {
8691
vis: &ast::Visibility,
8792
safety: ast::Safety,
8893
defaultness: ast::Defaultness,
94+
define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
8995
) {
96+
self.print_define_opaques(define_opaque);
9097
self.head("");
9198
self.print_visibility(vis);
9299
self.print_safety(safety);
@@ -174,7 +181,13 @@ impl<'a> State<'a> {
174181
self.print_use_tree(tree);
175182
self.word(";");
176183
}
177-
ast::ItemKind::Static(box StaticItem { ty, safety, mutability: mutbl, expr: body }) => {
184+
ast::ItemKind::Static(box StaticItem {
185+
ty,
186+
safety,
187+
mutability: mutbl,
188+
expr: body,
189+
define_opaque,
190+
}) => {
178191
self.print_safety(*safety);
179192
self.print_item_const(
180193
item.ident,
@@ -185,9 +198,16 @@ impl<'a> State<'a> {
185198
&item.vis,
186199
ast::Safety::Default,
187200
ast::Defaultness::Final,
201+
define_opaque.as_deref(),
188202
);
189203
}
190-
ast::ItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
204+
ast::ItemKind::Const(box ast::ConstItem {
205+
defaultness,
206+
generics,
207+
ty,
208+
expr,
209+
define_opaque,
210+
}) => {
191211
self.print_item_const(
192212
item.ident,
193213
None,
@@ -197,6 +217,7 @@ impl<'a> State<'a> {
197217
&item.vis,
198218
ast::Safety::Default,
199219
*defaultness,
220+
define_opaque.as_deref(),
200221
);
201222
}
202223
ast::ItemKind::Fn(func) => {
@@ -537,7 +558,13 @@ impl<'a> State<'a> {
537558
ast::AssocItemKind::Fn(func) => {
538559
self.print_fn_full(ident, vis, attrs, &*func);
539560
}
540-
ast::AssocItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
561+
ast::AssocItemKind::Const(box ast::ConstItem {
562+
defaultness,
563+
generics,
564+
ty,
565+
expr,
566+
define_opaque,
567+
}) => {
541568
self.print_item_const(
542569
ident,
543570
None,
@@ -547,6 +574,7 @@ impl<'a> State<'a> {
547574
vis,
548575
ast::Safety::Default,
549576
*defaultness,
577+
define_opaque.as_deref(),
550578
);
551579
}
552580
ast::AssocItemKind::Type(box ast::TyAlias {
@@ -652,7 +680,7 @@ impl<'a> State<'a> {
652680
) {
653681
let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func;
654682

655-
self.print_define_opaques(define_opaque);
683+
self.print_define_opaques(define_opaque.as_deref());
656684

657685
if body.is_some() {
658686
self.head("");
@@ -672,10 +700,7 @@ impl<'a> State<'a> {
672700
}
673701
}
674702

675-
fn print_define_opaques(
676-
&mut self,
677-
define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
678-
) {
703+
fn print_define_opaques(&mut self, define_opaque: Option<&[(ast::NodeId, ast::Path)]>) {
679704
if let Some(define_opaque) = define_opaque {
680705
self.word("#[define_opaque(");
681706
for (i, (_, path)) in define_opaque.iter().enumerate() {

‎compiler/rustc_builtin_macros/src/define_opaque.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,20 @@ pub(crate) fn expand(
1111
let define_opaque = match &mut item {
1212
Annotatable::Item(p) => match &mut p.kind {
1313
ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
14+
ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
15+
ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
1416
_ => None,
1517
},
1618
Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
1719
ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
20+
ast::AssocItemKind::Const(ct) => Some(&mut ct.define_opaque),
1821
_ => None,
1922
},
2023
Annotatable::Stmt(s) => match &mut s.kind {
2124
ast::StmtKind::Item(p) => match &mut p.kind {
2225
ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
26+
ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
27+
ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
2328
_ => None,
2429
},
2530
_ => None,

‎compiler/rustc_builtin_macros/src/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ pub(crate) fn expand_test_or_bench(
285285
defaultness: ast::Defaultness::Final,
286286
generics: ast::Generics::default(),
287287
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
288+
define_opaque: None,
288289
// test::TestDescAndFn {
289290
expr: Some(
290291
cx.expr_struct(

‎compiler/rustc_expand/src/build.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,14 @@ impl<'a> ExtCtxt<'a> {
698698
name,
699699
AttrVec::new(),
700700
ast::ItemKind::Static(
701-
ast::StaticItem { ty, safety: ast::Safety::Default, mutability, expr: Some(expr) }
702-
.into(),
701+
ast::StaticItem {
702+
ty,
703+
safety: ast::Safety::Default,
704+
mutability,
705+
expr: Some(expr),
706+
define_opaque: None,
707+
}
708+
.into(),
703709
),
704710
)
705711
}
@@ -723,6 +729,7 @@ impl<'a> ExtCtxt<'a> {
723729
generics: ast::Generics::default(),
724730
ty,
725731
expr: Some(expr),
732+
define_opaque: None,
726733
}
727734
.into(),
728735
),

‎compiler/rustc_parse/src/parser/item.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ impl<'a> Parser<'a> {
265265
generics,
266266
ty,
267267
expr,
268+
define_opaque: None,
268269
})),
269270
)
270271
}
@@ -980,13 +981,20 @@ impl<'a> Parser<'a> {
980981
let kind = match AssocItemKind::try_from(kind) {
981982
Ok(kind) => kind,
982983
Err(kind) => match kind {
983-
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
984+
ItemKind::Static(box StaticItem {
985+
ty,
986+
safety: _,
987+
mutability: _,
988+
expr,
989+
define_opaque,
990+
}) => {
984991
self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
985992
AssocItemKind::Const(Box::new(ConstItem {
986993
defaultness: Defaultness::Final,
987994
generics: Generics::default(),
988995
ty,
989996
expr,
997+
define_opaque,
990998
}))
991999
}
9921000
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
@@ -1254,6 +1262,7 @@ impl<'a> Parser<'a> {
12541262
mutability: Mutability::Not,
12551263
expr,
12561264
safety: Safety::Default,
1265+
define_opaque: None,
12571266
}))
12581267
}
12591268
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
@@ -1397,7 +1406,7 @@ impl<'a> Parser<'a> {
13971406

13981407
self.expect_semi()?;
13991408

1400-
Ok((ident, StaticItem { ty, safety, mutability, expr }))
1409+
Ok((ident, StaticItem { ty, safety, mutability, expr, define_opaque: None }))
14011410
}
14021411

14031412
/// Parse a constant item with the prefix `"const"` already parsed.

‎compiler/rustc_resolve/src/def_collector.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,13 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
244244

245245
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
246246
let def_kind = match fi.kind {
247-
ForeignItemKind::Static(box StaticItem { ty: _, mutability, expr: _, safety }) => {
247+
ForeignItemKind::Static(box StaticItem {
248+
ty: _,
249+
mutability,
250+
expr: _,
251+
safety,
252+
define_opaque: _,
253+
}) => {
248254
let safety = match safety {
249255
ast::Safety::Unsafe(_) | ast::Safety::Default => hir::Safety::Unsafe,
250256
ast::Safety::Safe(_) => hir::Safety::Safe,

‎compiler/rustc_resolve/src/late.rs

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use rustc_session::parse::feature_err;
3636
use rustc_span::source_map::{Spanned, respan};
3737
use rustc_span::{BytePos, Ident, Span, Symbol, SyntaxContext, kw, sym};
3838
use smallvec::{SmallVec, smallvec};
39+
use thin_vec::ThinVec;
3940
use tracing::{debug, instrument, trace};
4041

4142
use crate::{
@@ -2662,10 +2663,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
26622663
},
26632664
|this| visit::walk_item(this, item),
26642665
);
2665-
2666-
for (id, path) in define_opaque.iter().flatten() {
2667-
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
2668-
}
2666+
self.resolve_define_opaques(define_opaque);
26692667
}
26702668

26712669
ItemKind::Enum(_, ref generics)
@@ -2751,7 +2749,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
27512749
});
27522750
}
27532751

2754-
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
2752+
ItemKind::Static(box ast::StaticItem {
2753+
ref ty, ref expr, ref define_opaque, ..
2754+
}) => {
27552755
self.with_static_rib(def_kind, |this| {
27562756
this.with_lifetime_rib(
27572757
LifetimeRibKind::Elided(LifetimeRes::Static {
@@ -2767,9 +2767,16 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
27672767
this.resolve_const_body(expr, Some((item.ident, ConstantItemKind::Static)));
27682768
}
27692769
});
2770+
self.resolve_define_opaques(define_opaque);
27702771
}
27712772

2772-
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
2773+
ItemKind::Const(box ast::ConstItem {
2774+
ref generics,
2775+
ref ty,
2776+
ref expr,
2777+
ref define_opaque,
2778+
..
2779+
}) => {
27732780
self.with_generic_param_rib(
27742781
&generics.params,
27752782
RibKind::Item(
@@ -2803,6 +2810,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
28032810
}
28042811
},
28052812
);
2813+
self.resolve_define_opaques(define_opaque);
28062814
}
28072815

28082816
ItemKind::Use(ref use_tree) => {
@@ -3102,7 +3110,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
31023110
for item in trait_items {
31033111
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
31043112
match &item.kind {
3105-
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
3113+
AssocItemKind::Const(box ast::ConstItem {
3114+
generics,
3115+
ty,
3116+
expr,
3117+
define_opaque,
3118+
..
3119+
}) => {
31063120
self.with_generic_param_rib(
31073121
&generics.params,
31083122
RibKind::AssocItem,
@@ -3135,13 +3149,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
31353149
)
31363150
},
31373151
);
3152+
3153+
self.resolve_define_opaques(define_opaque);
31383154
}
31393155
AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
31403156
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
31413157

3142-
for (id, path) in define_opaque.iter().flatten() {
3143-
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
3144-
}
3158+
self.resolve_define_opaques(define_opaque);
31453159
}
31463160
AssocItemKind::Delegation(delegation) => {
31473161
self.with_generic_param_rib(
@@ -3306,7 +3320,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33063320
use crate::ResolutionError::*;
33073321
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
33083322
match &item.kind {
3309-
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
3323+
AssocItemKind::Const(box ast::ConstItem {
3324+
generics, ty, expr, define_opaque, ..
3325+
}) => {
33103326
debug!("resolve_implementation AssocItemKind::Const");
33113327
self.with_generic_param_rib(
33123328
&generics.params,
@@ -3350,6 +3366,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33503366
);
33513367
},
33523368
);
3369+
self.resolve_define_opaques(define_opaque);
33533370
}
33543371
AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
33553372
debug!("resolve_implementation AssocItemKind::Fn");
@@ -3379,9 +3396,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33793396
},
33803397
);
33813398

3382-
for (id, path) in define_opaque.iter().flatten() {
3383-
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
3384-
}
3399+
self.resolve_define_opaques(define_opaque);
33853400
}
33863401
AssocItemKind::Type(box TyAlias { generics, .. }) => {
33873402
self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
@@ -5103,6 +5118,14 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
51035118
});
51045119
}
51055120
}
5121+
5122+
fn resolve_define_opaques(&mut self, define_opaque: &Option<ThinVec<(NodeId, Path)>>) {
5123+
if let Some(define_opaque) = define_opaque {
5124+
for (id, path) in define_opaque {
5125+
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
5126+
}
5127+
}
5128+
}
51065129
}
51075130

51085131
/// Walks the whole crate in DFS order, visiting each item, counting the declared number of

‎src/tools/clippy/clippy_utils/src/ast_utils/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,14 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
336336
mutability: lm,
337337
expr: le,
338338
safety: ls,
339+
define_opaque: _,
339340
}),
340341
Static(box StaticItem {
341342
ty: rt,
342343
mutability: rm,
343344
expr: re,
344345
safety: rs,
346+
define_opaque: _,
345347
}),
346348
) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
347349
(
@@ -350,12 +352,14 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
350352
generics: lg,
351353
ty: lt,
352354
expr: le,
355+
define_opaque: _,
353356
}),
354357
Const(box ConstItem {
355358
defaultness: rd,
356359
generics: rg,
357360
ty: rt,
358361
expr: re,
362+
define_opaque: _,
359363
}),
360364
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
361365
(
@@ -490,12 +494,14 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
490494
mutability: lm,
491495
expr: le,
492496
safety: ls,
497+
define_opaque: _,
493498
}),
494499
Static(box StaticItem {
495500
ty: rt,
496501
mutability: rm,
497502
expr: re,
498503
safety: rs,
504+
define_opaque: _,
499505
}),
500506
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs,
501507
(
@@ -557,12 +563,14 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
557563
generics: lg,
558564
ty: lt,
559565
expr: le,
566+
define_opaque: _,
560567
}),
561568
Const(box ConstItem {
562569
defaultness: rd,
563570
generics: rg,
564571
ty: rt,
565572
expr: re,
573+
define_opaque: _,
566574
}),
567575
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
568576
(
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ check-pass
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
type Closure = impl Fn(u32) -> u32;
6+
7+
#[define_opaque(Closure)]
8+
const ADDER: Closure = |x| x + 1;
9+
10+
fn main() {
11+
let z = (ADDER)(1);
12+
}

‎tests/ui/type-alias-impl-trait/issue-53092-2.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
#![allow(dead_code)]
33

44
type Bug<T, U> = impl Fn(T) -> U + Copy;
5+
//~^ ERROR cycle detected when computing type of `Bug::{opaque#0}`
56

67
#[define_opaque(Bug)]
7-
//~^ ERROR: only functions and methods can define opaque types
88
const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
9+
//~^ ERROR item does not constrain `Bug::{opaque#0}`
910

1011
#[define_opaque(Bug)]
1112
fn make_bug<T, U: From<T>>() -> Bug<T, U> {
12-
|x| x.into() //~ ERROR is not satisfied
13+
|x| x.into()
1314
}
1415

1516
fn main() {
Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
1-
error: only functions and methods can define opaque types
2-
--> $DIR/issue-53092-2.rs:6:1
1+
error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
2+
--> $DIR/issue-53092-2.rs:4:18
33
|
4-
LL | #[define_opaque(Bug)]
5-
| ^^^^^^^^^^^^^^^^^^^^^
6-
7-
error[E0277]: the trait bound `U: From<T>` is not satisfied
8-
--> $DIR/issue-53092-2.rs:12:5
4+
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires computing type of opaque `Bug::{opaque#0}`...
8+
--> $DIR/issue-53092-2.rs:4:18
9+
|
10+
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
11+
| ^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires type-checking `CONST_BUG`...
13+
--> $DIR/issue-53092-2.rs:8:1
914
|
10-
LL | |x| x.into()
11-
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
15+
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: ...which requires computing layout of `Bug<u8, ()>`...
18+
= note: ...which requires normalizing `Bug<u8, ()>`...
19+
= note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
20+
note: cycle used when checking that `Bug::{opaque#0}` is well-formed
21+
--> $DIR/issue-53092-2.rs:4:18
22+
|
23+
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
24+
| ^^^^^^^^^^^^^^^^^^^^^^
25+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
26+
27+
error: item does not constrain `Bug::{opaque#0}`
28+
--> $DIR/issue-53092-2.rs:8:7
1229
|
13-
note: required by a bound in `make_bug`
14-
--> $DIR/issue-53092-2.rs:11:19
30+
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
31+
| ^^^^^^^^^
1532
|
16-
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
17-
| ^^^^^^^ required by this bound in `make_bug`
18-
help: consider restricting type parameter `U` with trait `From`
33+
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
34+
note: this opaque type is supposed to be constrained
35+
--> $DIR/issue-53092-2.rs:4:18
1936
|
20-
LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
21-
| +++++++++++++++++++++++
37+
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
38+
| ^^^^^^^^^^^^^^^^^^^^^^
2239

2340
error: aborting due to 2 previous errors
2441

25-
For more information about this error, try `rustc --explain E0277`.
42+
For more information about this error, try `rustc --explain E0391`.
Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1+
//@ check-pass
2+
13
#![feature(type_alias_impl_trait)]
2-
// Ensures that `const` items can not constrain an opaque `impl Trait`.
34

45
use std::fmt::Debug;
56

67
pub type Foo = impl Debug;
7-
//~^ ERROR unconstrained opaque type
88

99
#[define_opaque(Foo)]
10-
//~^ ERROR only functions and methods can define opaque types
1110
const _FOO: Foo = 5;
12-
//~^ ERROR mismatched types
1311

1412
#[define_opaque(Foo)]
15-
//~^ ERROR only functions and methods can define opaque types
16-
static _BAR: Foo = 22_u32;
17-
//~^ ERROR mismatched types
13+
static _BAR: Foo = 22_i32;
1814

1915
fn main() {}

‎tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.