From 5da4ff8180b4ba67c6e206e3c910f2a7848c2d07 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 13 Apr 2018 15:58:16 -0500 Subject: [PATCH] Attempt to fix hygiene for global_allocator --- src/librustc_allocator/expand.rs | 47 +++++++++++++++++------------- src/librustc_driver/driver.rs | 11 ++++++- src/test/ui/allocator-submodule.rs | 37 +++++++++++++++++++++++ 3 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/allocator-submodule.rs diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index a9530964bff..cea1807cfba 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_imports, unused_variables, dead_code)] + use rustc::middle::allocator::AllocatorKind; use rustc_errors; use syntax::ast::{Attribute, Crate, LitKind, StrStyle}; @@ -34,6 +36,7 @@ pub fn modify( sess: &ParseSess, resolver: &mut Resolver, krate: Crate, + crate_name: String, handler: &rustc_errors::Handler, ) -> ast::Crate { ExpandAllocatorDirectives { @@ -41,6 +44,7 @@ pub fn modify( sess, resolver, found: false, + crate_name: Some(crate_name), }.fold_crate(krate) } @@ -49,6 +53,7 @@ struct ExpandAllocatorDirectives<'a> { handler: &'a rustc_errors::Handler, sess: &'a ParseSess, resolver: &'a mut Resolver, + crate_name: Option, } impl<'a> Folder for ExpandAllocatorDirectives<'a> { @@ -77,44 +82,44 @@ fn fold_item(&mut self, item: P) -> SmallVector> { } self.found = true; + // Create a fresh Mark for the new macro expansion we are about to do let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo { - call_site: DUMMY_SP, + call_site: item.span, def_site: None, format: MacroAttribute(Symbol::intern(name)), allow_internal_unstable: true, allow_internal_unsafe: false, edition: hygiene::default_edition(), }); + + // Tie the span to the macro expansion info we just created let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - let ecfg = ExpansionConfig::default(name.to_string()); + + // Create an expansion config + let ecfg = ExpansionConfig::default(self.crate_name.take().unwrap()); + + // Generate a bunch of new items using the AllocFnFactory let mut f = AllocFnFactory { span, kind: AllocatorKind::Global, global: item.ident, - core: Ident::from_str("core"), + core: Ident::with_empty_ctxt(Symbol::gensym("core")), cx: ExtCtxt::new(self.sess, ecfg, self.resolver), }; - let super_path = f.cx.path(f.span, vec![Ident::from_str("super"), f.global]); - let mut items = vec![ - f.cx.item_extern_crate(f.span, f.core), - f.cx.item_use_simple( - f.span, - respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), - super_path, - ), - ]; - for method in ALLOCATOR_METHODS { - items.push(f.allocator_fn(method)); - } - let name = f.kind.fn_name("allocator_abi"); - let allocator_abi = Ident::with_empty_ctxt(Symbol::gensym(&name)); - let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); - let module = f.cx.monotonic_expander().fold_item(module).pop().unwrap(); + + let extcore = { + let extcore = f.cx.item_extern_crate(item.span, f.core); + f.cx.monotonic_expander().fold_item(extcore).pop().unwrap() + }; let mut ret = SmallVector::new(); ret.push(item); - ret.push(module); + ret.push(extcore); + ret.extend(ALLOCATOR_METHODS.iter().map(|method| { + let method = f.allocator_fn(method); + f.cx.monotonic_expander().fold_item(method).pop().unwrap() + })); return ret; } @@ -168,6 +173,7 @@ fn call_allocator(&self, method: &str, mut args: Vec>) -> P { let method = self.cx.path( self.span, vec![ + Ident::from_str("self"), self.core, Ident::from_str("alloc"), Ident::from_str("GlobalAlloc"), @@ -218,6 +224,7 @@ fn arg_ty( let layout_new = self.cx.path( self.span, vec![ + Ident::from_str("self"), self.core, Ident::from_str("alloc"), Ident::from_str("Layout"), diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c18a0892686..feeac9d938b 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1051,10 +1051,19 @@ pub fn phase_2_configure_and_expand_inner<'a, F>( }); } + // Expand global allocators, which are treated as an in-tree proc macro krate = time(sess, "creating allocators", || { - allocator::expand::modify(&sess.parse_sess, &mut resolver, krate, sess.diagnostic()) + allocator::expand::modify( + &sess.parse_sess, + &mut resolver, + krate, + crate_name.to_string(), + sess.diagnostic(), + ) }); + // Done with macro expansion! + after_expand(&krate)?; if sess.opts.debugging_opts.input_stats { diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs new file mode 100644 index 00000000000..b73068244b1 --- /dev/null +++ b/src/test/ui/allocator-submodule.rs @@ -0,0 +1,37 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests that it is possible to create a global allocator in a submodule, rather than in the crate +// root. + +#![feature(alloc, allocator_api, global_allocator)] + +extern crate alloc; + +use std::alloc::{GlobalAlloc, Layout, Opaque}; + +struct MyAlloc; + +unsafe impl GlobalAlloc for MyAlloc { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { + 0 as usize as *mut Opaque + } + + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {} +} + +mod submod { + use super::MyAlloc; + + #[global_allocator] + static MY_HEAP: MyAlloc = MyAlloc; +} + +fn main() {} -- 2.44.0