Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[beta] Rollup backports #51857

Merged
merged 11 commits into from
Jun 28, 2018
1 change: 0 additions & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`]
Expand Down
1 change: 1 addition & 0 deletions src/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
9 changes: 3 additions & 6 deletions src/bootstrap/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)*,)+
}
}
}
Expand Down Expand Up @@ -340,20 +340,17 @@ 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;
UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolStd;
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;
);

Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>).
fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
pub fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
// 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
Expand Down Expand Up @@ -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)?;
Expand All @@ -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));
Expand All @@ -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)?;
Expand Down
1 change: 1 addition & 0 deletions src/librustc_allocator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
107 changes: 79 additions & 28 deletions src/librustc_allocator/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,45 @@
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};

pub fn modify(
sess: &ParseSess,
resolver: &mut Resolver,
krate: Crate,
crate_name: String,
handler: &rustc_errors::Handler,
) -> ast::Crate {
ExpandAllocatorDirectives {
handler,
sess,
resolver,
found: false,
crate_name: Some(crate_name),
in_submod: -1, // -1 to account for the "root" module
}.fold_crate(krate)
}

Expand All @@ -50,10 +58,17 @@ struct ExpandAllocatorDirectives<'a> {
handler: &'a rustc_errors::Handler,
sess: &'a ParseSess,
resolver: &'a mut Resolver,
crate_name: Option<String>,

// 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<Item>) -> SmallVector<P<Item>> {
debug!("in submodule {}", self.in_submod);

let name = if attr::contains_name(&item.attrs, "global_allocator") {
"global_allocator"
} else {
Expand All @@ -68,19 +83,23 @@ 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;

// 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, // use the call site of the static
callee: NameAndSpan {
format: MacroAttribute(Symbol::intern(name)),
span: None,
Expand All @@ -89,38 +108,70 @@ 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"),
cx: ExtCtxt::new(self.sess, ecfg, self.resolver),
};

// 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,
),
];
for method in ALLOCATOR_METHODS {
items.push(f.allocator_fn(method));
}

// Add the allocator methods to the submodule
items.extend(
ALLOCATOR_METHODS
.iter()
.map(|method| f.allocator_fn(method)),
);

// 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();

let mut ret = SmallVector::new();
// Return the item and new submodule
let mut ret = SmallVector::with_capacity(2);
ret.push(item);
ret.push(module);

return ret;
}

// If we enter a submodule, take note.
fn fold_mod(&mut self, m: Mod) -> Mod {
debug!("enter submodule");
self.in_submod += 1;
let ret = fold::noop_fold_mod(m, self);
self.in_submod -= 1;
debug!("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)
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_allocator/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#![feature(rustc_private)]

#[macro_use] extern crate log;
extern crate rustc;
extern crate rustc_errors;
extern crate rustc_target;
Expand Down
11 changes: 10 additions & 1 deletion src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(..), _) |
Expand Down
40 changes: 40 additions & 0 deletions src/test/ui/allocator-submodule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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},
ptr,
};

struct MyAlloc;

unsafe impl GlobalAlloc for MyAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
ptr::null_mut()
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {}
}

mod submod {
use super::MyAlloc;

#[global_allocator]
static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator
}

fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/allocator-submodule.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: `global_allocator` cannot be used in submodules
--> $DIR/allocator-submodule.rs:37:5
|
LL | static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

9 changes: 9 additions & 0 deletions src/test/ui/borrowck/issue-51415.nll.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading