Skip to content

Commit 79d1834

Browse files
committed
wip
1 parent e4c626d commit 79d1834

File tree

9 files changed

+142
-0
lines changed

9 files changed

+142
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use crate::errors;
2+
use crate::util::check_builtin_macro_attribute;
3+
4+
use rustc_ast::ptr::P;
5+
use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind};
6+
use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe};
7+
use rustc_expand::base::{Annotatable, ExtCtxt};
8+
use rustc_span::symbol::{kw, sym, Ident};
9+
use rustc_span::Span;
10+
use thin_vec::{thin_vec, ThinVec};
11+
12+
pub fn expand(
13+
ecx: &mut ExtCtxt<'_>,
14+
_span: Span,
15+
meta_item: &ast::MetaItem,
16+
item: Annotatable,
17+
) -> Vec<Annotatable> {
18+
//check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
19+
//check_builtin_macro_attribute(ecx, meta_item, sym::autodiff);
20+
21+
let orig_item = item.clone();
22+
23+
// Allow using `#[alloc_error_handler]` on an item statement
24+
// FIXME - if we get deref patterns, use them to reduce duplication here
25+
let (item, is_stmt, sig_span) = if let Annotatable::Item(item) = &item
26+
&& let ItemKind::Fn(fn_kind) = &item.kind
27+
{
28+
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
29+
} else if let Annotatable::Stmt(stmt) = &item
30+
&& let StmtKind::Item(item) = &stmt.kind
31+
&& let ItemKind::Fn(fn_kind) = &item.kind
32+
{
33+
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
34+
} else {
35+
ecx.sess.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
36+
return vec![orig_item];
37+
};
38+
39+
// Generate a bunch of new items using the AllocFnFactory
40+
let span = ecx.with_def_site_ctxt(item.span);
41+
42+
// Generate item statements for the allocator methods.
43+
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
44+
45+
// Generate anonymous constant serving as container for the allocator methods.
46+
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
47+
let const_body = ecx.expr_block(ecx.block(span, stmts));
48+
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
49+
let const_item = if is_stmt {
50+
Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
51+
} else {
52+
Annotatable::Item(const_item)
53+
};
54+
55+
// Return the original item and the new methods.
56+
vec![orig_item, const_item]
57+
}
58+
59+
// #[rustc_std_internal_symbol]
60+
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
61+
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
62+
// }
63+
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
64+
let usize = cx.path_ident(span, Ident::new(sym::usize, span));
65+
let ty_usize = cx.ty_path(usize);
66+
let size = Ident::from_str_and_span("size", span);
67+
let align = Ident::from_str_and_span("align", span);
68+
69+
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
70+
let layout_new = cx.expr_path(cx.path(span, layout_new));
71+
let layout = cx.expr_call(
72+
span,
73+
layout_new,
74+
thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
75+
);
76+
77+
let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
78+
79+
let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
80+
let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
81+
let decl = cx.fn_decl(params, never);
82+
let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
83+
let sig = FnSig { decl, header, span: span };
84+
85+
let body = Some(cx.block_expr(call));
86+
let kind = ItemKind::Fn(Box::new(Fn {
87+
defaultness: ast::Defaultness::Final,
88+
sig,
89+
generics: Generics::default(),
90+
body,
91+
}));
92+
93+
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
94+
95+
let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind);
96+
cx.stmt_item(sig_span, item)
97+
}

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![feature(lint_reasons)]
1515
#![feature(proc_macro_internals)]
1616
#![feature(proc_macro_quote)]
17+
#![cfg_attr(not(bootstrap), feature(autodiff))]
1718
#![recursion_limit = "256"]
1819

1920
extern crate proc_macro;
@@ -29,6 +30,7 @@ use rustc_span::symbol::sym;
2930

3031
mod alloc_error_handler;
3132
mod assert;
33+
mod autodiff;
3234
mod cfg;
3335
mod cfg_accessible;
3436
mod cfg_eval;
@@ -105,6 +107,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
105107

106108
register_attr! {
107109
alloc_error_handler: alloc_error_handler::expand,
110+
autodiff: autodiff::expand,
108111
bench: test::expand_bench,
109112
cfg_accessible: cfg_accessible::Expander,
110113
cfg_eval: cfg_eval::expand,

compiler/rustc_expand/src/base.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,8 @@ pub trait ResolverExpand {
917917

918918
fn check_unused_macros(&mut self);
919919

920+
//fn autodiff() -> bool;
921+
920922
// Resolver interfaces for specific built-in macros.
921923
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
922924
fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;

compiler/rustc_resolve/src/macros.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
344344
self.containers_deriving_copy.contains(&expn_id)
345345
}
346346

347+
// TODO: add autodiff?
348+
347349
fn resolve_derives(
348350
&mut self,
349351
expn_id: LocalExpnId,

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ symbols! {
6969

7070
// Keywords that are used in unstable Rust or reserved for future use.
7171
Abstract: "abstract",
72+
//Autodiff: "autodiff",
7273
Become: "become",
7374
Box: "box",
7475
Do: "do",
@@ -438,6 +439,7 @@ symbols! {
438439
attributes,
439440
augmented_assignments,
440441
auto_traits,
442+
autodiff,
441443
automatically_derived,
442444
avx,
443445
avx512_target_feature,

library/core/src/macros/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,19 @@ pub(crate) mod builtin {
14861486
($file:expr $(,)?) => {{ /* compiler built-in */ }};
14871487
}
14881488

1489+
/// Attribute macro used to apply derive macros for implementing traits
1490+
/// in a const context. Autodiff
1491+
///
1492+
/// See [the reference] for more info.
1493+
///
1494+
/// [the reference]: ../../../reference/attributes/derive.html
1495+
#[unstable(feature = "autodiff", issue = "none")]
1496+
#[rustc_builtin_macro]
1497+
#[cfg(not(bootstrap))]
1498+
pub macro autodiff($item:item) {
1499+
/* compiler built-in */
1500+
}
1501+
14891502
/// Asserts that a boolean expression is `true` at runtime.
14901503
///
14911504
/// This will invoke the [`panic!`] macro if the provided expression cannot be

library/core/src/prelude/v1.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ pub use crate::macros::builtin::{
8383
#[unstable(feature = "derive_const", issue = "none")]
8484
pub use crate::macros::builtin::derive_const;
8585

86+
#[cfg(not(bootstrap))]
87+
#[unstable(feature = "autodiff", issue = "none")]
88+
#[rustc_builtin_macro]
89+
pub use crate::macros::builtin::autodiff;
90+
8691
#[unstable(
8792
feature = "cfg_accessible",
8893
issue = "64797",

library/std/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@
255255
#![allow(unused_features)]
256256
//
257257
// Features:
258+
259+
#![cfg_attr(not(bootstrap), feature(autodiff))]
258260
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
259261
#![cfg_attr(
260262
all(target_vendor = "fortanix", target_env = "sgx"),
@@ -662,6 +664,17 @@ pub use core::{
662664
module_path, option_env, stringify, trace_macros,
663665
};
664666

667+
668+
// #[unstable(
669+
// feature = "autodiff",
670+
// issue = "87555",
671+
// reason = "`autodiff` is not stable enough for use and is subject to change"
672+
// )]
673+
// #[cfg(not(bootstrap))]
674+
// pub use core::autodiff;
675+
676+
677+
665678
#[unstable(
666679
feature = "concat_bytes",
667680
issue = "87555",

library/std/src/prelude/v1.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ pub use core::prelude::v1::{
6767
#[unstable(feature = "derive_const", issue = "none")]
6868
pub use core::prelude::v1::derive_const;
6969

70+
#[unstable(feature = "autodiff", issue = "none")]
71+
#[cfg(not(bootstrap))]
72+
#[rustc_builtin_macro]
73+
pub use core::prelude::v1::autodiff;
74+
7075
// Do not `doc(no_inline)` either.
7176
#[unstable(
7277
feature = "cfg_accessible",

0 commit comments

Comments
 (0)