Skip to content

Commit 103a4d8

Browse files
mark-i-mpietroalbini
authored andcommitted
Attempt to fix hygiene for global_allocator
1 parent 5b172eb commit 103a4d8

File tree

3 files changed

+74
-21
lines changed

3 files changed

+74
-21
lines changed

src/librustc_allocator/expand.rs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![allow(unused_imports, unused_variables, dead_code)]
12+
1113
use rustc::middle::allocator::AllocatorKind;
1214
use rustc_errors;
1315
use rustc_target::spec::abi::Abi;
@@ -35,13 +37,15 @@ pub fn modify(
3537
sess: &ParseSess,
3638
resolver: &mut Resolver,
3739
krate: Crate,
40+
crate_name: String,
3841
handler: &rustc_errors::Handler,
3942
) -> ast::Crate {
4043
ExpandAllocatorDirectives {
4144
handler,
4245
sess,
4346
resolver,
4447
found: false,
48+
crate_name: Some(crate_name),
4549
}.fold_crate(krate)
4650
}
4751

@@ -50,6 +54,7 @@ struct ExpandAllocatorDirectives<'a> {
5054
handler: &'a rustc_errors::Handler,
5155
sess: &'a ParseSess,
5256
resolver: &'a mut Resolver,
57+
crate_name: Option<String>,
5358
}
5459

5560
impl<'a> Folder for ExpandAllocatorDirectives<'a> {
@@ -78,9 +83,10 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> {
7883
}
7984
self.found = true;
8085

86+
// Create a fresh Mark for the new macro expansion we are about to do
8187
let mark = Mark::fresh(Mark::root());
8288
mark.set_expn_info(ExpnInfo {
83-
call_site: DUMMY_SP,
89+
call_site: item.span,
8490
callee: NameAndSpan {
8591
format: MacroAttribute(Symbol::intern(name)),
8692
span: None,
@@ -89,35 +95,34 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> {
8995
edition: hygiene::default_edition(),
9096
},
9197
});
98+
99+
// Tie the span to the macro expansion info we just created
92100
let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
93-
let ecfg = ExpansionConfig::default(name.to_string());
101+
102+
// Create an expansion config
103+
let ecfg = ExpansionConfig::default(self.crate_name.take().unwrap());
104+
105+
// Generate a bunch of new items using the AllocFnFactory
94106
let mut f = AllocFnFactory {
95107
span,
96108
kind: AllocatorKind::Global,
97109
global: item.ident,
98-
core: Ident::from_str("core"),
110+
core: Ident::with_empty_ctxt(Symbol::gensym("core")),
99111
cx: ExtCtxt::new(self.sess, ecfg, self.resolver),
100112
};
101-
let super_path = f.cx.path(f.span, vec![Ident::from_str("super"), f.global]);
102-
let mut items = vec![
103-
f.cx.item_extern_crate(f.span, f.core),
104-
f.cx.item_use_simple(
105-
f.span,
106-
respan(f.span.shrink_to_lo(), VisibilityKind::Inherited),
107-
super_path,
108-
),
109-
];
110-
for method in ALLOCATOR_METHODS {
111-
items.push(f.allocator_fn(method));
112-
}
113-
let name = f.kind.fn_name("allocator_abi");
114-
let allocator_abi = Ident::with_empty_ctxt(Symbol::gensym(&name));
115-
let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items);
116-
let module = f.cx.monotonic_expander().fold_item(module).pop().unwrap();
113+
114+
let extcore = {
115+
let extcore = f.cx.item_extern_crate(item.span, f.core);
116+
f.cx.monotonic_expander().fold_item(extcore).pop().unwrap()
117+
};
117118

118119
let mut ret = SmallVector::new();
119120
ret.push(item);
120-
ret.push(module);
121+
ret.push(extcore);
122+
ret.extend(ALLOCATOR_METHODS.iter().map(|method| {
123+
let method = f.allocator_fn(method);
124+
f.cx.monotonic_expander().fold_item(method).pop().unwrap()
125+
}));
121126
return ret;
122127
}
123128

@@ -170,6 +175,7 @@ impl<'a> AllocFnFactory<'a> {
170175
let method = self.cx.path(
171176
self.span,
172177
vec![
178+
Ident::from_str("self"),
173179
self.core,
174180
Ident::from_str("alloc"),
175181
Ident::from_str("GlobalAlloc"),
@@ -220,6 +226,7 @@ impl<'a> AllocFnFactory<'a> {
220226
let layout_new = self.cx.path(
221227
self.span,
222228
vec![
229+
Ident::from_str("self"),
223230
self.core,
224231
Ident::from_str("alloc"),
225232
Ident::from_str("Layout"),

src/librustc_driver/driver.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,10 +1051,19 @@ where
10511051
});
10521052
}
10531053

1054+
// Expand global allocators, which are treated as an in-tree proc macro
10541055
krate = time(sess, "creating allocators", || {
1055-
allocator::expand::modify(&sess.parse_sess, &mut resolver, krate, sess.diagnostic())
1056+
allocator::expand::modify(
1057+
&sess.parse_sess,
1058+
&mut resolver,
1059+
krate,
1060+
crate_name.to_string(),
1061+
sess.diagnostic(),
1062+
)
10561063
});
10571064

1065+
// Done with macro expansion!
1066+
10581067
after_expand(&krate)?;
10591068

10601069
if sess.opts.debugging_opts.input_stats {

src/test/ui/allocator-submodule.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that it is possible to create a global allocator in a submodule, rather than in the crate
12+
// root.
13+
14+
#![feature(alloc, allocator_api, global_allocator)]
15+
16+
extern crate alloc;
17+
18+
use std::alloc::{GlobalAlloc, Layout, Opaque};
19+
20+
struct MyAlloc;
21+
22+
unsafe impl GlobalAlloc for MyAlloc {
23+
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
24+
0 as usize as *mut Opaque
25+
}
26+
27+
unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {}
28+
}
29+
30+
mod submod {
31+
use super::MyAlloc;
32+
33+
#[global_allocator]
34+
static MY_HEAP: MyAlloc = MyAlloc;
35+
}
36+
37+
fn main() {}

0 commit comments

Comments
 (0)