From 2a6a2a129b2eb26faedf19d24099c3f77a389148 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 22 Jun 2018 19:42:22 -0600 Subject: [PATCH 01/11] Do not build LLVM tools for any of the tools None of the tools in the list should need LLVM tools themselves as far as I can tell; if this is incorrect, we can re-enable the tool building later. The primary reason for doing this is that rust-central-station uses the BuildManifest tool and building LLVM there is not cached: it takes ~1.5 hours on the 2 core machine. This commit should make nightlies and stable releases much faster. --- src/bootstrap/tool.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 0c164d86332a8..0a428a61d1202 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -273,7 +273,7 @@ macro_rules! tool { /// Whether this tool requires LLVM to run pub fn uses_llvm_tools(&self) -> bool { match self { - $(Tool::$name => true $(&& $llvm)*,)+ + $(Tool::$name => false $(|| $llvm)*,)+ } } } @@ -340,9 +340,6 @@ macro_rules! tool { } } -// FIXME(#51459): We have only checked that RustInstaller does not require -// the LLVM binaries when running. We should go through all tools to determine -// if they really need LLVM binaries, and make `llvm_tools` a required argument. tool!( Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolRustc; ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::ToolRustc; @@ -350,10 +347,10 @@ tool!( Tidy, "src/tools/tidy", "tidy", Mode::ToolStd; Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolStd; CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolStd; - Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest; + Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest, llvm_tools = true; BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolStd; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolStd; - RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd, llvm_tools = false; + RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolStd; ); From d3edfb1d5e2b37e4ba2b2bd092de632f82e1059c Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 27 Jun 2018 18:24:24 +0200 Subject: [PATCH 02/11] Don't use `ParamEnv::reveal_all()` if there is a real one available --- src/librustc_mir/interpret/const_eval.rs | 2 +- .../ui/const-eval/ice-generic-assoc-const.rs | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/const-eval/ice-generic-assoc-const.rs diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 3fcf1b5c8ed59..592c9dbe6ffe4 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -76,7 +76,7 @@ pub fn value_to_const_value<'tcx>( val: Value, ty: Ty<'tcx>, ) -> &'tcx ty::Const<'tcx> { - let layout = ecx.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap(); + let layout = ecx.layout_of(ty).unwrap(); match (val, &layout.abi) { (Value::Scalar(Scalar::Bits { defined: 0, ..}), _) if layout.is_zst() => {}, (Value::ByRef(..), _) | diff --git a/src/test/ui/const-eval/ice-generic-assoc-const.rs b/src/test/ui/const-eval/ice-generic-assoc-const.rs new file mode 100644 index 0000000000000..31e056b66bce9 --- /dev/null +++ b/src/test/ui/const-eval/ice-generic-assoc-const.rs @@ -0,0 +1,28 @@ +// Copyright 2018 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. + +// compile-pass + +pub trait Nullable { + const NULL: Self; + + fn is_null(&self) -> bool; +} + +impl Nullable for *const T { + const NULL: Self = 0 as *const T; + + fn is_null(&self) -> bool { + *self == Self::NULL + } +} + +fn main() { +} From b81250f37ec3cb035ac60ecd9c615652187279a2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 21 Jun 2018 14:32:34 -0400 Subject: [PATCH 03/11] rename `pat_ty` to `pat_ty_adjusted` for clarity --- src/librustc/middle/mem_categorization.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 959dda69e30ed..2d3140a943b1c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -517,7 +517,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { /// implicit deref patterns attached (e.g., it is really /// `&Some(x)`). In that case, we return the "outermost" type /// (e.g., `&Option). - fn pat_ty(&self, pat: &hir::Pat) -> McResult> { + fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult> { // Check for implicit `&` types wrapping the pattern; note // that these are never attached to binding patterns, so // actually this is somewhat "disjoint" from the code below @@ -1300,7 +1300,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }; for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { - let subpat_ty = self.pat_ty(&subpat)?; // see (*2) + let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2) let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string()))); let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior)); self.cat_pattern_(subcmt, &subpat, op)?; @@ -1323,7 +1323,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }; for fp in field_pats { - let field_ty = self.pat_ty(&fp.node.pat)?; // see (*2) + let field_ty = self.pat_ty_adjusted(&fp.node.pat)?; // see (*2) let f_index = self.tcx.field_index(fp.node.id, self.tables); let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index, fp.node.ident, field_ty)); @@ -1342,7 +1342,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { - let subpat_ty = self.pat_ty(&subpat)?; // see (*2) + let subpat_ty = self.pat_ty_unadjusted(&subpat)?; // see (*2) let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string()))); let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior)); self.cat_pattern_(subcmt, &subpat, op)?; From 279a95fd21c66607b59759daa066b90fbd8b1eb0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 21 Jun 2018 14:32:52 -0400 Subject: [PATCH 04/11] use `pat_ty_adjusted` from `expr_use_visitor` to type of arguments --- src/librustc/middle/expr_use_visitor.rs | 3 ++- src/librustc/middle/mem_categorization.rs | 2 +- src/test/ui/borrowck/issue-51415.nll.stderr | 9 +++++++++ src/test/ui/borrowck/issue-51415.rs | 21 +++++++++++++++++++++ src/test/ui/borrowck/issue-51415.stderr | 12 ++++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/borrowck/issue-51415.nll.stderr create mode 100644 src/test/ui/borrowck/issue-51415.rs create mode 100644 src/test/ui/borrowck/issue-51415.stderr diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 9fb7d31ed6f75..8ef45a966da85 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -313,7 +313,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { debug!("consume_body(body={:?})", body); for arg in &body.arguments { - let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.hir_id)); + let arg_ty = return_if_err!(self.mc.pat_ty_adjusted(&arg.pat)); + debug!("consume_body: arg_ty = {:?}", arg_ty); let fn_body_scope_r = self.tcx().mk_region(ty::ReScope(region::Scope::Node(body.value.hir_id.local_id))); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 2d3140a943b1c..597872ef45de0 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -517,7 +517,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { /// implicit deref patterns attached (e.g., it is really /// `&Some(x)`). In that case, we return the "outermost" type /// (e.g., `&Option). - fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult> { + pub fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult> { // Check for implicit `&` types wrapping the pattern; note // that these are never attached to binding patterns, so // actually this is somewhat "disjoint" from the code below diff --git a/src/test/ui/borrowck/issue-51415.nll.stderr b/src/test/ui/borrowck/issue-51415.nll.stderr new file mode 100644 index 0000000000000..79454b635263c --- /dev/null +++ b/src/test/ui/borrowck/issue-51415.nll.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/issue-51415.rs:16:47 + | +LL | let opt = a.iter().enumerate().find(|(_, &s)| { + | ^ cannot move out of borrowed content + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/issue-51415.rs b/src/test/ui/borrowck/issue-51415.rs new file mode 100644 index 0000000000000..9067a50a8476d --- /dev/null +++ b/src/test/ui/borrowck/issue-51415.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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. + +// Regression test for #51415: match default bindings were failing to +// see the "move out" implied by `&s` below. + +fn main() { + let a = vec![String::from("a")]; + let opt = a.iter().enumerate().find(|(_, &s)| { + //~^ ERROR cannot move out + *s == String::from("d") + }).map(|(i, _)| i); + println!("{:?}", opt); +} diff --git a/src/test/ui/borrowck/issue-51415.stderr b/src/test/ui/borrowck/issue-51415.stderr new file mode 100644 index 0000000000000..b4b0bc7594305 --- /dev/null +++ b/src/test/ui/borrowck/issue-51415.stderr @@ -0,0 +1,12 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/issue-51415.rs:16:46 + | +LL | let opt = a.iter().enumerate().find(|(_, &s)| { + | ^- + | || + | |hint: to prevent move, use `ref s` or `ref mut s` + | cannot move out of borrowed content + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. From 5b172eb83b872314bbffa22c6eb649e6f019f218 Mon Sep 17 00:00:00 2001 From: Lireer Date: Thu, 28 Jun 2018 11:30:53 +0200 Subject: [PATCH 05/11] Remove process::id from 'Stabilized APIs' in 1.27 --- RELEASES.md | 1 - 1 file changed, 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 068e9e7263e7d..fba68ce043e26 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -56,7 +56,6 @@ Stabilized APIs - [`Take::set_limit`] - [`hint::unreachable_unchecked`] - [`os::unix::process::parent_id`] -- [`process::id`] - [`ptr::swap_nonoverlapping`] - [`slice::rsplit_mut`] - [`slice::rsplit`] From 103a4d8f18d37268854ae00c14d826db36c8b083 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 13 Apr 2018 15:58:16 -0500 Subject: [PATCH 06/11] 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 ec0676259ef20..928f3114c1f19 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 rustc_target::spec::abi::Abi; @@ -35,6 +37,7 @@ pub fn modify( sess: &ParseSess, resolver: &mut Resolver, krate: Crate, + crate_name: String, handler: &rustc_errors::Handler, ) -> ast::Crate { ExpandAllocatorDirectives { @@ -42,6 +45,7 @@ pub fn modify( sess, resolver, found: false, + crate_name: Some(crate_name), }.fold_crate(krate) } @@ -50,6 +54,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> { @@ -78,9 +83,10 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { } 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, callee: NameAndSpan { format: MacroAttribute(Symbol::intern(name)), span: None, @@ -89,35 +95,34 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { 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; } @@ -170,6 +175,7 @@ impl<'a> AllocFnFactory<'a> { let method = self.cx.path( self.span, vec![ + Ident::from_str("self"), self.core, Ident::from_str("alloc"), Ident::from_str("GlobalAlloc"), @@ -220,6 +226,7 @@ impl<'a> AllocFnFactory<'a> { 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 c18a089268659..feeac9d938b6a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1051,10 +1051,19 @@ where }); } + // 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 0000000000000..b73068244b10b --- /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() {} From 9e65155ab407a3fd27e01452469105e8b34c2ecf Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sun, 20 May 2018 17:04:00 -0500 Subject: [PATCH 07/11] Prohibit global_allocator in submodules for now - we need to figure out hygiene first - change the test to check that the prohibition works with a good error msg - leaves some comments and debugging code - leaves some of our supposed fixes --- src/Cargo.lock | 1 + src/librustc_allocator/Cargo.toml | 1 + src/librustc_allocator/expand.rs | 119 ++++++++++++++++--------- src/librustc_allocator/lib.rs | 1 + src/test/ui/allocator-submodule.rs | 2 +- src/test/ui/allocator-submodule.stderr | 8 ++ 6 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 src/test/ui/allocator-submodule.stderr diff --git a/src/Cargo.lock b/src/Cargo.lock index d4544ffa3244f..5c4d099f9c94c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2035,6 +2035,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "rustc_allocator" version = "0.0.0" dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_errors 0.0.0", "rustc_target 0.0.0", diff --git a/src/librustc_allocator/Cargo.toml b/src/librustc_allocator/Cargo.toml index 765cb80f35710..1cbde181cafae 100644 --- a/src/librustc_allocator/Cargo.toml +++ b/src/librustc_allocator/Cargo.toml @@ -14,3 +14,4 @@ rustc_errors = { path = "../librustc_errors" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } +log = "0.4" diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 928f3114c1f19..8bcf843640dfd 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -8,28 +8,31 @@ // 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 rustc_target::spec::abi::Abi; -use syntax::ast::{Attribute, Crate, LitKind, StrStyle}; -use syntax::ast::{Arg, Constness, Generics, Mac, Mutability, Ty, Unsafety}; -use syntax::ast::{self, Expr, Ident, Item, ItemKind, TyKind, VisibilityKind}; -use syntax::attr; -use syntax::codemap::{dummy_spanned, respan}; -use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan}; -use syntax::ext::base::ExtCtxt; -use syntax::ext::base::Resolver; -use syntax::ext::build::AstBuilder; -use syntax::ext::expand::ExpansionConfig; -use syntax::ext::hygiene::{self, Mark, SyntaxContext}; -use syntax::fold::{self, Folder}; -use syntax::parse::ParseSess; -use syntax::ptr::P; -use syntax::symbol::Symbol; -use syntax::util::small_vector::SmallVector; -use syntax_pos::{Span, DUMMY_SP}; +use syntax::{ + ast::{ + self, Arg, Attribute, Constness, Crate, Expr, Generics, Ident, Item, ItemKind, + LitKind, Mac, Mod, Mutability, StrStyle, Ty, TyKind, Unsafety, VisibilityKind, + }, + attr, + codemap::{ + dummy_spanned, respan, ExpnInfo, MacroAttribute, NameAndSpan, + }, + ext::{ + base::{ExtCtxt, Resolver}, + build::AstBuilder, + expand::ExpansionConfig, + hygiene::{self, Mark, SyntaxContext}, + }, + fold::{self, Folder}, + parse::ParseSess, + ptr::P, + symbol::Symbol, + util::small_vector::SmallVector, +}; +use syntax_pos::Span; use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; @@ -46,6 +49,7 @@ pub fn modify( resolver, found: false, crate_name: Some(crate_name), + in_submod: -1, // -1 to account for the "root" module }.fold_crate(krate) } @@ -55,10 +59,16 @@ struct ExpandAllocatorDirectives<'a> { sess: &'a ParseSess, resolver: &'a mut Resolver, crate_name: Option, + + // For now, we disallow `global_allocator` in submodules because hygiene is hard. Keep track of + // whether we are in a submodule or not. If `in_submod > 0` we are in a submodule. + in_submod: isize, } impl<'a> Folder for ExpandAllocatorDirectives<'a> { fn fold_item(&mut self, item: P) -> SmallVector> { + info!("in submodule {}", self.in_submod); + let name = if attr::contains_name(&item.attrs, "global_allocator") { "global_allocator" } else { @@ -73,12 +83,15 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { } } + if self.in_submod > 0 { + self.handler + .span_err(item.span, "`global_allocator` cannot be used in submodules"); + return SmallVector::one(item); + } + if self.found { - self.handler.span_err( - item.span, - "cannot define more than one \ - #[global_allocator]", - ); + self.handler + .span_err(item.span, "cannot define more than one #[global_allocator]"); return SmallVector::one(item); } self.found = true; @@ -86,7 +99,7 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { // 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: item.span, + call_site: item.span, // use the call site of the static callee: NameAndSpan { format: MacroAttribute(Symbol::intern(name)), span: None, @@ -107,27 +120,55 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { span, kind: AllocatorKind::Global, global: item.ident, - core: Ident::with_empty_ctxt(Symbol::gensym("core")), + core: Ident::from_str("core"), cx: ExtCtxt::new(self.sess, ecfg, self.resolver), }; - let extcore = { - let extcore = f.cx.item_extern_crate(item.span, f.core); - f.cx.monotonic_expander().fold_item(extcore).pop().unwrap() - }; + // We will generate a new submodule. To `use` the static from that module, we need to get + // the `super::...` path. + let super_path = f.cx.path(f.span, vec![Ident::from_str("super"), f.global]); + + // Generate the items in the submodule + let mut items = vec![ + // import `core` to use allocators + f.cx.item_extern_crate(f.span, f.core), + // `use` the `global_allocator` in `super` + f.cx.item_use_simple( + f.span, + respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), + super_path, + ), + ]; + + // Add the allocator methods to the submodule + items.extend( + ALLOCATOR_METHODS + .iter() + .map(|method| f.allocator_fn(method)), + ); - let mut ret = SmallVector::new(); + // Generate the submodule itself + 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(); + + // Return the item and new submodule + let mut ret = SmallVector::with_capacity(2); ret.push(item); - 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() - })); + ret.push(module); + return ret; } - fn fold_mac(&mut self, mac: Mac) -> Mac { - fold::noop_fold_mac(mac, self) + // If we enter a submodule, take note. + fn fold_mod(&mut self, m: Mod) -> Mod { + info!("enter submodule"); + self.in_submod += 1; + let ret = fold::noop_fold_mod(m, self); + self.in_submod -= 1; + info!("exit submodule"); + ret } } @@ -175,7 +216,6 @@ impl<'a> AllocFnFactory<'a> { let method = self.cx.path( self.span, vec![ - Ident::from_str("self"), self.core, Ident::from_str("alloc"), Ident::from_str("GlobalAlloc"), @@ -226,7 +266,6 @@ impl<'a> AllocFnFactory<'a> { 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_allocator/lib.rs b/src/librustc_allocator/lib.rs index 6595564fb30b5..b217d3665a245 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/librustc_allocator/lib.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] +#[macro_use] extern crate log; extern crate rustc; extern crate rustc_errors; extern crate rustc_target; diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs index b73068244b10b..40e5940c558db 100644 --- a/src/test/ui/allocator-submodule.rs +++ b/src/test/ui/allocator-submodule.rs @@ -31,7 +31,7 @@ mod submod { use super::MyAlloc; #[global_allocator] - static MY_HEAP: MyAlloc = MyAlloc; + static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator } fn main() {} diff --git a/src/test/ui/allocator-submodule.stderr b/src/test/ui/allocator-submodule.stderr new file mode 100644 index 0000000000000..6e7727f8889d4 --- /dev/null +++ b/src/test/ui/allocator-submodule.stderr @@ -0,0 +1,8 @@ +error: `global_allocator` cannot be used in submodules + --> $DIR/allocator-submodule.rs:34:5 + | +LL | static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 0f8f238ad569c812c6ba98798f3525173d99d95c Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 5 Jun 2018 19:24:10 -0500 Subject: [PATCH 08/11] enable fold_mac --- src/librustc_allocator/expand.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 8bcf843640dfd..f855a95f921c3 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -170,6 +170,11 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { info!("exit submodule"); ret } + + // `fold_mac` is disabled by default. Enable it here. + fn fold_mac(&mut self, mac: Mac) -> Mac { + fold::noop_fold_mac(mac, self) + } } struct AllocFnFactory<'a> { From 48bbbb09329de04a8885cdccd642cd20b9862d03 Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 18 Jun 2018 21:11:59 -0500 Subject: [PATCH 09/11] fix test --- src/test/ui/allocator-submodule.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs index 40e5940c558db..39b65766924f9 100644 --- a/src/test/ui/allocator-submodule.rs +++ b/src/test/ui/allocator-submodule.rs @@ -15,16 +15,19 @@ extern crate alloc; -use std::alloc::{GlobalAlloc, Layout, Opaque}; +use std::{ + alloc::{GlobalAlloc, Layout}, + ptr, +}; struct MyAlloc; unsafe impl GlobalAlloc for MyAlloc { - unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { - 0 as usize as *mut Opaque + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + ptr::null_mut() } - unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {} + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {} } mod submod { From fc709c6b2ac37ed8d6c63da1b671f82a16412d4b Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 18 Jun 2018 21:59:32 -0500 Subject: [PATCH 10/11] actually fix test --- src/test/ui/allocator-submodule.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/allocator-submodule.stderr b/src/test/ui/allocator-submodule.stderr index 6e7727f8889d4..06e0d36e8a2b1 100644 --- a/src/test/ui/allocator-submodule.stderr +++ b/src/test/ui/allocator-submodule.stderr @@ -1,5 +1,5 @@ error: `global_allocator` cannot be used in submodules - --> $DIR/allocator-submodule.rs:34:5 + --> $DIR/allocator-submodule.rs:37:5 | LL | static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 6164c6967574a3ba231f6193dba6901eeac7ab77 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 22 Jun 2018 19:59:29 -0500 Subject: [PATCH 11/11] used debug, not info --- src/librustc_allocator/expand.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index f855a95f921c3..3ef99c53705c5 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -67,7 +67,7 @@ struct ExpandAllocatorDirectives<'a> { impl<'a> Folder for ExpandAllocatorDirectives<'a> { fn fold_item(&mut self, item: P) -> SmallVector> { - info!("in submodule {}", self.in_submod); + debug!("in submodule {}", self.in_submod); let name = if attr::contains_name(&item.attrs, "global_allocator") { "global_allocator" @@ -163,11 +163,11 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { // If we enter a submodule, take note. fn fold_mod(&mut self, m: Mod) -> Mod { - info!("enter submodule"); + debug!("enter submodule"); self.in_submod += 1; let ret = fold::noop_fold_mod(m, self); self.in_submod -= 1; - info!("exit submodule"); + debug!("exit submodule"); ret }