about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-11 18:13:31 +0000
committerbors <bors@rust-lang.org>2025-03-11 18:13:31 +0000
commit6650252439d4e03368b305c42a10006e36f1545e (patch)
tree143473174f128998c2f0665dd2802ce459dadedd /compiler/rustc_builtin_macros
parentf2d69d5a7c04617d122facd0a7a5bdde0af928ae (diff)
parent69a1bb8bdba5ccb76a72e35a69fde1937c287386 (diff)
downloadrust-6650252439d4e03368b305c42a10006e36f1545e.tar.gz
rust-6650252439d4e03368b305c42a10006e36f1545e.zip
Auto merge of #128440 - oli-obk:defines, r=lcnr
Add `#[define_opaques]` attribute and require it for all type-alias-impl-trait sites that register a hidden type

Instead of relying on the signature of items to decide whether they are constraining an opaque type, the opaque types that the item constrains must be explicitly listed.

A previous version of this PR used an actual attribute, but had to keep the resolved `DefId`s in a side table.

Now we just lower to fields in the AST that have no surface syntax, instead a builtin attribute macro fills in those fields where applicable.

Note that for convenience referencing opaque types in associated types from associated methods on the same impl will not require an attribute. If that causes problems `#[defines()]` can be used to overwrite the default of searching for opaques in the signature.

One wart of this design is that closures and static items do not have generics. So since I stored the opaques in the generics of functions, consts and methods, I would need to add a custom field to closures and statics to track this information. During a T-types discussion we decided to just not do this for now.

fixes #131298
Diffstat (limited to 'compiler/rustc_builtin_macros')
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/define_opaque.rs54
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs1
7 files changed, 61 insertions, 0 deletions
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index 78bf2195975..1c1b2c88f76 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -88,6 +88,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
         generics: Generics::default(),
         contract: None,
         body,
+        define_opaque: None,
     }));
 
     let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 7b5c4a159b0..bb17efa02e0 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -247,6 +247,7 @@ mod llvm_enzyme {
             generics: Generics::default(),
             contract: None,
             body: Some(d_body),
+            define_opaque: None,
         });
         let mut rustc_ad_attr =
             P(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));
diff --git a/compiler/rustc_builtin_macros/src/define_opaque.rs b/compiler/rustc_builtin_macros/src/define_opaque.rs
new file mode 100644
index 00000000000..9777e772cf2
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/define_opaque.rs
@@ -0,0 +1,54 @@
+use rustc_ast::{DUMMY_NODE_ID, ast};
+use rustc_expand::base::{Annotatable, ExtCtxt};
+use rustc_span::Span;
+
+pub(crate) fn expand(
+    ecx: &mut ExtCtxt<'_>,
+    _expand_span: Span,
+    meta_item: &ast::MetaItem,
+    mut item: Annotatable,
+) -> Vec<Annotatable> {
+    let define_opaque = match &mut item {
+        Annotatable::Item(p) => match &mut p.kind {
+            ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+            _ => None,
+        },
+        Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
+            ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
+            _ => None,
+        },
+        Annotatable::Stmt(s) => match &mut s.kind {
+            ast::StmtKind::Item(p) => match &mut p.kind {
+                ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+                _ => None,
+            },
+            _ => None,
+        },
+        _ => None,
+    };
+
+    let Some(list) = meta_item.meta_item_list() else {
+        ecx.dcx().span_err(meta_item.span, "expected list of type aliases");
+        return vec![item];
+    };
+
+    if let Some(define_opaque) = define_opaque {
+        *define_opaque = Some(
+            list.iter()
+                .filter_map(|entry| match entry {
+                    ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => {
+                        Some((DUMMY_NODE_ID, meta_item.path.clone()))
+                    }
+                    _ => {
+                        ecx.dcx().span_err(entry.span(), "expected path to type alias");
+                        None
+                    }
+                })
+                .collect(),
+        );
+    } else {
+        ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types");
+    }
+
+    vec![item]
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 5402b5a1ae9..03ee59de70e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -1040,6 +1040,7 @@ impl<'a> MethodDef<'a> {
                 generics: fn_generics,
                 contract: None,
                 body: Some(body_block),
+                define_opaque: None,
             })),
             tokens: None,
         })
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 8fdbbf8e704..90d79235820 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -83,6 +83,7 @@ impl AllocFnFactory<'_, '_> {
             generics: Generics::default(),
             contract: None,
             body,
+            define_opaque: None,
         }));
         let item = self.cx.item(
             self.span,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index ca16583a45d..c5d2a84fba4 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -39,6 +39,7 @@ mod compile_error;
 mod concat;
 mod concat_bytes;
 mod concat_idents;
+mod define_opaque;
 mod derive;
 mod deriving;
 mod edition_panic;
@@ -114,6 +115,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         bench: test::expand_bench,
         cfg_accessible: cfg_accessible::Expander,
         cfg_eval: cfg_eval::expand,
+        define_opaque: define_opaque::expand,
         derive: derive::Expander { is_const: false },
         derive_const: derive::Expander { is_const: true },
         global_allocator: global_allocator::expand,
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 472e16e62d5..768b459ec5e 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -346,6 +346,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         generics: ast::Generics::default(),
         contract: None,
         body: Some(main_body),
+        define_opaque: None,
     }));
 
     // Honor the reexport_test_harness_main attribute