Skip to content

Commit 615c460

Browse files
committed
Auto merge of #63341 - Centril:rollup-hkhxahb, r=Centril
Rollup of 9 pull requests Successful merges: - #63034 (Fix generator size regressions due to optimization) - #63035 (Use MaybeUninit to produce more correct layouts) - #63163 (add a pair of whitespace after remove parentheses) - #63294 (tests for async/await drop order) - #63307 (don't ignore mir_dump folder) - #63308 (PlaceRef's base is already a reference) - #63310 (Tests around moving parts of structs and tuples across await points) - #63314 (doc: the content has since been moved to the guide) - #63333 (Remove unnecessary features from compiler error code list) Failed merges: r? @ghost
2 parents c326c2e + c8ea26e commit 615c460

26 files changed

+1599
-73
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ config.mk
5252
config.stamp
5353
keywords.md
5454
lexer.ml
55-
mir_dump
5655
Session.vim
5756
src/etc/dl
5857
tmp.*.rs

src/README.md

+2-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ This directory contains the source code of the rust project, including:
55

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

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

1411
[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html

src/libcore/mem/maybe_uninit.rs

+2
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ use crate::mem::ManuallyDrop;
209209
/// guarantee may evolve.
210210
#[allow(missing_debug_implementations)]
211211
#[stable(feature = "maybe_uninit", since = "1.36.0")]
212+
// Lang item so we can wrap other types in it. This is useful for generators.
213+
#[cfg_attr(not(bootstrap), lang = "maybe_uninit")]
212214
#[derive(Copy)]
213215
#[repr(transparent)]
214216
pub union MaybeUninit<T> {

src/librustc/middle/lang_items.rs

+2
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,8 @@ language_item_table! {
365365

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

368+
MaybeUninitLangItem, "maybe_uninit", maybe_uninit, Target::Union;
369+
368370
DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait;
369371

370372
// Align offset for stride != 1, must not panic.

src/librustc/ty/context.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -2347,18 +2347,17 @@ impl<'tcx> TyCtxt<'tcx> {
23472347
self.mk_ty(Foreign(def_id))
23482348
}
23492349

2350-
pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
2351-
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
2352-
let adt_def = self.adt_def(def_id);
2353-
let substs = InternalSubsts::for_item(self, def_id, |param, substs| {
2350+
fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
2351+
let adt_def = self.adt_def(wrapper_def_id);
2352+
let substs = InternalSubsts::for_item(self, wrapper_def_id, |param, substs| {
23542353
match param.kind {
23552354
GenericParamDefKind::Lifetime |
23562355
GenericParamDefKind::Const => {
23572356
bug!()
23582357
}
23592358
GenericParamDefKind::Type { has_default, .. } => {
23602359
if param.index == 0 {
2361-
ty.into()
2360+
ty_param.into()
23622361
} else {
23632362
assert!(has_default);
23642363
self.type_of(param.def_id).subst(self, substs).into()
@@ -2369,6 +2368,18 @@ impl<'tcx> TyCtxt<'tcx> {
23692368
self.mk_ty(Adt(adt_def, substs))
23702369
}
23712370

2371+
#[inline]
2372+
pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
2373+
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
2374+
self.mk_generic_adt(def_id, ty)
2375+
}
2376+
2377+
#[inline]
2378+
pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
2379+
let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem);
2380+
self.mk_generic_adt(def_id, ty)
2381+
}
2382+
23722383
#[inline]
23732384
pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
23742385
self.mk_ty(RawPtr(tm))

src/librustc/ty/layout.rs

+23-5
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,27 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
13681368
}
13691369
}
13701370

1371+
// Count the number of variants in use. If only one of them, then it is
1372+
// impossible to overlap any locals in our layout. In this case it's
1373+
// always better to make the remaining locals ineligible, so we can
1374+
// lay them out with the other locals in the prefix and eliminate
1375+
// unnecessary padding bytes.
1376+
{
1377+
let mut used_variants = BitSet::new_empty(info.variant_fields.len());
1378+
for assignment in &assignments {
1379+
match assignment {
1380+
Assigned(idx) => { used_variants.insert(*idx); }
1381+
_ => {}
1382+
}
1383+
}
1384+
if used_variants.count() < 2 {
1385+
for assignment in assignments.iter_mut() {
1386+
*assignment = Ineligible(None);
1387+
}
1388+
ineligible_locals.insert_all();
1389+
}
1390+
}
1391+
13711392
// Write down the order of our locals that will be promoted to the prefix.
13721393
{
13731394
let mut idx = 0u32;
@@ -1406,24 +1427,21 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14061427
Abi::Scalar(s) => s.clone(),
14071428
_ => bug!(),
14081429
};
1409-
// FIXME(eddyb) wrap each promoted type in `MaybeUninit` so that they
1410-
// don't poison the `largest_niche` or `abi` fields of `prefix`.
14111430
let promoted_layouts = ineligible_locals.iter()
14121431
.map(|local| subst_field(info.field_tys[local]))
1432+
.map(|ty| tcx.mk_maybe_uninit(ty))
14131433
.map(|ty| self.layout_of(ty));
14141434
let prefix_layouts = substs.prefix_tys(def_id, tcx)
14151435
.map(|ty| self.layout_of(ty))
14161436
.chain(iter::once(Ok(discr_layout)))
14171437
.chain(promoted_layouts)
14181438
.collect::<Result<Vec<_>, _>>()?;
1419-
let mut prefix = self.univariant_uninterned(
1439+
let prefix = self.univariant_uninterned(
14201440
ty,
14211441
&prefix_layouts,
14221442
&ReprOptions::default(),
14231443
StructKind::AlwaysSized,
14241444
)?;
1425-
// FIXME(eddyb) need `MaybeUninit` around promoted types (see above).
1426-
prefix.largest_niche = None;
14271445

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

src/librustc_lint/unused.rs

+83-27
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use syntax::print::pprust;
1515
use syntax::symbol::{kw, sym};
1616
use syntax::symbol::Symbol;
1717
use syntax::util::parser;
18-
use syntax_pos::Span;
18+
use syntax_pos::{Span, BytePos};
1919

2020
use rustc::hir;
2121

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

355355
impl UnusedParens {
356+
357+
fn is_expr_parens_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool {
358+
followed_by_block && match inner.node {
359+
ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true,
360+
_ => parser::contains_exterior_struct_lit(&inner),
361+
}
362+
}
363+
356364
fn check_unused_parens_expr(&self,
357-
cx: &EarlyContext<'_>,
358-
value: &ast::Expr,
359-
msg: &str,
360-
followed_by_block: bool) {
365+
cx: &EarlyContext<'_>,
366+
value: &ast::Expr,
367+
msg: &str,
368+
followed_by_block: bool,
369+
left_pos: Option<BytePos>,
370+
right_pos: Option<BytePos>) {
361371
match value.node {
362372
ast::ExprKind::Paren(ref inner) => {
363-
let necessary = followed_by_block && match inner.node {
364-
ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true,
365-
_ => parser::contains_exterior_struct_lit(&inner),
366-
};
367-
if !necessary {
373+
if !Self::is_expr_parens_necessary(inner, followed_by_block) {
368374
let expr_text = if let Ok(snippet) = cx.sess().source_map()
369375
.span_to_snippet(value.span) {
370376
snippet
371377
} else {
372378
pprust::expr_to_string(value)
373379
};
374-
Self::remove_outer_parens(cx, value.span, &expr_text, msg);
380+
let keep_space = (
381+
left_pos.map(|s| s >= value.span.lo()).unwrap_or(false),
382+
right_pos.map(|s| s <= value.span.hi()).unwrap_or(false),
383+
);
384+
Self::remove_outer_parens(cx, value.span, &expr_text, msg, keep_space);
375385
}
376386
}
377387
ast::ExprKind::Let(_, ref expr) => {
378388
// FIXME(#60336): Properly handle `let true = (false && true)`
379389
// actually needing the parenthesis.
380-
self.check_unused_parens_expr(cx, expr, "`let` head expression", followed_by_block);
390+
self.check_unused_parens_expr(
391+
cx, expr,
392+
"`let` head expression",
393+
followed_by_block,
394+
None, None
395+
);
381396
}
382397
_ => {}
383398
}
@@ -394,11 +409,15 @@ impl UnusedParens {
394409
} else {
395410
pprust::pat_to_string(value)
396411
};
397-
Self::remove_outer_parens(cx, value.span, &pattern_text, msg);
412+
Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false));
398413
}
399414
}
400415

401-
fn remove_outer_parens(cx: &EarlyContext<'_>, span: Span, pattern: &str, msg: &str) {
416+
fn remove_outer_parens(cx: &EarlyContext<'_>,
417+
span: Span,
418+
pattern: &str,
419+
msg: &str,
420+
keep_space: (bool, bool)) {
402421
let span_msg = format!("unnecessary parentheses around {}", msg);
403422
let mut err = cx.struct_span_lint(UNUSED_PARENS, span, &span_msg);
404423
let mut ate_left_paren = false;
@@ -424,11 +443,27 @@ impl UnusedParens {
424443
},
425444
_ => false,
426445
}
427-
}).to_owned();
446+
});
447+
448+
let replace = {
449+
let mut replace = if keep_space.0 {
450+
let mut s = String::from(" ");
451+
s.push_str(parens_removed);
452+
s
453+
} else {
454+
String::from(parens_removed)
455+
};
456+
457+
if keep_space.1 {
458+
replace.push(' ');
459+
}
460+
replace
461+
};
462+
428463
err.span_suggestion_short(
429464
span,
430465
"remove these parentheses",
431-
parens_removed,
466+
replace,
432467
Applicability::MachineApplicable,
433468
);
434469
err.emit();
@@ -438,14 +473,35 @@ impl UnusedParens {
438473
impl EarlyLintPass for UnusedParens {
439474
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
440475
use syntax::ast::ExprKind::*;
441-
let (value, msg, followed_by_block) = match e.node {
442-
If(ref cond, ..) => (cond, "`if` condition", true),
443-
While(ref cond, ..) => (cond, "`while` condition", true),
444-
ForLoop(_, ref cond, ..) => (cond, "`for` head expression", true),
445-
Match(ref head, _) => (head, "`match` head expression", true),
446-
Ret(Some(ref value)) => (value, "`return` value", false),
447-
Assign(_, ref value) => (value, "assigned value", false),
448-
AssignOp(.., ref value) => (value, "assigned value", false),
476+
let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
477+
If(ref cond, ref block, ..) => {
478+
let left = e.span.lo() + syntax_pos::BytePos(2);
479+
let right = block.span.lo();
480+
(cond, "`if` condition", true, Some(left), Some(right))
481+
}
482+
483+
While(ref cond, ref block, ..) => {
484+
let left = e.span.lo() + syntax_pos::BytePos(5);
485+
let right = block.span.lo();
486+
(cond, "`while` condition", true, Some(left), Some(right))
487+
},
488+
489+
ForLoop(_, ref cond, ref block, ..) => {
490+
(cond, "`for` head expression", true, None, Some(block.span.lo()))
491+
}
492+
493+
Match(ref head, _) => {
494+
let left = e.span.lo() + syntax_pos::BytePos(5);
495+
(head, "`match` head expression", true, Some(left), None)
496+
}
497+
498+
Ret(Some(ref value)) => {
499+
let left = e.span.lo() + syntax_pos::BytePos(3);
500+
(value, "`return` value", false, Some(left), None)
501+
}
502+
503+
Assign(_, ref value) => (value, "assigned value", false, None, None),
504+
AssignOp(.., ref value) => (value, "assigned value", false, None, None),
449505
// either function/method call, or something this lint doesn't care about
450506
ref call_or_other => {
451507
let (args_to_check, call_kind) = match *call_or_other {
@@ -467,12 +523,12 @@ impl EarlyLintPass for UnusedParens {
467523
}
468524
let msg = format!("{} argument", call_kind);
469525
for arg in args_to_check {
470-
self.check_unused_parens_expr(cx, arg, &msg, false);
526+
self.check_unused_parens_expr(cx, arg, &msg, false, None, None);
471527
}
472528
return;
473529
}
474530
};
475-
self.check_unused_parens_expr(cx, &value, msg, followed_by_block);
531+
self.check_unused_parens_expr(cx, &value, msg, followed_by_block, left_pos, right_pos);
476532
}
477533

478534
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
@@ -492,7 +548,7 @@ impl EarlyLintPass for UnusedParens {
492548
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
493549
if let ast::StmtKind::Local(ref local) = s.node {
494550
if let Some(ref value) = local.init {
495-
self.check_unused_parens_expr(cx, &value, "assigned value", false);
551+
self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
496552
}
497553
}
498554
}

0 commit comments

Comments
 (0)