diff --git a/.mailmap b/.mailmap index 78c3c3019af50..aed3a4ca5b002 100644 --- a/.mailmap +++ b/.mailmap @@ -133,7 +133,7 @@ João Oliveira joaoxsouls Johann Hofmann Johann John Clements John Hodge John Hodge -John Kåre Alsaker +John Kåre Alsaker John Talling Jonathan Bailey Jonathan S Jonathan S @@ -153,7 +153,7 @@ Laurențiu Nicola Lee Jeffery Lee Jeffery Lee Wondong Lennart Kudling -Léo Testard +Léo Testard Lindsey Kuper Lindsey Kuper Luke Metz diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index daa030c59d641..a8c00c8c3ca88 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -134,11 +134,6 @@ fn main() { cmd.arg(format!("-Clinker={}", host_linker)); } - // Override linker flavor if necessary. - if let Ok(host_linker_flavor) = env::var("RUSTC_HOST_LINKER_FLAVOR") { - cmd.arg(format!("-Clinker-flavor={}", host_linker_flavor)); - } - if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") { if s == "true" { cmd.arg("-C").arg("target-feature=+crt-static"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7fc089d18f113..8d6c2db792645 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -969,27 +969,11 @@ impl<'a> Builder<'a> { // See https://github.com/rust-lang/rust/issues/68647. let can_use_lld = mode != Mode::Std; - // FIXME: The beta compiler doesn't pick the `lld-link` flavor for `*-pc-windows-msvc` - // Remove `RUSTC_HOST_LINKER_FLAVOR` when this is fixed - let lld_linker_flavor = |linker: &Path, target: Interned| { - compiler.stage == 0 - && linker.file_name() == Some(OsStr::new("rust-lld")) - && target.contains("pc-windows-msvc") - }; - if let Some(host_linker) = self.linker(compiler.host, can_use_lld) { - if lld_linker_flavor(host_linker, compiler.host) { - cargo.env("RUSTC_HOST_LINKER_FLAVOR", "lld-link"); - } - cargo.env("RUSTC_HOST_LINKER", host_linker); } if let Some(target_linker) = self.linker(target, can_use_lld) { - if lld_linker_flavor(target_linker, target) { - rustflags.arg("-Clinker-flavor=lld-link"); - } - let target = crate::envify(&target); cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker); } diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index a01e9b25dd6c8..03c9164fb9095 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1,10 +1,10 @@ //! A priority queue implemented with a binary heap. //! -//! Insertion and popping the largest element have `O(log n)` time complexity. +//! Insertion and popping the largest element have `O(log(n))` time complexity. //! Checking the largest element is `O(1)`. Converting a vector to a binary heap //! can be done in-place, and has `O(n)` complexity. A binary heap can also be -//! converted to a sorted vector in-place, allowing it to be used for an `O(n -//! log n)` in-place heapsort. +//! converted to a sorted vector in-place, allowing it to be used for an `O(n * log(n))` +//! in-place heapsort. //! //! # Examples //! @@ -233,9 +233,9 @@ use super::SpecExtend; /// /// # Time complexity /// -/// | [push] | [pop] | [peek]/[peek\_mut] | -/// |--------|----------|--------------------| -/// | O(1)~ | O(log n) | O(1) | +/// | [push] | [pop] | [peek]/[peek\_mut] | +/// |--------|-----------|--------------------| +/// | O(1)~ | O(log(n)) | O(1) | /// /// The value for `push` is an expected cost; the method documentation gives a /// more detailed analysis. @@ -398,7 +398,7 @@ impl BinaryHeap { /// /// # Time complexity /// - /// Cost is O(1) in the worst case. + /// Cost is `O(1)` in the worst case. #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { Some(PeekMut { heap: self, sift: true }) } @@ -422,8 +422,7 @@ impl BinaryHeap { /// /// # Time complexity /// - /// The worst case cost of `pop` on a heap containing *n* elements is O(log - /// n). + /// The worst case cost of `pop` on a heap containing *n* elements is `O(log(n))`. #[stable(feature = "rust1", since = "1.0.0")] pub fn pop(&mut self) -> Option { self.data.pop().map(|mut item| { @@ -456,15 +455,15 @@ impl BinaryHeap { /// /// The expected cost of `push`, averaged over every possible ordering of /// the elements being pushed, and over a sufficiently large number of - /// pushes, is O(1). This is the most meaningful cost metric when pushing + /// pushes, is `O(1)`. This is the most meaningful cost metric when pushing /// elements that are *not* already in any sorted pattern. /// /// The time complexity degrades if elements are pushed in predominantly /// ascending order. In the worst case, elements are pushed in ascending - /// sorted order and the amortized cost per push is O(log n) against a heap + /// sorted order and the amortized cost per push is `O(log(n))` against a heap /// containing *n* elements. /// - /// The worst case cost of a *single* call to `push` is O(n). The worst case + /// The worst case cost of a *single* call to `push` is `O(n)`. The worst case /// occurs when capacity is exhausted and needs a resize. The resize cost /// has been amortized in the previous figures. #[stable(feature = "rust1", since = "1.0.0")] @@ -623,7 +622,7 @@ impl BinaryHeap { // `rebuild` takes O(len1 + len2) operations // and about 2 * (len1 + len2) comparisons in the worst case - // while `extend` takes O(len2 * log_2(len1)) operations + // while `extend` takes O(len2 * log(len1)) operations // and about 1 * len2 * log_2(len1) comparisons in the worst case, // assuming len1 >= len2. #[inline] @@ -644,7 +643,7 @@ impl BinaryHeap { /// The remaining elements will be removed on drop in heap order. /// /// Note: - /// * `.drain_sorted()` is O(n lg n); much slower than `.drain()`. + /// * `.drain_sorted()` is `O(n * log(n))`; much slower than `.drain()`. /// You should use the latter for most cases. /// /// # Examples @@ -729,7 +728,7 @@ impl BinaryHeap { /// /// # Time complexity /// - /// Cost is O(1) in the worst case. + /// Cost is `O(1)` in the worst case. #[stable(feature = "rust1", since = "1.0.0")] pub fn peek(&self) -> Option<&T> { self.data.get(0) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 38196b2d4b4c5..91d93a1be1c98 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -40,7 +40,7 @@ use UnderflowResult::*; /// performance on *small* nodes of elements which are cheap to compare. However in the future we /// would like to further explore choosing the optimal search strategy based on the choice of B, /// and possibly other factors. Using linear search, searching for a random element is expected -/// to take O(B logBn) comparisons, which is generally worse than a BST. In practice, +/// to take O(B * log(n)) comparisons, which is generally worse than a BST. In practice, /// however, performance is excellent. /// /// It is a logic error for a key to be modified in such a way that the key's ordering relative to diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 243ebb453d3ea..af341e6c1caab 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -390,7 +390,7 @@ impl LinkedList { /// This reuses all the nodes from `other` and moves them into `self`. After /// this operation, `other` becomes empty. /// - /// This operation should compute in O(1) time and O(1) memory. + /// This operation should compute in `O(1)` time and `O(1)` memory. /// /// # Examples /// @@ -547,7 +547,7 @@ impl LinkedList { /// Returns `true` if the `LinkedList` is empty. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -568,7 +568,7 @@ impl LinkedList { /// Returns the length of the `LinkedList`. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -594,7 +594,7 @@ impl LinkedList { /// Removes all elements from the `LinkedList`. /// - /// This operation should compute in O(n) time. + /// This operation should compute in `O(n)` time. /// /// # Examples /// @@ -737,7 +737,7 @@ impl LinkedList { /// Adds an element first in the list. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -760,7 +760,7 @@ impl LinkedList { /// Removes the first element and returns it, or `None` if the list is /// empty. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -783,7 +783,7 @@ impl LinkedList { /// Appends an element to the back of a list. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -803,7 +803,7 @@ impl LinkedList { /// Removes the last element from a list and returns it, or `None` if /// it is empty. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -824,7 +824,7 @@ impl LinkedList { /// Splits the list into two at the given index. Returns everything after the given index, /// including the index. /// - /// This operation should compute in O(n) time. + /// This operation should compute in `O(n)` time. /// /// # Panics /// @@ -880,7 +880,7 @@ impl LinkedList { /// Removes the element at the given index and returns it. /// - /// This operation should compute in O(n) time. + /// This operation should compute in `O(n)` time. /// /// # Panics /// Panics if at >= len diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 06e00465e12db..091b068b0b245 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1391,7 +1391,7 @@ impl VecDeque { /// Removes an element from anywhere in the `VecDeque` and returns it, /// replacing it with the first element. /// - /// This does not preserve ordering, but is O(1). + /// This does not preserve ordering, but is `O(1)`. /// /// Returns `None` if `index` is out of bounds. /// @@ -1426,7 +1426,7 @@ impl VecDeque { /// Removes an element from anywhere in the `VecDeque` and returns it, replacing it with the /// last element. /// - /// This does not preserve ordering, but is O(1). + /// This does not preserve ordering, but is `O(1)`. /// /// Returns `None` if `index` is out of bounds. /// @@ -2927,7 +2927,7 @@ impl From> for Vec { /// [`Vec`]: crate::vec::Vec /// [`VecDeque`]: crate::collections::VecDeque /// - /// This never needs to re-allocate, but does need to do O(n) data movement if + /// This never needs to re-allocate, but does need to do `O(n)` data movement if /// the circular buffer doesn't happen to be at the beginning of the allocation. /// /// # Examples diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 4171185c9701a..955cbe77819e5 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -165,7 +165,7 @@ mod hack { impl [T] { /// Sorts the slice. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(n log n)` worst-case. + /// This sort is stable (i.e., does not reorder equal elements) and `O(n * log(n))` worst-case. /// /// When applicable, unstable sorting is preferred because it is generally faster than stable /// sorting and it doesn't allocate auxiliary memory. @@ -200,7 +200,7 @@ impl [T] { /// Sorts the slice with a comparator function. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(n log n)` worst-case. + /// This sort is stable (i.e., does not reorder equal elements) and `O(n * log(n))` worst-case. /// /// The comparator function must define a total ordering for the elements in the slice. If /// the ordering is not total, the order of the elements is unspecified. An order is a @@ -254,7 +254,7 @@ impl [T] { /// Sorts the slice with a key extraction function. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(m n log n)` + /// This sort is stable (i.e., does not reorder equal elements) and `O(m * n * log(n))` /// worst-case, where the key function is `O(m)`. /// /// For expensive key functions (e.g. functions that are not simple property accesses or @@ -297,7 +297,7 @@ impl [T] { /// /// During sorting, the key function is called only once per element. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(m n + n log n)` + /// This sort is stable (i.e., does not reorder equal elements) and `O(m * n + n * log(n))` /// worst-case, where the key function is `O(m)`. /// /// For simple key functions (e.g., functions that are property accesses or @@ -935,7 +935,7 @@ where /// 1. for every `i` in `1..runs.len()`: `runs[i - 1].len > runs[i].len` /// 2. for every `i` in `2..runs.len()`: `runs[i - 2].len > runs[i - 1].len + runs[i].len` /// -/// The invariants ensure that the total running time is `O(n log n)` worst-case. +/// The invariants ensure that the total running time is `O(n * log(n))` worst-case. fn merge_sort(v: &mut [T], mut is_less: F) where F: FnMut(&T, &T) -> bool, diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 4d333fbf8ed97..df976128b5efb 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1606,7 +1606,7 @@ impl [T] { /// Sorts the slice, but may not preserve the order of equal elements. /// /// This sort is unstable (i.e., may reorder equal elements), in-place - /// (i.e., does not allocate), and `O(n log n)` worst-case. + /// (i.e., does not allocate), and `O(n * log(n))` worst-case. /// /// # Current implementation /// @@ -1642,7 +1642,7 @@ impl [T] { /// elements. /// /// This sort is unstable (i.e., may reorder equal elements), in-place - /// (i.e., does not allocate), and `O(n log n)` worst-case. + /// (i.e., does not allocate), and `O(n * log(n))` worst-case. /// /// The comparator function must define a total ordering for the elements in the slice. If /// the ordering is not total, the order of the elements is unspecified. An order is a @@ -1697,7 +1697,7 @@ impl [T] { /// elements. /// /// This sort is unstable (i.e., may reorder equal elements), in-place - /// (i.e., does not allocate), and `O(m n log n)` worst-case, where the key function is + /// (i.e., does not allocate), and `O(m * n * log(n))` worst-case, where the key function is /// `O(m)`. /// /// # Current implementation @@ -1957,7 +1957,7 @@ impl [T] { // over all the elements, swapping as we go so that at the end // the elements we wish to keep are in the front, and those we // wish to reject are at the back. We can then split the slice. - // This operation is still O(n). + // This operation is still `O(n)`. // // Example: We start in this state, where `r` represents "next // read" and `w` represents "next_write`. diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index 019832e16f89c..be3e7aaa2e89a 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -143,7 +143,7 @@ where } } -/// Sorts `v` using heapsort, which guarantees `O(n log n)` worst-case. +/// Sorts `v` using heapsort, which guarantees `O(n * log(n))` worst-case. #[cold] pub fn heapsort(v: &mut [T], is_less: &mut F) where @@ -621,7 +621,7 @@ where } // If too many bad pivot choices were made, simply fall back to heapsort in order to - // guarantee `O(n log n)` worst-case. + // guarantee `O(n * log(n))` worst-case. if limit == 0 { heapsort(v, is_less); return; @@ -684,7 +684,7 @@ where } } -/// Sorts `v` using pattern-defeating quicksort, which is `O(n log n)` worst-case. +/// Sorts `v` using pattern-defeating quicksort, which is `O(n * log(n))` worst-case. pub fn quicksort(v: &mut [T], mut is_less: F) where F: FnMut(&T, &T) -> bool, diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 219d5aa77ea0d..4913138650880 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -111,7 +111,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>, cleanup: Option, ) { - if let Some(cleanup) = cleanup { + // If there is a cleanup block and the function we're calling can unwind, then + // do an invoke, otherwise do a call. + if let Some(cleanup) = cleanup.filter(|_| fn_abi.can_unwind) { let ret_bx = if let Some((_, target)) = destination { fx.blocks[target] } else { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 0fd930090d56a..71275452fb688 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -26,7 +26,7 @@ pub enum MemPlaceMeta { /// `Sized` types or unsized `extern type` None, /// The address of this place may not be taken. This protects the `MemPlace` from coming from - /// a ZST Operand with a backing allocation and being converted to an integer address. This + /// a ZST Operand without a backing allocation and being converted to an integer address. This /// should be impossible, because you can't take the address of an operand, but this is a second /// protection layer ensuring that we don't mess up. Poison, diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 12b9b68268248..552f3d798ae8a 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1054,6 +1054,39 @@ impl<'a> Parser<'a> { } } + pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P> { + let is_try = self.token.is_keyword(kw::Try); + let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for ! + let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(token::Paren)); //check for ( + + if is_try && is_questionmark && is_open { + let lo = self.token.span; + self.bump(); //remove try + self.bump(); //remove ! + let try_span = lo.to(self.token.span); //we take the try!( span + self.bump(); //remove ( + let is_empty = self.token == token::CloseDelim(token::Paren); //check if the block is empty + self.consume_block(token::Paren, ConsumeClosingDelim::No); //eat the block + let hi = self.token.span; + self.bump(); //remove ) + let mut err = self.struct_span_err(lo.to(hi), "use of deprecated `try` macro"); + err.note("in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated"); + let prefix = if is_empty { "" } else { "alternatively, " }; + if !is_empty { + err.multipart_suggestion( + "you can use the `?` operator instead", + vec![(try_span, "".to_owned()), (hi, "?".to_owned())], + Applicability::MachineApplicable, + ); + } + err.span_suggestion(lo.shrink_to_lo(), &format!("{}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax", prefix), "r#".to_string(), Applicability::MachineApplicable); + err.emit(); + Ok(self.mk_expr_err(lo.to(hi))) + } else { + Err(self.expected_expression_found()) // The user isn't trying to invoke the try! macro + } + } + /// Recovers a situation like `for ( $pat in $expr )` /// and suggest writing `for $pat in $expr` instead. /// diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 4e3c5fa63de2c..986f5410e26c0 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1006,7 +1006,7 @@ impl<'a> Parser<'a> { let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs); self.maybe_recover_from_bad_qpath(expr, true) } - None => Err(self.expected_expression_found()), + None => self.try_macro_suggestion(), } } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index e8b9e9cb1f29c..cc6663bebd3d4 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -110,10 +110,10 @@ //! //! For Sets, all operations have the cost of the equivalent Map operation. //! -//! | | get | insert | remove | predecessor | append | -//! |--------------|-----------|----------|----------|-------------|--------| -//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | -//! | [`BTreeMap`] | O(log n) | O(log n) | O(log n) | O(log n) | O(n+m) | +//! | | get | insert | remove | predecessor | append | +//! |--------------|-----------|-----------|-----------|-------------|--------| +//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | +//! | [`BTreeMap`] | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n+m) | //! //! # Correct and Efficient Usage of Collections //! diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 72f7367c9dcdb..5aca7b7476a52 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -43,8 +43,8 @@ //! terminator, so the buffer length is really `len+1` characters. //! Rust strings don't have a nul terminator; their length is always //! stored and does not need to be calculated. While in Rust -//! accessing a string's length is a O(1) operation (because the -//! length is stored); in C it is an O(length) operation because the +//! accessing a string's length is a `O(1)` operation (because the +//! length is stored); in C it is an `O(length)` operation because the //! length needs to be computed by scanning the string for the nul //! terminator. //! diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs index 971f4e3e12ea8..29c82686731ca 100644 --- a/src/test/codegen/c-variadic.rs +++ b/src/test/codegen/c-variadic.rs @@ -16,13 +16,13 @@ extern "C" { #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_0() { // Ensure that we correctly call foreign C-variadic functions. - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM:i32( signext)?]] 0) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM:i32( signext)?]] 0) foreign_c_variadic_0(0); - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42) foreign_c_variadic_0(0, 42i32); - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024) foreign_c_variadic_0(0, 42i32, 1024i32); - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024, [[PARAM]] 0) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024, [[PARAM]] 0) foreign_c_variadic_0(0, 42i32, 1024i32, 0i32); } @@ -30,24 +30,24 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() { // removing the "spoofed" `VaListImpl` that is used by Rust defined C-variadics. #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap) foreign_c_variadic_1(ap); } #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 42) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 42) foreign_c_variadic_1(ap, 42i32); } #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42) foreign_c_variadic_1(ap, 2i32, 42i32); } #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); } diff --git a/src/test/codegen/call-llvm-intrinsics.rs b/src/test/codegen/call-llvm-intrinsics.rs new file mode 100644 index 0000000000000..c7a464a9b0ef2 --- /dev/null +++ b/src/test/codegen/call-llvm-intrinsics.rs @@ -0,0 +1,27 @@ +// compile-flags: -C no-prepopulate-passes + +#![feature(link_llvm_intrinsics)] +#![crate_type = "lib"] + +struct A; + +impl Drop for A { + fn drop(&mut self) { + println!("A"); + } +} + +extern { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; +} + +pub fn do_call() { + let _a = A; + + unsafe { + // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them + // CHECK: call float @llvm.sqrt.f32(float 4.000000e+00 + sqrt(4.0); + } +} diff --git a/src/test/ui/try-macro-suggestion.rs b/src/test/ui/try-macro-suggestion.rs new file mode 100644 index 0000000000000..635ceac0b199e --- /dev/null +++ b/src/test/ui/try-macro-suggestion.rs @@ -0,0 +1,9 @@ +// compile-flags: --edition 2018 +fn foo() -> Result<(), ()> { + Ok(try!()); //~ ERROR use of deprecated `try` macro + Ok(try!(Ok(()))) //~ ERROR use of deprecated `try` macro +} + +fn main() { + let _ = foo(); +} diff --git a/src/test/ui/try-macro-suggestion.stderr b/src/test/ui/try-macro-suggestion.stderr new file mode 100644 index 0000000000000..9d833ef5ed9fb --- /dev/null +++ b/src/test/ui/try-macro-suggestion.stderr @@ -0,0 +1,30 @@ +error: use of deprecated `try` macro + --> $DIR/try-macro-suggestion.rs:3:8 + | +LL | Ok(try!()); + | ^^^^^^ + | + = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated +help: you can still access the deprecated `try!()` macro using the "raw identifier" syntax + | +LL | Ok(r#try!()); + | ^^ + +error: use of deprecated `try` macro + --> $DIR/try-macro-suggestion.rs:4:8 + | +LL | Ok(try!(Ok(()))) + | ^^^^^^^^^^^^ + | + = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated +help: you can use the `?` operator instead + | +LL | Ok(Ok(())?) + | -- ^ +help: alternatively, you can still access the deprecated `try!()` macro using the "raw identifier" syntax + | +LL | Ok(r#try!(Ok(()))) + | ^^ + +error: aborting due to 2 previous errors +