Skip to content

Commit

Permalink
Auto merge of rust-lang#71367 - Dylan-DPC:rollup-ysj4olr, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 4 pull requests

Successful merges:

 - rust-lang#69362 (Stabilize most common subset of alloc_layout_extras)
 - rust-lang#71174 (Check that main/start is not async)
 - rust-lang#71285 (MIR: use HirId instead of NodeId to avoid cycles while inlining)
 - rust-lang#71346 (Do not build tools if user do not want them)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Apr 21, 2020
2 parents 20fc02f + 9a0e702 commit 073744f
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 35 deletions.
10 changes: 9 additions & 1 deletion src/bootstrap/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,15 @@ macro_rules! tool_extended {

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
run.path($path).default_condition(builder.config.extended)
run.path($path).default_condition(
builder.config.extended
&& builder.config.tools.as_ref().map_or(true, |tools| {
tools.iter().any(|tool| match tool.as_ref() {
"clippy" => $tool_name == "clippy-driver",
x => $tool_name == x,
})
}),
)
}

fn make_run(run: RunConfig<'_>) {
Expand Down
56 changes: 43 additions & 13 deletions src/libcore/alloc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl Layout {
/// Returns an error if the combination of `self.size()` and the given
/// `align` violates the conditions listed in
/// [`Layout::from_size_align`](#method.from_size_align).
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
Layout::from_size_align(self.size(), cmp::max(self.align(), align))
Expand Down Expand Up @@ -218,7 +218,7 @@ impl Layout {
///
/// This is equivalent to adding the result of `padding_needed_for`
/// to the layout's current size.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn pad_to_align(&self) -> Layout {
let pad = self.padding_needed_for(self.align());
Expand Down Expand Up @@ -258,19 +258,50 @@ impl Layout {

/// Creates a layout describing the record for `self` followed by
/// `next`, including any necessary padding to ensure that `next`
/// will be properly aligned. Note that the resulting layout will
/// satisfy the alignment properties of both `self` and `next`.
/// will be properly aligned, but *no trailing padding*.
///
/// The resulting layout will be the same as that of a C struct containing
/// two fields with the layouts of `self` and `next`, in that order.
/// In order to match C representation layout `repr(C)`, you should
/// call `pad_to_align` after extending the layout with all fields.
/// (There is no way to match the default Rust representation
/// layout `repr(Rust)`, as it is unspecified.)
///
/// Returns `Some((k, offset))`, where `k` is layout of the concatenated
/// Note that the alignment of the resulting layout will be the maximum of
/// those of `self` and `next`, in order to ensure alignment of both parts.
///
/// Returns `Ok((k, offset))`, where `k` is layout of the concatenated
/// record and `offset` is the relative location, in bytes, of the
/// start of the `next` embedded within the concatenated record
/// (assuming that the record itself starts at offset 0).
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
///
/// # Examples
///
/// To calculate the layout of a `#[repr(C)]` structure and the offsets of
/// the fields from its fields' layouts:
///
/// ```rust
/// # use std::alloc::{Layout, LayoutErr};
/// pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec<usize>), LayoutErr> {
/// let mut offsets = Vec::new();
/// let mut layout = Layout::from_size_align(0, 1)?;
/// for &field in fields {
/// let (new_layout, offset) = layout.extend(field)?;
/// layout = new_layout;
/// offsets.push(offset);
/// }
/// // Remember to finalize with `pad_to_align`!
/// Ok((layout.pad_to_align(), offsets))
/// }
/// # // test that it works
/// # #[repr(C)] struct S { a: u64, b: u32, c: u16, d: u32 }
/// # let s = Layout::new::<S>();
/// # let u16 = Layout::new::<u16>();
/// # let u32 = Layout::new::<u32>();
/// # let u64 = Layout::new::<u64>();
/// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16])));
/// ```
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
let new_align = cmp::max(self.align(), next.align());
Expand Down Expand Up @@ -318,13 +349,12 @@ impl Layout {
/// Creates a layout describing the record for a `[T; n]`.
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
Layout::new::<T>().repeat(n).map(|(k, offs)| {
debug_assert!(offs == mem::size_of::<T>());
k
})
let (layout, offset) = Layout::new::<T>().repeat(n)?;
debug_assert_eq!(offset, mem::size_of::<T>());
Ok(layout.pad_to_align())
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ E0748: include_str!("./error_codes/E0748.md"),
E0749: include_str!("./error_codes/E0749.md"),
E0750: include_str!("./error_codes/E0750.md"),
E0751: include_str!("./error_codes/E0751.md"),
E0752: include_str!("./error_codes/E0752.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
Expand Down
11 changes: 11 additions & 0 deletions src/librustc_error_codes/error_codes/E0752.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
`fn main()` or the specified start function is not allowed to be
async. You might be seeing this error because your async runtime
library is not set up correctly.

Erroneous code example:

```compile_fail,E0752
async fn main() -> Result<i32, ()> {
Ok(1)
}
```
12 changes: 5 additions & 7 deletions src/librustc_mir/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,15 @@ impl Inliner<'tcx> {
continue;
}

let self_node_id = self.tcx.hir().as_local_node_id(self.source.def_id()).unwrap();
let callee_node_id = self.tcx.hir().as_local_node_id(callsite.callee);
let callee_hir_id = self.tcx.hir().as_local_hir_id(callsite.callee);

let callee_body = if let Some(callee_node_id) = callee_node_id {
let callee_body = if let Some(callee_hir_id) = callee_hir_id {
let self_hir_id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap();
// Avoid a cycle here by only using `optimized_mir` only if we have
// a lower node id than the callee. This ensures that the callee will
// a lower `HirId` than the callee. This ensures that the callee will
// not inline us. This trick only works without incremental compilation.
// So don't do it if that is enabled.
if !self.tcx.dep_graph.is_fully_enabled()
&& self_node_id.as_u32() < callee_node_id.as_u32()
{
if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id {
self.tcx.optimized_mir(callsite.callee)
} else {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
match &node {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => {
self.describe_generator(*body_id).or_else(|| {
Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header {
"an async function"
} else {
"a function"
Some(match sig.header {
hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async function",
_ => "a function",
})
})
}
Expand All @@ -97,10 +96,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
kind: hir::ImplItemKind::Fn(sig, body_id),
..
}) => self.describe_generator(*body_id).or_else(|| {
Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header {
"an async method"
} else {
"a method"
Some(match sig.header {
hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async method",
_ => "a method",
})
}),
hir::Node::Expr(hir::Expr {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1318,10 +1318,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {

let is_async = inner_generator_body
.and_then(|body| body.generator_kind())
.map(|generator_kind| match generator_kind {
hir::GeneratorKind::Async(..) => true,
_ => false,
})
.map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
.unwrap_or(false);
let (await_or_yield, an_await_or_yield) =
if is_async { ("await", "an await") } else { ("yield", "a yield") };
Expand Down
28 changes: 26 additions & 2 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
match main_t.kind {
ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(main_id) {
if let hir::ItemKind::Fn(.., ref generics, _) = it.kind {
if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind {
let mut error = false;
if !generics.params.is_empty() {
let msg = "`main` function is not allowed to have generic \
Expand All @@ -182,6 +182,18 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
.emit();
error = true;
}
if let hir::IsAsync::Async = sig.header.asyncness {
let span = tcx.sess.source_map().guess_head_span(it.span);
struct_span_err!(
tcx.sess,
span,
E0752,
"`main` function is not allowed to be `async`"
)
.span_label(span, "`main` function is not allowed to be `async`")
.emit();
error = true;
}
if error {
return;
}
Expand Down Expand Up @@ -226,7 +238,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
match start_t.kind {
ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
if let hir::ItemKind::Fn(.., ref generics, _) = it.kind {
if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind {
let mut error = false;
if !generics.params.is_empty() {
struct_span_err!(
Expand All @@ -250,6 +262,18 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
.emit();
error = true;
}
if let hir::IsAsync::Async = sig.header.asyncness {
let span = tcx.sess.source_map().guess_head_span(it.span);
struct_span_err!(
tcx.sess,
span,
E0752,
"start is not allowed to be `async`"
)
.span_label(span, "start is not allowed to be `async`")
.emit();
error = true;
}
if error {
return;
}
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/async-await/issue-68523-start.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// edition:2018

#![feature(start)]

#[start]
pub async fn start(_: isize, _: *const *const u8) -> isize {
//~^ ERROR start is not allowed to be `async`
0
}
9 changes: 9 additions & 0 deletions src/test/ui/async-await/issue-68523-start.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0752]: start is not allowed to be `async`
--> $DIR/issue-68523-start.rs:6:1
|
LL | pub async fn start(_: isize, _: *const *const u8) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ start is not allowed to be `async`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0752`.
7 changes: 7 additions & 0 deletions src/test/ui/async-await/issue-68523.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// edition:2018

async fn main() -> Result<i32, ()> {
//~^ ERROR `main` function is not allowed to be `async`
//~^^ ERROR `main` has invalid return type `impl std::future::Future`
Ok(1)
}
18 changes: 18 additions & 0 deletions src/test/ui/async-await/issue-68523.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0277]: `main` has invalid return type `impl std::future::Future`
--> $DIR/issue-68523.rs:3:20
|
LL | async fn main() -> Result<i32, ()> {
| ^^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
|
= help: consider using `()`, or a `Result`

error[E0752]: `main` function is not allowed to be `async`
--> $DIR/issue-68523.rs:3:1
|
LL | async fn main() -> Result<i32, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` function is not allowed to be `async`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0752.
For more information about an error, try `rustc --explain E0277`.

0 comments on commit 073744f

Please sign in to comment.