Skip to content

Commit 94ab946

Browse files
committed
Implement #[define_opaques] attribute for functions.
1 parent 91a0e16 commit 94ab946

File tree

639 files changed

+2664
-2207
lines changed

Some content is hidden

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

639 files changed

+2664
-2207
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4516,6 +4516,7 @@ version = "0.0.0"
45164516
dependencies = [
45174517
"itertools",
45184518
"rustc_abi",
4519+
"rustc_attr_parsing",
45194520
"rustc_data_structures",
45204521
"rustc_errors",
45214522
"rustc_fluent_macro",

compiler/rustc_ast/src/ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3454,6 +3454,7 @@ pub struct Fn {
34543454
pub generics: Generics,
34553455
pub sig: FnSig,
34563456
pub contract: Option<P<FnContract>>,
3457+
pub define_opaques: Option<ThinVec<(NodeId, Path)>>,
34573458
pub body: Option<P<Block>>,
34583459
}
34593460

@@ -3751,7 +3752,7 @@ mod size_asserts {
37513752
static_assert_size!(Block, 32);
37523753
static_assert_size!(Expr, 72);
37533754
static_assert_size!(ExprKind, 40);
3754-
static_assert_size!(Fn, 168);
3755+
static_assert_size!(Fn, 176);
37553756
static_assert_size!(ForeignItem, 88);
37563757
static_assert_size!(ForeignItemKind, 16);
37573758
static_assert_size!(GenericArg, 24);

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,14 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
973973
_ctxt,
974974
_ident,
975975
_vis,
976-
Fn { defaultness, generics, contract, body, sig: FnSig { header, decl, span } },
976+
Fn {
977+
defaultness,
978+
generics,
979+
contract,
980+
body,
981+
sig: FnSig { header, decl, span },
982+
define_opaques,
983+
},
977984
) => {
978985
// Identifier and visibility are visited as a part of the item.
979986
visit_defaultness(vis, defaultness);
@@ -987,6 +994,11 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
987994
vis.visit_block(body);
988995
}
989996
vis.visit_span(span);
997+
998+
for (id, path) in define_opaques.iter_mut().flatten() {
999+
vis.visit_id(id);
1000+
vis.visit_path(path)
1001+
}
9901002
}
9911003
FnKind::Closure(binder, coroutine_kind, decl, body) => {
9921004
vis.visit_closure_binder(binder);

compiler/rustc_ast/src/visit.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,14 +892,24 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
892892
_ctxt,
893893
_ident,
894894
_vis,
895-
Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, contract, body },
895+
Fn {
896+
defaultness: _,
897+
sig: FnSig { header, decl, span: _ },
898+
generics,
899+
contract,
900+
body,
901+
define_opaques,
902+
},
896903
) => {
897904
// Identifier and visibility are visited as a part of the item.
898905
try_visit!(visitor.visit_fn_header(header));
899906
try_visit!(visitor.visit_generics(generics));
900907
try_visit!(visitor.visit_fn_decl(decl));
901908
visit_opt!(visitor, visit_contract, contract);
902909
visit_opt!(visitor, visit_block, body);
910+
for (id, path) in define_opaques.iter().flatten() {
911+
try_visit!(visitor.visit_path(path, *id))
912+
}
903913
}
904914
FnKind::Closure(binder, coroutine_kind, decl, body) => {
905915
try_visit!(visitor.visit_closure_binder(binder));
@@ -1203,7 +1213,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
12031213
FnKind::Closure(binder, coroutine_kind, fn_decl, body),
12041214
*span,
12051215
*id
1206-
))
1216+
));
12071217
}
12081218
ExprKind::Block(block, opt_label) => {
12091219
visit_opt!(visitor, visit_label, opt_label);

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ use rustc_ast::ptr::P;
33
use rustc_ast::visit::AssocCtxt;
44
use rustc_ast::*;
55
use rustc_errors::ErrorGuaranteed;
6-
use rustc_hir as hir;
7-
use rustc_hir::PredicateOrigin;
86
use rustc_hir::def::{DefKind, Res};
97
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
8+
use rustc_hir::{self as hir, HirId, PredicateOrigin};
109
use rustc_index::{IndexSlice, IndexVec};
1110
use rustc_middle::span_bug;
1211
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -209,6 +208,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
209208
generics,
210209
body,
211210
contract,
211+
define_opaques,
212212
..
213213
}) => {
214214
self.with_new_scopes(*fn_sig_span, |this| {
@@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
237237
header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
238238
span: this.lower_span(*fn_sig_span),
239239
};
240+
this.lower_define_opaques(hir_id, &define_opaques);
240241
hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
241242
})
242243
}
@@ -779,7 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
779780
);
780781
(generics, kind, expr.is_some())
781782
}
782-
AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
783+
AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaques, .. }) => {
783784
// FIXME(contracts): Deny contract here since it won't apply to
784785
// any impl method or callees.
785786
let names = self.lower_fn_params_to_names(&sig.decl);
@@ -791,9 +792,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
791792
sig.header.coroutine_kind,
792793
attrs,
793794
);
795+
if define_opaques.is_some() {
796+
self.dcx().span_err(
797+
i.span,
798+
"only trait methods with default bodies can define opaque types",
799+
);
800+
}
794801
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
795802
}
796-
AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), contract, .. }) => {
803+
AssocItemKind::Fn(box Fn {
804+
sig,
805+
generics,
806+
body: Some(body),
807+
contract,
808+
define_opaques,
809+
..
810+
}) => {
797811
let body_id = self.lower_maybe_coroutine_body(
798812
sig.span,
799813
i.span,
@@ -812,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
812826
sig.header.coroutine_kind,
813827
attrs,
814828
);
829+
self.lower_define_opaques(hir_id, &define_opaques);
815830
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
816831
}
817832
AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
@@ -911,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911926
hir::ImplItemKind::Const(ty, body)
912927
},
913928
),
914-
AssocItemKind::Fn(box Fn { sig, generics, body, contract, .. }) => {
929+
AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaques, .. }) => {
915930
let body_id = self.lower_maybe_coroutine_body(
916931
sig.span,
917932
i.span,
@@ -930,6 +945,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
930945
sig.header.coroutine_kind,
931946
attrs,
932947
);
948+
self.lower_define_opaques(hir_id, &define_opaques);
933949

934950
(generics, hir::ImplItemKind::Fn(sig, body_id))
935951
}
@@ -1657,6 +1673,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
16571673
(lowered_generics, res)
16581674
}
16591675

1676+
pub(super) fn lower_define_opaques(
1677+
&mut self,
1678+
hir_id: HirId,
1679+
define_opaques: &Option<ThinVec<(NodeId, Path)>>,
1680+
) {
1681+
assert_eq!(self.define_opaques, None);
1682+
assert!(hir_id.is_owner());
1683+
let Some(define_opaques) = define_opaques.as_ref() else {
1684+
return;
1685+
};
1686+
let define_opaques = define_opaques
1687+
.iter()
1688+
// TODO: error reporting for non-local items being mentioned and tests that go through these code paths
1689+
.map(|(id, _path)| {
1690+
self.resolver
1691+
.get_partial_res(*id)
1692+
.unwrap()
1693+
.expect_full_res()
1694+
.def_id()
1695+
.expect_local()
1696+
});
1697+
let define_opaques = self.arena.alloc_from_iter(define_opaques);
1698+
self.define_opaques = Some(define_opaques);
1699+
}
1700+
16601701
pub(super) fn lower_generic_bound_predicate(
16611702
&mut self,
16621703
ident: Ident,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#![doc(rust_logo)]
3636
#![feature(assert_matches)]
3737
#![feature(box_patterns)]
38+
#![feature(exact_size_is_empty)]
3839
#![feature(if_let_guard)]
3940
#![feature(let_chains)]
4041
#![feature(rustdoc_internals)]
@@ -98,6 +99,8 @@ struct LoweringContext<'a, 'hir> {
9899

99100
/// Bodies inside the owner being lowered.
100101
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
102+
/// `#[define_opaques]` attributes
103+
define_opaques: Option<&'hir [LocalDefId]>,
101104
/// Attributes inside the owner being lowered.
102105
attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
103106
/// Collect items that were created by lowering the current owner.
@@ -155,6 +158,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
155158

156159
// HirId handling.
157160
bodies: Vec::new(),
161+
define_opaques: None,
158162
attrs: SortedMap::default(),
159163
children: Vec::default(),
160164
contract_ensures: None,
@@ -547,6 +551,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
547551

548552
let current_attrs = std::mem::take(&mut self.attrs);
549553
let current_bodies = std::mem::take(&mut self.bodies);
554+
let current_define_opaques = std::mem::take(&mut self.define_opaques);
550555
let current_ident_and_label_to_local_id =
551556
std::mem::take(&mut self.ident_and_label_to_local_id);
552557

@@ -580,6 +585,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
580585

581586
self.attrs = current_attrs;
582587
self.bodies = current_bodies;
588+
self.define_opaques = current_define_opaques;
583589
self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
584590

585591
#[cfg(debug_assertions)]
@@ -599,6 +605,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
599605
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
600606
let attrs = std::mem::take(&mut self.attrs);
601607
let mut bodies = std::mem::take(&mut self.bodies);
608+
let define_opaques = std::mem::take(&mut self.define_opaques);
602609
let trait_map = std::mem::take(&mut self.trait_map);
603610

604611
#[cfg(debug_assertions)]
@@ -618,7 +625,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
618625
let num_nodes = self.item_local_id_counter.as_usize();
619626
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
620627
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
621-
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
628+
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaques };
622629

623630
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
624631
}

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
917917
walk_list!(self, visit_attribute, &item.attrs);
918918
return; // Avoid visiting again.
919919
}
920-
ItemKind::Fn(func @ box Fn { defaultness, generics: _, sig, contract: _, body }) => {
920+
ItemKind::Fn(
921+
func @ box Fn {
922+
defaultness,
923+
generics: _,
924+
sig,
925+
contract: _,
926+
body,
927+
define_opaques: _,
928+
},
929+
) => {
921930
self.check_defaultness(item.span, *defaultness);
922931

923932
let is_intrinsic =

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use rustc_span::edition::Edition;
2424
use rustc_span::source_map::{SourceMap, Spanned};
2525
use rustc_span::symbol::IdentPrinter;
2626
use rustc_span::{BytePos, CharPos, DUMMY_SP, FileName, Ident, Pos, Span, Symbol, kw, sym};
27-
use thin_vec::ThinVec;
2827

2928
use crate::pp::Breaks::{Consistent, Inconsistent};
3029
use crate::pp::{self, Breaks};
@@ -1978,15 +1977,7 @@ impl<'a> State<'a> {
19781977
) {
19791978
self.ibox(INDENT_UNIT);
19801979
self.print_formal_generic_params(generic_params);
1981-
let generics = ast::Generics {
1982-
params: ThinVec::new(),
1983-
where_clause: ast::WhereClause {
1984-
has_where_token: false,
1985-
predicates: ThinVec::new(),
1986-
span: DUMMY_SP,
1987-
},
1988-
span: DUMMY_SP,
1989-
};
1980+
let generics = ast::Generics::default();
19901981
let header = ast::FnHeader { safety, ext, ..ast::FnHeader::default() };
19911982
self.print_fn(decl, header, name, &generics);
19921983
self.end();

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,16 @@ impl<'a> State<'a> {
650650
attrs: &[ast::Attribute],
651651
func: &ast::Fn,
652652
) {
653-
let ast::Fn { defaultness, generics, sig, contract, body } = func;
653+
let ast::Fn { defaultness, generics, sig, contract, body, define_opaques } = func;
654+
655+
if let Some(define_opaques) = define_opaques {
656+
for (_, path) in define_opaques {
657+
self.word("define opaques from ");
658+
self.print_path(path, false, 0);
659+
self.word(",");
660+
}
661+
}
662+
654663
if body.is_some() {
655664
self.head("");
656665
}
@@ -698,7 +707,7 @@ impl<'a> State<'a> {
698707
}
699708
self.print_generic_params(&generics.params);
700709
self.print_fn_params_and_ret(decl, false);
701-
self.print_where_clause(&generics.where_clause)
710+
self.print_where_clause(&generics.where_clause);
702711
}
703712

704713
pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) {

compiler/rustc_attr_data_structures/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_abi::Align;
1717
use rustc_ast::token::CommentKind;
1818
use rustc_ast::{AttrStyle, IntTy, UintTy};
1919
use rustc_ast_pretty::pp::Printer;
20+
use rustc_span::def_id::LocalDefId;
2021
use rustc_span::hygiene::Transparency;
2122
use rustc_span::{Span, Symbol};
2223
pub use stability::*;
@@ -148,4 +149,4 @@ macro_rules! print_tup {
148149
print_tup!(A B C D E F G H);
149150
print_skip!(Span, ());
150151
print_disp!(Symbol, u16, bool, NonZero<u32>);
151-
print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
152+
print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency, LocalDefId);

0 commit comments

Comments
 (0)