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 4 pull requests #71367

Merged
merged 14 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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`.