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 9 pull requests #63341

Merged
merged 24 commits into from
Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6fae7f8
Wrap promoted generator fields in MaybeUninit
tmandry Jul 27, 2019
b12c20c
add a pair of whitespace after remove parentheses
bravomikekilo Jul 31, 2019
e64493e
add new test and add conditional whitespace
bravomikekilo Aug 2, 2019
4c1d892
fix tidy problem
bravomikekilo Aug 2, 2019
9d4ca87
Add niche-in-generator test
tmandry Aug 3, 2019
0a1bdd4
test .await while holding variables of different sizes
alsuren Aug 4, 2019
f40190a
test drop order for parameters when a future is dropped part-way thro…
alsuren Aug 5, 2019
7c374cf
don't ignore mir_dump folder
RalfJung Aug 5, 2019
f85fc71
PlaceRef's base is already a reference
spastorino Aug 5, 2019
ef0f490
Tests around moving parts of structs and tuples across await points
gorup Aug 5, 2019
48c7346
doc: the content has since been moved to the guide
tshepang Aug 6, 2019
3a95c71
Add rustfix test and fix test name.
bravomikekilo Aug 6, 2019
3882ed4
fixup! test drop order for parameters when a future is dropped part-w…
alsuren Aug 6, 2019
c4940e0
test drop order for locals when a future is dropped part-way through …
alsuren Aug 6, 2019
c22cc1d
Remove unnecessary features from compiler error code list
Aug 6, 2019
b40788e
Fix generator size regressions due to optimization
tmandry Jul 27, 2019
fb1f57e
Rollup merge of #63034 - tmandry:reduce-generator-size-regressions, r…
Centril Aug 6, 2019
fb79a74
Rollup merge of #63163 - bravomikekilo:master, r=cramertj
Centril Aug 6, 2019
7860cf4
Rollup merge of #63294 - alsuren:async-tests, r=cramertj
Centril Aug 6, 2019
3c76ab3
Rollup merge of #63307 - RalfJung:gitignore, r=alexcrichton
Centril Aug 6, 2019
f635ce5
Rollup merge of #63308 - spastorino:place-ref-base-is-ref, r=oli-obk
Centril Aug 6, 2019
051f94d
Rollup merge of #63310 - gorup:partial-moves, r=cramertj
Centril Aug 6, 2019
2c81d60
Rollup merge of #63314 - tshepang:update-src-readme, r=matthewjasper
Centril Aug 6, 2019
c8ea26e
Rollup merge of #63333 - jethrogb:jb/error-codes-features, r=Mark-Sim…
Centril Aug 6, 2019
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: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ config.mk
config.stamp
keywords.md
lexer.ml
mir_dump
Session.vim
src/etc/dl
tmp.*.rs
Expand Down
7 changes: 2 additions & 5 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ This directory contains the source code of the rust project, including:

For more information on how various parts of the compiler work, see the [rustc guide].

There is also useful content in the following READMEs, which are gradually being moved over to the guide:
- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query
- https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph
- https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked
- https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve
There is also useful content in this README:
https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve.

[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
2 changes: 2 additions & 0 deletions src/libcore/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ use crate::mem::ManuallyDrop;
/// guarantee may evolve.
#[allow(missing_debug_implementations)]
#[stable(feature = "maybe_uninit", since = "1.36.0")]
// Lang item so we can wrap other types in it. This is useful for generators.
#[cfg_attr(not(bootstrap), lang = "maybe_uninit")]
#[derive(Copy)]
#[repr(transparent)]
pub union MaybeUninit<T> {
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ language_item_table! {

ManuallyDropItem, "manually_drop", manually_drop, Target::Struct;

MaybeUninitLangItem, "maybe_uninit", maybe_uninit, Target::Union;

DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait;

// Align offset for stride != 1, must not panic.
Expand Down
21 changes: 16 additions & 5 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2347,18 +2347,17 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Foreign(def_id))
}

pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
let adt_def = self.adt_def(def_id);
let substs = InternalSubsts::for_item(self, def_id, |param, substs| {
fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
let adt_def = self.adt_def(wrapper_def_id);
let substs = InternalSubsts::for_item(self, wrapper_def_id, |param, substs| {
match param.kind {
GenericParamDefKind::Lifetime |
GenericParamDefKind::Const => {
bug!()
}
GenericParamDefKind::Type { has_default, .. } => {
if param.index == 0 {
ty.into()
ty_param.into()
} else {
assert!(has_default);
self.type_of(param.def_id).subst(self, substs).into()
Expand All @@ -2369,6 +2368,18 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Adt(adt_def, substs))
}

#[inline]
pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
self.mk_generic_adt(def_id, ty)
}

#[inline]
pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem);
self.mk_generic_adt(def_id, ty)
}

#[inline]
pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
self.mk_ty(RawPtr(tm))
Expand Down
28 changes: 23 additions & 5 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,27 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
}
}

// Count the number of variants in use. If only one of them, then it is
// impossible to overlap any locals in our layout. In this case it's
// always better to make the remaining locals ineligible, so we can
// lay them out with the other locals in the prefix and eliminate
// unnecessary padding bytes.
{
let mut used_variants = BitSet::new_empty(info.variant_fields.len());
for assignment in &assignments {
match assignment {
Assigned(idx) => { used_variants.insert(*idx); }
_ => {}
}
}
if used_variants.count() < 2 {
for assignment in assignments.iter_mut() {
*assignment = Ineligible(None);
}
ineligible_locals.insert_all();
}
}

// Write down the order of our locals that will be promoted to the prefix.
{
let mut idx = 0u32;
Expand Down Expand Up @@ -1406,24 +1427,21 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
Abi::Scalar(s) => s.clone(),
_ => bug!(),
};
// FIXME(eddyb) wrap each promoted type in `MaybeUninit` so that they
// don't poison the `largest_niche` or `abi` fields of `prefix`.
let promoted_layouts = ineligible_locals.iter()
.map(|local| subst_field(info.field_tys[local]))
.map(|ty| tcx.mk_maybe_uninit(ty))
.map(|ty| self.layout_of(ty));
let prefix_layouts = substs.prefix_tys(def_id, tcx)
.map(|ty| self.layout_of(ty))
.chain(iter::once(Ok(discr_layout)))
.chain(promoted_layouts)
.collect::<Result<Vec<_>, _>>()?;
let mut prefix = self.univariant_uninterned(
let prefix = self.univariant_uninterned(
ty,
&prefix_layouts,
&ReprOptions::default(),
StructKind::AlwaysSized,
)?;
// FIXME(eddyb) need `MaybeUninit` around promoted types (see above).
prefix.largest_niche = None;

let (prefix_size, prefix_align) = (prefix.size, prefix.align);

Expand Down
110 changes: 83 additions & 27 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use syntax::print::pprust;
use syntax::symbol::{kw, sym};
use syntax::symbol::Symbol;
use syntax::util::parser;
use syntax_pos::Span;
use syntax_pos::{Span, BytePos};

use rustc::hir;

Expand Down Expand Up @@ -353,31 +353,46 @@ declare_lint! {
declare_lint_pass!(UnusedParens => [UNUSED_PARENS]);

impl UnusedParens {

fn is_expr_parens_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool {
followed_by_block && match inner.node {
ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true,
_ => parser::contains_exterior_struct_lit(&inner),
}
}

fn check_unused_parens_expr(&self,
cx: &EarlyContext<'_>,
value: &ast::Expr,
msg: &str,
followed_by_block: bool) {
cx: &EarlyContext<'_>,
value: &ast::Expr,
msg: &str,
followed_by_block: bool,
left_pos: Option<BytePos>,
right_pos: Option<BytePos>) {
match value.node {
ast::ExprKind::Paren(ref inner) => {
let necessary = followed_by_block && match inner.node {
ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true,
_ => parser::contains_exterior_struct_lit(&inner),
};
if !necessary {
if !Self::is_expr_parens_necessary(inner, followed_by_block) {
let expr_text = if let Ok(snippet) = cx.sess().source_map()
.span_to_snippet(value.span) {
snippet
} else {
pprust::expr_to_string(value)
};
Self::remove_outer_parens(cx, value.span, &expr_text, msg);
let keep_space = (
left_pos.map(|s| s >= value.span.lo()).unwrap_or(false),
right_pos.map(|s| s <= value.span.hi()).unwrap_or(false),
);
Self::remove_outer_parens(cx, value.span, &expr_text, msg, keep_space);
}
}
ast::ExprKind::Let(_, ref expr) => {
// FIXME(#60336): Properly handle `let true = (false && true)`
// actually needing the parenthesis.
self.check_unused_parens_expr(cx, expr, "`let` head expression", followed_by_block);
self.check_unused_parens_expr(
cx, expr,
"`let` head expression",
followed_by_block,
None, None
);
}
_ => {}
}
Expand All @@ -394,11 +409,15 @@ impl UnusedParens {
} else {
pprust::pat_to_string(value)
};
Self::remove_outer_parens(cx, value.span, &pattern_text, msg);
Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false));
}
}

fn remove_outer_parens(cx: &EarlyContext<'_>, span: Span, pattern: &str, msg: &str) {
fn remove_outer_parens(cx: &EarlyContext<'_>,
span: Span,
pattern: &str,
msg: &str,
keep_space: (bool, bool)) {
let span_msg = format!("unnecessary parentheses around {}", msg);
let mut err = cx.struct_span_lint(UNUSED_PARENS, span, &span_msg);
let mut ate_left_paren = false;
Expand All @@ -424,11 +443,27 @@ impl UnusedParens {
},
_ => false,
}
}).to_owned();
});

let replace = {
let mut replace = if keep_space.0 {
let mut s = String::from(" ");
s.push_str(parens_removed);
s
} else {
String::from(parens_removed)
};

if keep_space.1 {
replace.push(' ');
}
replace
};

err.span_suggestion_short(
span,
"remove these parentheses",
parens_removed,
replace,
Applicability::MachineApplicable,
);
err.emit();
Expand All @@ -438,14 +473,35 @@ impl UnusedParens {
impl EarlyLintPass for UnusedParens {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
use syntax::ast::ExprKind::*;
let (value, msg, followed_by_block) = match e.node {
If(ref cond, ..) => (cond, "`if` condition", true),
While(ref cond, ..) => (cond, "`while` condition", true),
ForLoop(_, ref cond, ..) => (cond, "`for` head expression", true),
Match(ref head, _) => (head, "`match` head expression", true),
Ret(Some(ref value)) => (value, "`return` value", false),
Assign(_, ref value) => (value, "assigned value", false),
AssignOp(.., ref value) => (value, "assigned value", false),
let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
If(ref cond, ref block, ..) => {
let left = e.span.lo() + syntax_pos::BytePos(2);
let right = block.span.lo();
(cond, "`if` condition", true, Some(left), Some(right))
}

While(ref cond, ref block, ..) => {
let left = e.span.lo() + syntax_pos::BytePos(5);
let right = block.span.lo();
(cond, "`while` condition", true, Some(left), Some(right))
},

ForLoop(_, ref cond, ref block, ..) => {
(cond, "`for` head expression", true, None, Some(block.span.lo()))
}

Match(ref head, _) => {
let left = e.span.lo() + syntax_pos::BytePos(5);
(head, "`match` head expression", true, Some(left), None)
}

Ret(Some(ref value)) => {
let left = e.span.lo() + syntax_pos::BytePos(3);
(value, "`return` value", false, Some(left), None)
}

Assign(_, ref value) => (value, "assigned value", false, None, None),
AssignOp(.., ref value) => (value, "assigned value", false, None, None),
// either function/method call, or something this lint doesn't care about
ref call_or_other => {
let (args_to_check, call_kind) = match *call_or_other {
Expand All @@ -467,12 +523,12 @@ impl EarlyLintPass for UnusedParens {
}
let msg = format!("{} argument", call_kind);
for arg in args_to_check {
self.check_unused_parens_expr(cx, arg, &msg, false);
self.check_unused_parens_expr(cx, arg, &msg, false, None, None);
}
return;
}
};
self.check_unused_parens_expr(cx, &value, msg, followed_by_block);
self.check_unused_parens_expr(cx, &value, msg, followed_by_block, left_pos, right_pos);
}

fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
Expand All @@ -492,7 +548,7 @@ impl EarlyLintPass for UnusedParens {
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
if let ast::StmtKind::Local(ref local) = s.node {
if let Some(ref value) = local.init {
self.check_unused_parens_expr(cx, &value, "assigned value", false);
self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
}
}
}
Expand Down
Loading