Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
591584e
Add tests for 'impl Default for [T; N]'
MikailBag May 26, 2020
3313bf6
Skip leak test on targets without panic=unwind
MikailBag May 28, 2020
5837518
`-Zunpretty=everybody_loops` only works after expansion
ecstatic-morse Jun 7, 2020
d684855
Helper method for whether `ast::Ty` contains `impl Trait`
ecstatic-morse Jun 7, 2020
b5fdbbe
Use correct names for things in `ReplaceBodyWithLoops`
ecstatic-morse Jun 7, 2020
d8c99f3
Preserve expressions that get a `DefId`
ecstatic-morse Jun 7, 2020
1a30042
Remove unnecessary `opt_local_def_id_to_hir_id`
ecstatic-morse Jun 7, 2020
e319f20
Add `rustdoc` tests from #72088
ecstatic-morse Jun 7, 2020
bbb3321
Ensure std benchmarks get tested.
ehuss Jun 8, 2020
0687b78
Speed up bootstrap a little.
ehuss Jun 13, 2020
561107c
Ignore overflow when finding auto-trait impls in Rustdoc
Aaron1011 Jun 14, 2020
4004bf1
Don't run generator transform when there's a TyErr
jonas-schievink Jun 14, 2020
607e851
Switch bootstrap metadata to --no-deps.
ehuss Jun 14, 2020
c2b920f
Show suite paths (`src/test/ui/...`) in help output.
ehuss Jun 14, 2020
f17fd7b
Add some doc comments regarding PathSet.
ehuss Jun 15, 2020
c0c3327
Check for overflow in DroplessArena and return aligned pointer
tmiasko Jun 11, 2020
1f08951
Avoid forming references to an uninitialized memory in DroplessArena
tmiasko Jun 14, 2020
f62903b
Export `#[inline] #[no_mangle]` fns in cdylibs and staticlibs
cofibrant Jun 5, 2020
6b7cacb
Export all fns with extern indicator
cofibrant Jun 8, 2020
d23bedd
Fix whitespace
cofibrant Jun 8, 2020
ee810a7
Fix exports with `#[inline(always)]`
cofibrant Jun 9, 2020
11b56fb
Fix whitespace
cofibrant Jun 9, 2020
babda94
Fix sanitizer test
cofibrant Jun 15, 2020
e8e0a0e
Update sanitizer test
cofibrant Jun 15, 2020
64a6de2
Join mutiple lines if it is more readable
tesuji Jun 15, 2020
9e51008
Complete the std::time documentation to warn about the inconsistencie…
poliorcetics Jun 15, 2020
b67bdb5
Re-order correctly the sections in the sidebar
GuillaumeGomez Jun 15, 2020
fe7456c
Use track caller for bug! macro
tesuji Jun 15, 2020
e857696
Tweak "non-primitive cast" error
estebank Jun 15, 2020
81c9094
Suggest substituting `'static` lifetime in impl/dyn `Trait + 'static`…
estebank May 29, 2020
4e90f17
When `'static` is explicit, suggest constraining argument with it
estebank May 30, 2020
921f35f
Reduce verbosity of suggestion message and mention lifetime in label
estebank May 30, 2020
e755889
Move overlapping span to a note
estebank May 30, 2020
bc15790
Tweak output for overlapping required/captured spans
estebank May 30, 2020
539e978
Tweak wording and add error code
estebank May 30, 2020
31ea589
review comments: wording
estebank Jun 1, 2020
10d9bf1
Use note for requirement source span
estebank Jun 2, 2020
34d8692
Register new eror code
estebank Jun 2, 2020
e31367d
small tweaks
estebank Jun 2, 2020
f7a1f97
Change E0758 to E0759 to avoid conflict with #72912
estebank Jun 3, 2020
bfe1434
fix rebase
estebank Jun 15, 2020
a4337cc
Use `LocalDefId` for import IDs in trait map
petrochenkov Jun 14, 2020
fc13fd0
typeck: Use `LocalDefId`s for the unused trait import set
petrochenkov Jun 15, 2020
9b18bbf
Rollup merge of #72628 - MikailBag:array-default-tests, r=shepmaster
Manishearth Jun 16, 2020
0521cf9
Rollup merge of #72804 - estebank:opaque-missing-lts-in-fn-2, r=nikom…
Manishearth Jun 16, 2020
809dd8e
Rollup merge of #72836 - poliorcetics:std-time-os-specificities, r=sh…
Manishearth Jun 16, 2020
3bbc4fd
Rollup merge of #73034 - doctorn:nomangle-inline-linkage, r=matthewja…
Manishearth Jun 16, 2020
be623f5
Rollup merge of #73103 - ecstatic-morse:replace-body-with-loop, r=pnk…
Manishearth Jun 16, 2020
d5dc79d
Rollup merge of #73142 - ehuss:std-benches, r=dtolnay
Manishearth Jun 16, 2020
6e5d03e
Rollup merge of #73237 - tmiasko:arena, r=nnethercote
Manishearth Jun 16, 2020
88a3b0e
Rollup merge of #73335 - Aaron1011:fix/rustdoc-overflow, r=estebank
Manishearth Jun 16, 2020
e1af5cb
Rollup merge of #73339 - jonas-schievink:unbug, r=estebank
Manishearth Jun 16, 2020
54c762f
Rollup merge of #73352 - ehuss:bootstrap-metadata, r=Mark-Simulacrum
Manishearth Jun 16, 2020
aa70ddd
Rollup merge of #73357 - petrochenkov:tmap, r=davidtwco
Manishearth Jun 16, 2020
f77b58b
Rollup merge of #73361 - estebank:non-primitive-cast, r=davidtwco
Manishearth Jun 16, 2020
6d14efc
Rollup merge of #73372 - GuillaumeGomez:re-order-sidebar-sections, r=…
Manishearth Jun 16, 2020
2973b63
Rollup merge of #73373 - lzutao:bug-trackcaller, r=Amanieu
Manishearth Jun 16, 2020
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
21 changes: 21 additions & 0 deletions src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub use UnsafeSource::*;
use crate::ptr::P;
use crate::token::{self, DelimToken};
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
use crate::visit::{walk_ty, Visitor};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
Expand Down Expand Up @@ -1795,6 +1796,26 @@ pub struct Ty {
pub span: Span,
}

impl Ty {
/// Returns `true` if the kind of this type or any types contained within are `impl Trait`.
pub fn contains_impl_trait(&self) -> bool {
struct ContainsImplTrait(bool);

impl<'ast> Visitor<'ast> for ContainsImplTrait {
fn visit_ty(&mut self, t: &'ast Ty) {
self.0 |= matches!(t.kind, TyKind::ImplTrait(..));
if !self.0 {
walk_ty(self, t);
}
}
}

let mut vis = ContainsImplTrait(false);
vis.visit_ty(self);
vis.0
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct BareFnTy {
pub unsafety: Unsafe,
Expand Down
211 changes: 122 additions & 89 deletions src/librustc_interface/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,97 +592,54 @@ pub fn build_output_filenames(
//
// [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401
pub struct ReplaceBodyWithLoop<'a, 'b> {
within_static_or_const: bool,
ignore_item: bool,
nested_blocks: Option<Vec<ast::Block>>,
resolver: &'a mut Resolver<'b>,
}

impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
pub fn new(resolver: &'a mut Resolver<'b>) -> ReplaceBodyWithLoop<'a, 'b> {
ReplaceBodyWithLoop { within_static_or_const: false, nested_blocks: None, resolver }
ReplaceBodyWithLoop { ignore_item: false, nested_blocks: None, resolver }
}

fn run<R, F: FnOnce(&mut Self) -> R>(&mut self, is_const: bool, action: F) -> R {
let old_const = mem::replace(&mut self.within_static_or_const, is_const);
fn run<R, F: FnOnce(&mut Self) -> R>(&mut self, ignore_item: bool, action: F) -> R {
let old_ignore_item = mem::replace(&mut self.ignore_item, ignore_item);
let old_blocks = self.nested_blocks.take();
let ret = action(self);
self.within_static_or_const = old_const;
self.ignore_item = old_ignore_item;
self.nested_blocks = old_blocks;
ret
}

fn should_ignore_fn(ret_ty: &ast::FnRetTy) -> bool {
if let ast::FnRetTy::Ty(ref ty) = ret_ty {
fn involves_impl_trait(ty: &ast::Ty) -> bool {
match ty.kind {
ast::TyKind::ImplTrait(..) => true,
ast::TyKind::Slice(ref subty)
| ast::TyKind::Array(ref subty, _)
| ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. })
| ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. })
| ast::TyKind::Paren(ref subty) => involves_impl_trait(subty),
ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()),
ast::TyKind::Path(_, ref path) => {
path.segments.iter().any(|seg| match seg.args.as_deref() {
None => false,
Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
data.args.iter().any(|arg| match arg {
ast::AngleBracketedArg::Arg(arg) => match arg {
ast::GenericArg::Type(ty) => involves_impl_trait(ty),
ast::GenericArg::Lifetime(_)
| ast::GenericArg::Const(_) => false,
},
ast::AngleBracketedArg::Constraint(c) => match c.kind {
ast::AssocTyConstraintKind::Bound { .. } => true,
ast::AssocTyConstraintKind::Equality { ref ty } => {
involves_impl_trait(ty)
}
},
})
}
Some(&ast::GenericArgs::Parenthesized(ref data)) => {
any_involves_impl_trait(data.inputs.iter())
|| ReplaceBodyWithLoop::should_ignore_fn(&data.output)
}
})
}
_ => false,
}
}

fn any_involves_impl_trait<'a, I: Iterator<Item = &'a P<ast::Ty>>>(mut it: I) -> bool {
it.any(|subty| involves_impl_trait(subty))
}

involves_impl_trait(ty)
} else {
false
}
fn should_ignore_fn(sig: &ast::FnSig) -> bool {
matches!(sig.header.constness, ast::Const::Yes(_))
|| matches!(&sig.decl.output, ast::FnRetTy::Ty(ty) if ty.contains_impl_trait())
}

fn is_sig_const(sig: &ast::FnSig) -> bool {
matches!(sig.header.constness, ast::Const::Yes(_))
|| ReplaceBodyWithLoop::should_ignore_fn(&sig.decl.output)
/// Keep some `Expr`s that are ultimately assigned `DefId`s. This keeps the `HirId` parent
/// mappings correct even after this pass runs.
fn should_preserve_expr(e: &ast::Expr) -> bool {
matches!(&e.kind, ast::ExprKind::Closure(..) | ast::ExprKind::Async(..))
}
}

impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
let is_const = match i {
let ignore_item = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
ast::ItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig),
ast::ItemKind::Fn(_, ref sig, _, _) => Self::should_ignore_fn(sig),
_ => false,
};
self.run(is_const, |s| noop_visit_item_kind(i, s))
self.run(ignore_item, |s| noop_visit_item_kind(i, s))
}

fn flat_map_trait_item(&mut self, i: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
let is_const = match i.kind {
let ignore_item = match i.kind {
ast::AssocItemKind::Const(..) => true,
ast::AssocItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig),
ast::AssocItemKind::Fn(_, ref sig, _, _) => Self::should_ignore_fn(sig),
_ => false,
};
self.run(is_const, |s| noop_flat_map_assoc_item(i, s))
self.run(ignore_item, |s| noop_flat_map_assoc_item(i, s))
}

fn flat_map_impl_item(&mut self, i: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
Expand All @@ -693,6 +650,75 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
self.run(true, |s| noop_visit_anon_const(c, s))
}

fn filter_map_expr(&mut self, mut e: P<ast::Expr>) -> Option<P<ast::Expr>> {
if self.ignore_item {
return noop_filter_map_expr(e, self);
}

if let ast::ExprKind::Closure(.., decl, expr, _) = &mut e.kind {
// Replacing a closure body and removing its callsites will break inference. Give
// all closures the signature `|| -> !` to work around this.
decl.inputs = vec![];
if let ast::FnRetTy::Default(_) = decl.output {
decl.output = ast::FnRetTy::Ty(P(ast::Ty {
id: self.resolver.next_node_id(),
span: rustc_span::DUMMY_SP,
kind: ast::TyKind::Never,
}));
}

// Replace `|| expr` with `|| { expr }` so that `visit_block` gets called on the
// closure body.
if !matches!(expr.kind, ast::ExprKind::Block(..)) {
let new_stmt = ast::Stmt {
kind: ast::StmtKind::Expr(expr.clone()),
id: self.resolver.next_node_id(),
span: expr.span,
};

let new_block = ast::Block {
stmts: vec![new_stmt],
rules: BlockCheckMode::Default,
id: self.resolver.next_node_id(),
span: expr.span,
};

expr.kind = ast::ExprKind::Block(P(new_block), None);
}
}

if Self::should_preserve_expr(&e) {
self.run(false, |s| noop_filter_map_expr(e, s))
} else {
noop_filter_map_expr(e, self)
}
}

fn flat_map_stmt(&mut self, s: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
if self.ignore_item {
return noop_flat_map_stmt(s, self);
}

let ast::Stmt { id, span, .. } = s;
match s.kind {
// Replace `let x = || {};` with `|| {};`
ast::StmtKind::Local(mut local) if local.init.is_some() => self
.filter_map_expr(local.init.take().unwrap())
.into_iter()
.map(|e| ast::Stmt { kind: ast::StmtKind::Semi(e), id, span })
.collect(),

// Replace `|| {}` with `|| {};`
ast::StmtKind::Expr(expr) => self
.filter_map_expr(expr)
.into_iter()
.map(|e| ast::Stmt { kind: ast::StmtKind::Semi(e), id, span })
.collect(),

_ => noop_flat_map_stmt(s, self),
}
}

fn visit_block(&mut self, b: &mut P<ast::Block>) {
fn stmt_to_block(
rules: ast::BlockCheckMode,
Expand Down Expand Up @@ -723,6 +749,11 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
}
}

if self.ignore_item {
noop_visit_block(b, self);
return;
}

let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver);
let loop_expr = P(ast::Expr {
kind: ast::ExprKind::Loop(P(empty_block), None),
Expand All @@ -738,39 +769,41 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
kind: ast::StmtKind::Expr(loop_expr),
};

if self.within_static_or_const {
noop_visit_block(b, self)
} else {
visit_clobber(b.deref_mut(), |b| {
let mut stmts = vec![];
for s in b.stmts {
let old_blocks = self.nested_blocks.replace(vec![]);
visit_clobber(b.deref_mut(), |b| {
let mut stmts = vec![];
for s in b.stmts {
let old_blocks = self.nested_blocks.replace(vec![]);

stmts.extend(self.flat_map_stmt(s).into_iter().filter(|s| {
s.is_item()
|| matches!(
&s.kind,
ast::StmtKind::Semi(expr) if Self::should_preserve_expr(expr)
)
}));

// we put a Some in there earlier with that replace(), so this is valid
let new_blocks = self.nested_blocks.take().unwrap();
self.nested_blocks = old_blocks;
stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver)));
}

stmts.extend(self.flat_map_stmt(s).into_iter().filter(|s| s.is_item()));
let mut new_block = ast::Block { stmts, ..b };

// we put a Some in there earlier with that replace(), so this is valid
let new_blocks = self.nested_blocks.take().unwrap();
self.nested_blocks = old_blocks;
stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver)));
if let Some(old_blocks) = self.nested_blocks.as_mut() {
//push our fresh block onto the cache and yield an empty block with `loop {}`
if !new_block.stmts.is_empty() {
old_blocks.push(new_block);
}

let mut new_block = ast::Block { stmts, ..b };

if let Some(old_blocks) = self.nested_blocks.as_mut() {
//push our fresh block onto the cache and yield an empty block with `loop {}`
if !new_block.stmts.is_empty() {
old_blocks.push(new_block);
}

stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver)
} else {
//push `loop {}` onto the end of our fresh block and yield that
new_block.stmts.push(loop_stmt);
stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver)
} else {
//push `loop {}` onto the end of our fresh block and yield that
new_block.stmts.push(loop_stmt);

new_block
}
})
}
new_block
}
})
}

// in general the pretty printer processes unexpanded code, so
Expand Down
7 changes: 2 additions & 5 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,11 +942,8 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
let macro_module_def_id =
ty::DefIdTree::parent(self.tcx, self.tcx.hir().local_def_id(md.hir_id).to_def_id())
.unwrap();
// FIXME(#71104) Should really be using just `as_local_hir_id` but
// some `DefId` do not seem to have a corresponding HirId.
let hir_id = macro_module_def_id
.as_local()
.and_then(|def_id| self.tcx.hir().opt_local_def_id_to_hir_id(def_id));
let hir_id =
macro_module_def_id.as_local().map(|def_id| self.tcx.hir().as_local_hir_id(def_id));
let mut module_id = match hir_id {
Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id,
// `module_id` doesn't correspond to a `mod`, return early (#63164, #65252).
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1954,9 +1954,11 @@ impl PpMode {
use PpMode::*;
use PpSourceMode::*;
match *self {
PpmSource(PpmNormal | PpmEveryBodyLoops | PpmIdentified) => false,
PpmSource(PpmNormal | PpmIdentified) => false,

PpmSource(PpmExpanded | PpmExpandedIdentified | PpmExpandedHygiene)
PpmSource(
PpmExpanded | PpmEveryBodyLoops | PpmExpandedIdentified | PpmExpandedHygiene,
)
| PpmHir(_)
| PpmHirTree(_)
| PpmMir
Expand Down
9 changes: 9 additions & 0 deletions src/test/rustdoc/macro-in-async-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Regression issue for rustdoc ICE encountered in PR #72088.
// edition:2018
#![feature(decl_macro)]

fn main() {
async {
macro m() {}
};
}
7 changes: 7 additions & 0 deletions src/test/rustdoc/macro-in-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ fn main() {
|| {
macro m() {}
};

let _ = || {
macro n() {}
};

let cond = true;
let _ = || if cond { macro n() {} } else { panic!() };
}