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

Rollup of 10 pull requests #57075

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e38e954
Simplify MIR generation for logical ops
sinkuu Dec 17, 2018
f731445
Mark tuple structs as live if their constructors are used
oli-obk Dec 18, 2018
c2402dc
Replace "native pointer" in error message with "raw pointer"
varkor Dec 18, 2018
d6969ac
Fix string for raw pointer deref suggestion
varkor Dec 18, 2018
0309874
Fix string for array access suggestion
varkor Dec 18, 2018
e7c5146
Remove `TokenStream::JointTree`.
nnethercote Dec 19, 2018
405d8b0
Copyrite
oli-obk Dec 20, 2018
59f643f
Point to return span when writing `return;` on non-() fn
estebank Dec 20, 2018
cdbccf5
Point at coercion source on type errors for fn returning `impl Trait`
estebank Dec 21, 2018
f8e508c
Fix a recently introduces regression
oli-obk Dec 17, 2018
b9d74fc
Also test projections
oli-obk Dec 17, 2018
3414be0
fix deprecation warnings in liballoc benches
RalfJung Dec 21, 2018
6ed596e
Update tests to changes on master
oli-obk Dec 21, 2018
097d39d
Fix alignment for array indexing
nikic Dec 21, 2018
3986c96
enum type instead of variant suggestion unification
zackmdavis Nov 19, 2018
64ad3e2
adjust enum type instead of variant suggestions for prelude enums
zackmdavis Nov 23, 2018
2820dc8
Remove dead code
estebank Dec 23, 2018
b42a3ac
stabilize min_const_unsafe_fn in 1.33.
Centril Dec 22, 2018
bd1d5bc
stabilize min_const_unsafe_fn --bless tests.
Centril Dec 22, 2018
7ae6fb2
stabilize min_const_unsafe_fn -- revert const-size_of-cycle changes
Centril Dec 22, 2018
cd93b16
Rollup merge of #56188 - zackmdavis:if_i_may_suggest, r=davidtwco
Centril Dec 23, 2018
d9bad38
Rollup merge of #56916 - oli-obk:static_mut_beta_regression, r=davidtwco
Centril Dec 23, 2018
6fa0b0a
Rollup merge of #56917 - sinkuu:mir_build_logicop, r=davidtwco
Centril Dec 23, 2018
99f4ce2
Rollup merge of #56953 - oli-obk:dead_const, r=petrochenkov
Centril Dec 23, 2018
3a5e4da
Rollup merge of #56964 - nnethercote:TokenStream-IsJoint, r=petrochenkov
Centril Dec 23, 2018
d875fcd
Rollup merge of #56966 - varkor:raw-pointer-deref-parens, r=zackmdavis
Centril Dec 23, 2018
174dfb8
Rollup merge of #57020 - estebank:return-span, r=zackmdavis
Centril Dec 23, 2018
ee1c818
Rollup merge of #57032 - RalfJung:alloc-bench-deprecations, r=Centril
Centril Dec 23, 2018
841af07
Rollup merge of #57053 - nikic:fix-gep-align, r=nagisa
Centril Dec 23, 2018
24a5335
Rollup merge of #57067 - Centril:stabilize-min_const_unsafe_fn, r=oli…
Centril Dec 23, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies = [
"compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }

[dev-dependencies]
rand = "0.6"
rand_xorshift = "0.1"

[[test]]
name = "collectionstests"
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/benches/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use std::iter::Iterator;
use std::vec::Vec;
use std::collections::BTreeMap;
use rand::{Rng, thread_rng};
use rand::{Rng, seq::SliceRandom, thread_rng};
use test::{Bencher, black_box};

macro_rules! map_insert_rand_bench {
Expand Down Expand Up @@ -78,7 +78,7 @@ macro_rules! map_find_rand_bench {
map.insert(k, k);
}

rng.shuffle(&mut keys);
keys.shuffle(&mut rng);

// measure
let mut i = 0;
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#![feature(test)]

extern crate rand;
extern crate rand_xorshift;
extern crate test;

mod btree;
Expand Down
3 changes: 2 additions & 1 deletion src/liballoc/benches/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use rand::{thread_rng};
use std::mem;
use std::ptr;

use rand::{Rng, SeedableRng, XorShiftRng};
use rand::{Rng, SeedableRng};
use rand::distributions::{Standard, Alphanumeric};
use rand_xorshift::XorShiftRng;
use test::{Bencher, black_box};

#[bench]
Expand Down
8 changes: 4 additions & 4 deletions src/liballoc/benches/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,11 @@ make_test!(split_a_str, s, s.split("a").count());
make_test!(trim_ascii_char, s, {
s.trim_matches(|c: char| c.is_ascii())
});
make_test!(trim_left_ascii_char, s, {
s.trim_left_matches(|c: char| c.is_ascii())
make_test!(trim_start_ascii_char, s, {
s.trim_start_matches(|c: char| c.is_ascii())
});
make_test!(trim_right_ascii_char, s, {
s.trim_right_matches(|c: char| c.is_ascii())
make_test!(trim_end_ascii_char, s, {
s.trim_end_matches(|c: char| c.is_ascii())
});

make_test!(find_underscore_char, s, s.find('_'));
Expand Down
11 changes: 10 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1979,6 +1979,15 @@ pub enum FunctionRetTy {
Return(P<Ty>),
}

impl fmt::Display for FunctionRetTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Return(ref ty) => print::to_string(print::NO_ANN, |s| s.print_type(ty)).fmt(f),
DefaultReturn(_) => "()".fmt(f),
}
}
}

impl FunctionRetTy {
pub fn span(&self) -> Span {
match *self {
Expand Down Expand Up @@ -2119,7 +2128,7 @@ impl StructField {
/// Id of the whole enum lives in `Item`.
///
/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
/// used for `Struct`-structs (but still present). Structures don't have an analogue of "Id of
/// the variant itself" from enum variants.
/// Id of the whole struct lives in `Item`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
Expand Down
1 change: 0 additions & 1 deletion src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ impl_stable_hash_for!(enum mir::BorrowKind {
impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
General,
GeneralAndConstFn,
GatedConstFnCall,
ExternStatic(lint_node_id),
BorrowPacked(lint_node_id),
});
Expand Down
80 changes: 38 additions & 42 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use middle::privacy;
use ty::{self, TyCtxt};
use util::nodemap::FxHashSet;

use rustc_data_structures::fx::FxHashMap;

use syntax::{ast, source_map};
use syntax::attr;
use syntax_pos;
Expand Down Expand Up @@ -55,12 +57,15 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
in_pat: bool,
inherited_pub_visibility: bool,
ignore_variant_stack: Vec<DefId>,
// maps from tuple struct constructors to tuple struct items
struct_constructors: FxHashMap<ast::NodeId, ast::NodeId>,
}

impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn check_def_id(&mut self, def_id: DefId) {
if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
if should_explore(self.tcx, node_id) {
if should_explore(self.tcx, node_id) ||
self.struct_constructors.contains_key(&node_id) {
self.worklist.push(node_id);
}
self.live_symbols.insert(node_id);
Expand Down Expand Up @@ -137,19 +142,23 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
continue
}

if let Some(ref node) = self.tcx.hir().find(id) {
// in the case of tuple struct constructors we want to check the item, not the generated
// tuple struct constructor function
let id = self.struct_constructors.get(&id).cloned().unwrap_or(id);

if let Some(node) = self.tcx.hir().find(id) {
self.live_symbols.insert(id);
self.visit_node(node);
}
}
}

fn visit_node(&mut self, node: &Node<'tcx>) {
fn visit_node(&mut self, node: Node<'tcx>) {
let had_repr_c = self.repr_has_repr_c;
self.repr_has_repr_c = false;
let had_inherited_pub_visibility = self.inherited_pub_visibility;
self.inherited_pub_visibility = false;
match *node {
match node {
Node::Item(item) => {
match item.node {
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
Expand Down Expand Up @@ -337,6 +346,8 @@ struct LifeSeeder<'k, 'tcx: 'k> {
worklist: Vec<ast::NodeId>,
krate: &'k hir::Crate,
tcx: TyCtxt<'k, 'tcx, 'tcx>,
// see `MarkSymbolVisitor::struct_constructors`
struct_constructors: FxHashMap<ast::NodeId, ast::NodeId>,
}

impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
Expand Down Expand Up @@ -379,6 +390,9 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
}
}
}
hir::ItemKind::Struct(ref variant_data, _) => {
self.struct_constructors.insert(variant_data.id(), item.id);
}
_ => ()
}
}
Expand All @@ -392,11 +406,11 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
}
}

fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &privacy::AccessLevels,
krate: &hir::Crate)
-> Vec<ast::NodeId>
{
fn create_and_seed_worklist<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &privacy::AccessLevels,
krate: &hir::Crate,
) -> (Vec<ast::NodeId>, FxHashMap<ast::NodeId, ast::NodeId>) {
let worklist = access_levels.map.iter().filter_map(|(&id, level)| {
if level >= &privacy::AccessLevel::Reachable {
Some(id)
Expand All @@ -413,17 +427,18 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
worklist,
krate,
tcx,
struct_constructors: Default::default(),
};
krate.visit_all_item_likes(&mut life_seeder);

return life_seeder.worklist;
(life_seeder.worklist, life_seeder.struct_constructors)
}

fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &privacy::AccessLevels,
krate: &hir::Crate)
-> FxHashSet<ast::NodeId> {
let worklist = create_and_seed_worklist(tcx, access_levels, krate);
let (worklist, struct_constructors) = create_and_seed_worklist(tcx, access_levels, krate);
let mut symbol_visitor = MarkSymbolVisitor {
worklist,
tcx,
Expand All @@ -433,20 +448,12 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
in_pat: false,
inherited_pub_visibility: false,
ignore_variant_stack: vec![],
struct_constructors,
};
symbol_visitor.mark_live_symbols();
symbol_visitor.live_symbols
}

fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
match item.node {
hir::ItemKind::Struct(ref struct_def, _) if !struct_def.is_struct() => {
Some(struct_def.id())
}
_ => None
}
}

struct DeadVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
live_symbols: FxHashSet<ast::NodeId>,
Expand All @@ -464,46 +471,35 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
| hir::ItemKind::Union(..) => true,
_ => false
};
let ctor_id = get_struct_ctor_id(item);
should_warn && !self.symbol_is_live(item.id, ctor_id)
should_warn && !self.symbol_is_live(item.id)
}

fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
!field.is_positional()
&& !self.symbol_is_live(field.id, None)
&& !self.symbol_is_live(field.id)
&& !field_type.is_phantom_data()
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.id, &field.attrs)
}

fn should_warn_about_variant(&mut self, variant: &hir::VariantKind) -> bool {
!self.symbol_is_live(variant.data.id(), None)
!self.symbol_is_live(variant.data.id())
&& !has_allow_dead_code_or_lang_attr(self.tcx,
variant.data.id(),
&variant.attrs)
}

fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem) -> bool {
!self.symbol_is_live(fi.id, None)
!self.symbol_is_live(fi.id)
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.id, &fi.attrs)
}

// id := node id of an item's definition.
// ctor_id := `Some` if the item is a struct_ctor (tuple struct),
// `None` otherwise.
// If the item is a struct_ctor, then either its `id` or
// `ctor_id` (unwrapped) is in the live_symbols set. More specifically,
// DefMap maps the ExprKind::Path of a struct_ctor to the node referred by
// `ctor_id`. On the other hand, in a statement like
// `type <ident> <generics> = <ty>;` where <ty> refers to a struct_ctor,
// DefMap maps <ty> to `id` instead.
fn symbol_is_live(&mut self,
id: ast::NodeId,
ctor_id: Option<ast::NodeId>)
-> bool {
if self.live_symbols.contains(&id)
|| ctor_id.map_or(false, |ctor| self.live_symbols.contains(&ctor))
{
fn symbol_is_live(
&mut self,
id: ast::NodeId,
) -> bool {
if self.live_symbols.contains(&id) {
return true;
}
// If it's a type whose items are live, then it's live, too.
Expand Down Expand Up @@ -611,7 +607,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
match impl_item.node {
hir::ImplItemKind::Const(_, body_id) => {
if !self.symbol_is_live(impl_item.id, None) {
if !self.symbol_is_live(impl_item.id) {
self.warn_dead_code(impl_item.id,
impl_item.span,
impl_item.ident.name,
Expand All @@ -621,7 +617,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
self.visit_nested_body(body_id)
}
hir::ImplItemKind::Method(_, body_id) => {
if !self.symbol_is_live(impl_item.id, None) {
if !self.symbol_is_live(impl_item.id) {
let span = self.tcx.sess.source_map().def_span(impl_item.span);
self.warn_dead_code(impl_item.id, span, impl_item.ident.name, "method", "used");
}
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2792,9 +2792,6 @@ impl Location {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum UnsafetyViolationKind {
General,
/// Right now function calls to `const unsafe fn` are only permitted behind a feature gate
/// Also, even `const unsafe fn` need an `unsafe` block to do the allowed operations.
GatedConstFnCall,
/// Permitted in const fn and regular fns
GeneralAndConstFn,
ExternStatic(ast::NodeId),
Expand Down
13 changes: 11 additions & 2 deletions src/librustc_codegen_ssa/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,20 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
bx: &mut Bx,
llindex: V
) -> Self {
// Statically compute the offset if we can, otherwise just use the element size,
// as this will yield the lowest alignment.
let layout = self.layout.field(bx, 0);
let offset = if bx.is_const_integral(llindex) {
layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
} else {
layout.size
};

PlaceRef {
llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]),
llextra: None,
layout: self.layout.field(bx.cx(), 0),
align: self.align
layout,
align: self.align.restrict_for_offset(offset),
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_codegen_ssa/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());

let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size);
cg_elem.val.store(&mut body_bx,
PlaceRef::new_sized(current, cg_elem.layout, dest.align));
PlaceRef::new_sized(current, cg_elem.layout, align));

let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]);
body_bx.br(header_bx.llbb());
Expand Down
Loading