mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Auto merge of #55347 - pietroalbini:rollup, r=pietroalbini
Rollup of 22 pull requests Successful merges: - #53507 (Add doc for impl From for Waker) - #53931 (Gradually expanding libstd's keyword documentation) - #54965 (update tcp stream documentation) - #54977 (Accept `Option<Box<$t:ty>>` in macro argument) - #55138 (in which unused-parens suggestions heed what the user actually wrote) - #55173 (Suggest appropriate syntax on missing lifetime specifier in return type) - #55200 (Documents `From` implementations for `Stdio`) - #55245 (submodules: update clippy from5afdf8b7
tob1d03437
) - #55247 (Clarified code example in char primitive doc) - #55251 (Fix a typo in the documentation of RangeInclusive) - #55253 (only issue "variant of the expected type" suggestion for enums) - #55254 (Correct trailing ellipsis in name_from_pat) - #55269 (fix typos in various places) - #55282 (Remove redundant clone) - #55285 (Do some copy editing on the release notes) - #55291 (Update stdsimd submodule) - #55296 (Set RUST_BACKTRACE=0 for rustdoc-ui/failed-doctest-output.rs) - #55306 (Regression test for #54478.) - #55328 (Fix doc for new copysign functions) - #55340 (Operands no longer appear in places) - #55345 (Remove is_null) - #55348 (Update RELEASES.md after destabilization of non_modrs_mods) Failed merges: r? @ghost
This commit is contained in:
commit
8ec22e7ec7
89
RELEASES.md
89
RELEASES.md
@ -4,34 +4,31 @@ Version 1.30.0 (2018-10-25)
|
||||
Language
|
||||
--------
|
||||
- [Procedural macros are now available.][52081] These kinds of macros allow for
|
||||
more powerful code generation, there is a [new chapter available][proc-macros]
|
||||
in Rust Programming Language book that goes further in depth.
|
||||
more powerful code generation. There is a [new chapter available][proc-macros]
|
||||
in the Rust Programming Language book that goes further in depth.
|
||||
- [You can now use keywords as identifiers using the raw identifiers
|
||||
syntax (`r#`).][53236] e.g. `let r#for = true;`
|
||||
syntax (`r#`),][53236] e.g. `let r#for = true;`
|
||||
- [Using anonymous parameters in traits is now deprecated with a warning and
|
||||
will be a hard error in the 2018 edition.][53272]
|
||||
- [You can now use `crate` in paths.][54404] This allows you to refer to the
|
||||
crate root in the path. e.g. `use crate::foo;` refers to `foo` in `src/lib.rs`.
|
||||
- [Using a external crate now no longer requires being prefixed with `::`.][54404]
|
||||
e.g. previously using a external crate in a module without a use statement
|
||||
required `let json = ::serde_json::from_str(foo);` can now be written
|
||||
crate root in the path, e.g. `use crate::foo;` refers to `foo` in `src/lib.rs`.
|
||||
- [Using a external crate no longer requires being prefixed with `::`.][54404]
|
||||
Previously, using a external crate in a module without a use statement
|
||||
required `let json = ::serde_json::from_str(foo);` but can now be written
|
||||
as `let json = serde_json::from_str(foo);`.
|
||||
- [You can now apply the `#[used]` attribute to static items to prevent the
|
||||
compiler from optimising them away even if they appear to be unused.][51363]
|
||||
compiler from optimising them away, even if they appear to be unused,][51363]
|
||||
e.g. `#[used] static FOO: u32 = 1;`
|
||||
- [You can now import and reexport macros from other crates with the `use`
|
||||
syntax.][50911] Macros exported with `#[macro_export]` are now placed into
|
||||
the root module of the crate. If your macro relies on calling other local
|
||||
macros it is recommended to export with the
|
||||
`#[macro_export(local_inner_macros)]` attribute so that users won't have to
|
||||
import those macros.
|
||||
- [`mod.rs` files are now optional.][54146] Previously if you had a `foo` module
|
||||
with a `bar` submodule, you would have `src/foo/mod.rs` and `src/foo/bar.rs`.
|
||||
Now you can have `src/foo.rs` and `src/foo/bar.rs` to achieve the same effect.
|
||||
macros, it is recommended to export with the
|
||||
`#[macro_export(local_inner_macros)]` attribute so users won't have to import
|
||||
those macros.
|
||||
- [You can now catch visibility keywords (e.g. `pub`, `pub(crate)`) in macros
|
||||
using the `vis` specifier.][53370]
|
||||
- [Non-macro attributes now allow all forms of literals not just
|
||||
strings.][53044] e.g. Previously you would write `#[attr("true")]` you can now
|
||||
- [Non-macro attributes now allow all forms of literals, not just
|
||||
strings.][53044] Previously, you would write `#[attr("true")]`, and you can now
|
||||
write `#[attr(true)]`.
|
||||
- [You can now specify a function to handle a panic in the Rust runtime with the
|
||||
`#[panic_handler]` attribute.][51366]
|
||||
@ -54,9 +51,9 @@ Stabilized APIs
|
||||
- [`Ipv6Addr::UNSPECIFIED`]
|
||||
- [`Iterator::find_map`]
|
||||
|
||||
The following methods are a replacement methods for `trim_left`, `trim_right`,
|
||||
`trim_left_matches`, and `trim_right_matches`. Which will be deprecated
|
||||
in 1.33.0.
|
||||
The following methods are replacement methods for `trim_left`, `trim_right`,
|
||||
`trim_left_matches`, and `trim_right_matches`, which will be deprecated
|
||||
in 1.33.0:
|
||||
- [`str::trim_end_matches`]
|
||||
- [`str::trim_end`]
|
||||
- [`str::trim_start_matches`]
|
||||
@ -76,12 +73,12 @@ Misc
|
||||
----
|
||||
- [`rustdoc` allows you to specify what edition to treat your code as with the
|
||||
`--edition` option.][54057]
|
||||
- [`rustdoc` now has the `--color` (Specify whether to output color) and
|
||||
`--error-format` (Specify error format e.g. `json`) options.][53003]
|
||||
- [`rustdoc` now has the `--color` (specify whether to output color) and
|
||||
`--error-format` (specify error format, e.g. `json`) options.][53003]
|
||||
- [We now distribute a `rust-gdbgui` script that invokes `gdbgui` with Rust
|
||||
debug symbols.][53774]
|
||||
- [Attributes from Rust tools such as `rustfmt` or `clippy` are now
|
||||
available.][53459] e.g. `#[rustfmt::skip]` will skip formatting the next item.
|
||||
available,][53459] e.g. `#[rustfmt::skip]` will skip formatting the next item.
|
||||
|
||||
[50911]: https://github.com/rust-lang/rust/pull/50911/
|
||||
[51363]: https://github.com/rust-lang/rust/pull/51363/
|
||||
@ -153,7 +150,7 @@ Compiler
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [`Once::call_once` now no longer requires `Once` to be `'static`.][52239]
|
||||
- [`Once::call_once` no longer requires `Once` to be `'static`.][52239]
|
||||
- [`BuildHasherDefault` now implements `PartialEq` and `Eq`.][52402]
|
||||
- [`Box<CStr>`, `Box<OsStr>`, and `Box<Path>` now implement `Clone`.][51912]
|
||||
- [Implemented `PartialEq<&str>` for `OsString` and `PartialEq<OsString>`
|
||||
@ -169,10 +166,10 @@ Stabilized APIs
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [Cargo can silently fix some bad lockfiles ][cargo/5831] You can use
|
||||
`--locked` to disable this behaviour.
|
||||
- [Cargo can silently fix some bad lockfiles.][cargo/5831] You can use
|
||||
`--locked` to disable this behavior.
|
||||
- [`cargo-install` will now allow you to cross compile an install
|
||||
using `--target`][cargo/5614]
|
||||
using `--target`.][cargo/5614]
|
||||
- [Added the `cargo-fix` subcommand to automatically move project code from
|
||||
2015 edition to 2018.][cargo/5723]
|
||||
- [`cargo doc` can now optionally document private types using the
|
||||
@ -184,15 +181,15 @@ Misc
|
||||
the specified level to that level.][52354] For example `--cap-lints warn`
|
||||
will demote `deny` and `forbid` lints to `warn`.
|
||||
- [`rustc` and `rustdoc` will now have the exit code of `1` if compilation
|
||||
fails, and `101` if there is a panic.][52197]
|
||||
fails and `101` if there is a panic.][52197]
|
||||
- [A preview of clippy has been made available through rustup.][51122]
|
||||
You can install the preview with `rustup component add clippy-preview`
|
||||
You can install the preview with `rustup component add clippy-preview`.
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- [`str::{slice_unchecked, slice_unchecked_mut}` are now deprecated.][51807]
|
||||
Use `str::get_unchecked(begin..end)` instead.
|
||||
- [`std::env::home_dir` is now deprecated for its unintuitive behaviour.][51656]
|
||||
- [`std::env::home_dir` is now deprecated for its unintuitive behavior.][51656]
|
||||
Consider using the `home_dir` function from
|
||||
https://crates.io/crates/dirs instead.
|
||||
- [`rustc` will no longer silently ignore invalid data in target spec.][52330]
|
||||
@ -432,7 +429,7 @@ Language
|
||||
be used as an identifier.
|
||||
- [The dyn syntax is now available.][49968] This syntax is equivalent to the
|
||||
bare `Trait` syntax, and should make it clearer when being used in tandem with
|
||||
`impl Trait`. Since it is equivalent to the following syntax:
|
||||
`impl Trait` because it is equivalent to the following syntax:
|
||||
`&Trait == &dyn Trait`, `&mut Trait == &mut dyn Trait`, and
|
||||
`Box<Trait> == Box<dyn Trait>`.
|
||||
- [Attributes on generic parameters such as types and lifetimes are
|
||||
@ -495,10 +492,10 @@ Cargo
|
||||
a different directory than `target` for placing compilation artifacts.
|
||||
- [Cargo will be adding automatic target inference for binaries, benchmarks,
|
||||
examples, and tests in the Rust 2018 edition.][cargo/5335] If your project specifies
|
||||
specific targets e.g. using `[[bin]]` and have other binaries in locations
|
||||
specific targets, e.g. using `[[bin]]`, and have other binaries in locations
|
||||
where cargo would infer a binary, Cargo will produce a warning. You can
|
||||
disable this feature ahead of time by setting any of the following `autobins`,
|
||||
`autobenches`, `autoexamples`, `autotests` to false.
|
||||
disable this feature ahead of time by setting any of the following to false:
|
||||
`autobins`, `autobenches`, `autoexamples`, `autotests`.
|
||||
- [Cargo will now cache compiler information.][cargo/5359] This can be disabled by
|
||||
setting `CARGO_CACHE_RUSTC_INFO=0` in your environment.
|
||||
|
||||
@ -514,8 +511,8 @@ Compatibility Notes
|
||||
work.][49896] e.g. `::core::prelude::v1::StrExt::is_empty("")` will not
|
||||
compile, `"".is_empty()` will still compile.
|
||||
- [`Debug` output on `atomic::{AtomicBool, AtomicIsize, AtomicPtr, AtomicUsize}`
|
||||
will only print the inner type.][48553] e.g.
|
||||
`print!("{:?}", AtomicBool::new(true))` will print `true`
|
||||
will only print the inner type.][48553] E.g.
|
||||
`print!("{:?}", AtomicBool::new(true))` will print `true`,
|
||||
not `AtomicBool(true)`.
|
||||
- [The maximum number for `repr(align(N))` is now 2²⁹.][50378] Previously you
|
||||
could enter higher numbers but they were not supported by LLVM. Up to 512MB
|
||||
@ -578,7 +575,7 @@ Version 1.26.2 (2018-06-05)
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [The borrow checker was fixed to avoid unsoundness when using match ergonomics][51117]
|
||||
- [The borrow checker was fixed to avoid unsoundness when using match ergonomics.][51117]
|
||||
|
||||
[51117]: https://github.com/rust-lang/rust/issues/51117
|
||||
|
||||
@ -589,18 +586,18 @@ Version 1.26.1 (2018-05-29)
|
||||
Tools
|
||||
-----
|
||||
|
||||
- [RLS now works on Windows][50646]
|
||||
- [Rustfmt stopped badly formatting text in some cases][rustfmt/2695]
|
||||
- [RLS now works on Windows.][50646]
|
||||
- [Rustfmt stopped badly formatting text in some cases.][rustfmt/2695]
|
||||
|
||||
|
||||
Compatibility Notes
|
||||
--------
|
||||
|
||||
- [`fn main() -> impl Trait` no longer works for non-Termination
|
||||
trait][50656]
|
||||
trait.][50656]
|
||||
This reverts an accidental stabilization.
|
||||
- [`NaN > NaN` no longer returns true in const-fn contexts][50812]
|
||||
- [Prohibit using turbofish for `impl Trait` in method arguments][50950]
|
||||
- [`NaN > NaN` no longer returns true in const-fn contexts.][50812]
|
||||
- [Prohibit using turbofish for `impl Trait` in method arguments.][50950]
|
||||
|
||||
[50646]: https://github.com/rust-lang/rust/issues/50646
|
||||
[50656]: https://github.com/rust-lang/rust/pull/50656
|
||||
@ -616,18 +613,18 @@ Language
|
||||
- [Closures now implement `Copy` and/or `Clone` if all captured variables
|
||||
implement either or both traits.][49299]
|
||||
- [The inclusive range syntax e.g. `for x in 0..=10` is now stable.][47813]
|
||||
- [The `'_` lifetime is now stable. The underscore lifetime can be used anywhere where a
|
||||
- [The `'_` lifetime is now stable. The underscore lifetime can be used anywhere a
|
||||
lifetime can be elided.][49458]
|
||||
- [`impl Trait` is now stable allowing you to have abstract types in returns
|
||||
or in function parameters.][49255] e.g. `fn foo() -> impl Iterator<Item=u8>` or
|
||||
or in function parameters.][49255] E.g. `fn foo() -> impl Iterator<Item=u8>` or
|
||||
`fn open(path: impl AsRef<Path>)`.
|
||||
- [Pattern matching will now automatically apply dereferences.][49394]
|
||||
- [128-bit integers in the form of `u128` and `i128` are now stable.][49101]
|
||||
- [`main` can now return `Result<(), E: Debug>`][49162] in addition to `()`.
|
||||
- [A lot of operations are now available in a const context.][46882] E.g. You
|
||||
can now index into constant arrays, reference and dereference into constants,
|
||||
and use Tuple struct constructors.
|
||||
- [Fixed entry slice patterns are now stable.][48516] e.g.
|
||||
and use tuple struct constructors.
|
||||
- [Fixed entry slice patterns are now stable.][48516] E.g.
|
||||
```rust
|
||||
let points = [1, 2, 3, 4];
|
||||
match points {
|
||||
@ -1052,7 +1049,7 @@ Language
|
||||
Compiler
|
||||
--------
|
||||
- [Enabled `TrapUnreachable` in LLVM which should mitigate the impact of
|
||||
undefined behaviour.][45920]
|
||||
undefined behavior.][45920]
|
||||
- [rustc now suggests renaming import if names clash.][45660]
|
||||
- [Display errors/warnings correctly when there are zero-width or
|
||||
wide characters.][45711]
|
||||
|
@ -349,6 +349,7 @@ dependencies = [
|
||||
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -594,7 +594,7 @@ class RustBuild(object):
|
||||
return ''
|
||||
|
||||
def bootstrap_binary(self):
|
||||
"""Return the path of the boostrap binary
|
||||
"""Return the path of the bootstrap binary
|
||||
|
||||
>>> rb = RustBuild()
|
||||
>>> rb.build_dir = "build"
|
||||
|
@ -277,7 +277,7 @@ def print_std_string_val(val, internal_dict):
|
||||
#=--------------------------------------------------------------------------------------------------
|
||||
|
||||
def print_array_of_values(array_name, data_ptr_val, length, internal_dict):
|
||||
"""Prints a contigous memory range, interpreting it as values of the
|
||||
"""Prints a contiguous memory range, interpreting it as values of the
|
||||
pointee-type of data_ptr_val."""
|
||||
|
||||
data_ptr_type = data_ptr_val.type
|
||||
|
@ -77,7 +77,7 @@ use self::Entry::*;
|
||||
/// movie_reviews.insert("Office Space", "Deals with real issues in the workplace.");
|
||||
/// movie_reviews.insert("Pulp Fiction", "Masterpiece.");
|
||||
/// movie_reviews.insert("The Godfather", "Very enjoyable.");
|
||||
/// movie_reviews.insert("The Blues Brothers", "Eye lyked it alot.");
|
||||
/// movie_reviews.insert("The Blues Brothers", "Eye lyked it a lot.");
|
||||
///
|
||||
/// // check for a specific one.
|
||||
/// if !movie_reviews.contains_key("Les Misérables") {
|
||||
|
@ -518,7 +518,7 @@ pub unsafe trait GlobalAlloc {
|
||||
/// The block is described by the given `ptr` pointer and `layout`.
|
||||
///
|
||||
/// If this returns a non-null pointer, then ownership of the memory block
|
||||
/// referenced by `ptr` has been transferred to this alloctor.
|
||||
/// referenced by `ptr` has been transferred to this allocator.
|
||||
/// The memory may or may not have been deallocated,
|
||||
/// and should be considered unusable (unless of course it was
|
||||
/// transferred back to the caller again via the return value of
|
||||
|
@ -1025,7 +1025,7 @@ extern "rust-intrinsic" {
|
||||
/// // to avoid problems in case something further down panics.
|
||||
/// src.set_len(0);
|
||||
///
|
||||
/// // The two regions cannot overlap becuase mutable references do
|
||||
/// // The two regions cannot overlap because mutable references do
|
||||
/// // not alias, and two different vectors cannot own the same
|
||||
/// // memory.
|
||||
/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
|
||||
|
@ -304,7 +304,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An range bounded inclusively below and above (`start..=end`).
|
||||
/// A range bounded inclusively below and above (`start..=end`).
|
||||
///
|
||||
/// The `RangeInclusive` `start..=end` contains all values with `x >= start`
|
||||
/// and `x <= end`. It is empty unless `start <= end`.
|
||||
|
@ -102,7 +102,7 @@ pub use marker::Unpin;
|
||||
/// value in place, preventing the value referenced by that pointer from being moved
|
||||
/// unless it implements [`Unpin`].
|
||||
///
|
||||
/// See the [`pin` module] documentation for furthur explanation on pinning.
|
||||
/// See the [`pin` module] documentation for further explanation on pinning.
|
||||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
/// [`pin` module]: ../../std/pin/index.html
|
||||
|
@ -38,7 +38,7 @@
|
||||
//! underlying object is live and no reference (just raw pointers) is used to
|
||||
//! access the same memory.
|
||||
//!
|
||||
//! These axioms, along with careful use of [`offset`] for pointer arithmentic,
|
||||
//! These axioms, along with careful use of [`offset`] for pointer arithmetic,
|
||||
//! are enough to correctly implement many useful things in unsafe code. Stronger guarantees
|
||||
//! will be provided eventually, as the [aliasing] rules are being determined. For more
|
||||
//! information, see the [book] as well as the section in the reference devoted
|
||||
|
@ -188,6 +188,11 @@ impl LocalWaker {
|
||||
}
|
||||
|
||||
impl From<LocalWaker> for Waker {
|
||||
/// Converts a `LocalWaker` into a `Waker`.
|
||||
///
|
||||
/// This conversion turns a `!Sync` `LocalWaker` into a `Sync` `Waker`, allowing a wakeup
|
||||
/// object to be sent to another thread, but giving up its ability to do specialized
|
||||
/// thread-local wakeup behavior.
|
||||
#[inline]
|
||||
fn from(local_waker: LocalWaker) -> Self {
|
||||
local_waker.0
|
||||
|
@ -40,7 +40,7 @@ impl ::std::fmt::Debug for CrateNum {
|
||||
match self {
|
||||
CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
|
||||
CrateNum::Invalid => write!(fmt, "invalid crate"),
|
||||
CrateNum::BuiltinMacros => write!(fmt, "bultin macros crate"),
|
||||
CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"),
|
||||
CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
|
||||
}
|
||||
}
|
||||
@ -101,7 +101,7 @@ impl fmt::Display for CrateNum {
|
||||
match self {
|
||||
CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
|
||||
CrateNum::Invalid => write!(f, "invalid crate"),
|
||||
CrateNum::BuiltinMacros => write!(f, "bultin macros crate"),
|
||||
CrateNum::BuiltinMacros => write!(f, "builtin macros crate"),
|
||||
CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
|
||||
}
|
||||
}
|
||||
|
@ -1147,7 +1147,7 @@ impl<'a> LoweringContext<'a> {
|
||||
TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
|
||||
TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
|
||||
TyKind::Rptr(ref region, ref mt) => {
|
||||
let span = t.span.shrink_to_lo();
|
||||
let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
|
||||
let lifetime = match *region {
|
||||
Some(ref lt) => self.lower_lifetime(lt),
|
||||
None => self.elided_ref_lifetime(span),
|
||||
|
@ -180,7 +180,7 @@ impl<'a> State<'a> {
|
||||
State {
|
||||
s: pp::mk_printer(out, default_columns),
|
||||
cm: Some(cm),
|
||||
comments: comments.clone(),
|
||||
comments,
|
||||
literals: literals.unwrap_or_default().into_iter().peekable(),
|
||||
cur_cmnt: 0,
|
||||
boxes: Vec::new(),
|
||||
|
@ -44,7 +44,7 @@ impl<'cm> CachingSourceMapView<'cm> {
|
||||
|
||||
CachingSourceMapView {
|
||||
source_map,
|
||||
line_cache: [entry.clone(), entry.clone(), entry.clone()],
|
||||
line_cache: [entry.clone(), entry.clone(), entry],
|
||||
time_stamp: 0,
|
||||
}
|
||||
}
|
||||
|
@ -2235,21 +2235,46 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len());
|
||||
let mut add_label = true;
|
||||
|
||||
if let Some(params) = error {
|
||||
if lifetime_refs.len() == 1 {
|
||||
self.report_elision_failure(&mut err, params);
|
||||
add_label = add_label && self.report_elision_failure(&mut err, params, span);
|
||||
}
|
||||
}
|
||||
if add_label {
|
||||
add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len());
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn suggest_lifetime(&self, db: &mut DiagnosticBuilder<'_>, span: Span, msg: &str) -> bool {
|
||||
match self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
Ok(ref snippet) => {
|
||||
let (sugg, applicability) = if snippet == "&" {
|
||||
("&'static ".to_owned(), Applicability::MachineApplicable)
|
||||
} else if snippet == "'_" {
|
||||
("'static".to_owned(), Applicability::MachineApplicable)
|
||||
} else {
|
||||
(format!("{} + 'static", snippet), Applicability::MaybeIncorrect)
|
||||
};
|
||||
db.span_suggestion_with_applicability(span, msg, sugg, applicability);
|
||||
false
|
||||
}
|
||||
Err(_) => {
|
||||
db.help(msg);
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_elision_failure(
|
||||
&mut self,
|
||||
db: &mut DiagnosticBuilder<'_>,
|
||||
params: &[ElisionFailureInfo],
|
||||
) {
|
||||
span: Span,
|
||||
) -> bool {
|
||||
let mut m = String::new();
|
||||
let len = params.len();
|
||||
|
||||
@ -2304,7 +2329,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
"this function's return type contains a borrowed value, but \
|
||||
there is no value for it to be borrowed from"
|
||||
);
|
||||
help!(db, "consider giving it a 'static lifetime");
|
||||
self.suggest_lifetime(db, span, "consider giving it a 'static lifetime")
|
||||
} else if elided_len == 0 {
|
||||
help!(
|
||||
db,
|
||||
@ -2312,11 +2337,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
an elided lifetime, but the lifetime cannot be derived from \
|
||||
the arguments"
|
||||
);
|
||||
help!(
|
||||
db,
|
||||
"consider giving it an explicit bounded or 'static \
|
||||
lifetime"
|
||||
);
|
||||
let msg = "consider giving it an explicit bounded or 'static lifetime";
|
||||
self.suggest_lifetime(db, span, msg)
|
||||
} else if elided_len == 1 {
|
||||
help!(
|
||||
db,
|
||||
@ -2324,6 +2346,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
the signature does not say which {} it is borrowed from",
|
||||
m
|
||||
);
|
||||
true
|
||||
} else {
|
||||
help!(
|
||||
db,
|
||||
@ -2331,6 +2354,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
the signature does not say whether it is borrowed from {}",
|
||||
m
|
||||
);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@ -2744,26 +2768,28 @@ fn insert_late_bound_lifetimes(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_missing_lifetime_specifiers(
|
||||
fn report_missing_lifetime_specifiers(
|
||||
sess: &Session,
|
||||
span: Span,
|
||||
count: usize,
|
||||
) -> DiagnosticBuilder<'_> {
|
||||
let mut err = struct_span_err!(
|
||||
struct_span_err!(
|
||||
sess,
|
||||
span,
|
||||
E0106,
|
||||
"missing lifetime specifier{}",
|
||||
if count > 1 { "s" } else { "" }
|
||||
);
|
||||
|
||||
let msg: Cow<'static, str> = if count > 1 {
|
||||
format!("expected {} lifetime parameters", count).into()
|
||||
} else {
|
||||
"expected lifetime parameter".into()
|
||||
};
|
||||
|
||||
err.span_label(span, msg);
|
||||
|
||||
err
|
||||
)
|
||||
}
|
||||
|
||||
fn add_missing_lifetime_specifiers_label(
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
count: usize,
|
||||
) {
|
||||
if count > 1 {
|
||||
err.span_label(span, format!("expected {} lifetime parameters", count));
|
||||
} else {
|
||||
err.span_label(span, "expected lifetime parameter");
|
||||
};
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Methods to faciliate working with signed integers stored in a u128
|
||||
// Methods to facilitate working with signed integers stored in a u128
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub fn sign_extend(value: u128, size: Size) -> u128 {
|
||||
|
@ -181,7 +181,7 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
#[inline]
|
||||
pub fn is_null_ptr(self, cx: impl HasDataLayout) -> bool {
|
||||
match self {
|
||||
Scalar::Bits { bits, size } => {
|
||||
Scalar::Bits { bits, size } => {
|
||||
assert_eq!(size as u64, cx.data_layout().pointer_size.bytes());
|
||||
bits == 0
|
||||
},
|
||||
@ -189,14 +189,6 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_null(self) -> bool {
|
||||
match self {
|
||||
Scalar::Bits { bits, .. } => bits == 0,
|
||||
Scalar::Ptr(_) => false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_bool(b: bool) -> Self {
|
||||
Scalar::Bits { bits: b as u128, size: 1 }
|
||||
|
@ -469,7 +469,7 @@ pub enum BorrowKind {
|
||||
/// }
|
||||
///
|
||||
/// This can't be a shared borrow because mutably borrowing (*x as Some).0
|
||||
/// should not prevent `if let None = x { ... }`, for example, becase the
|
||||
/// should not prevent `if let None = x { ... }`, for example, because the
|
||||
/// mutating `(*x as Some).0` can't affect the discriminant of `x`.
|
||||
/// We can also report errors with this kind of borrow differently.
|
||||
Shallow,
|
||||
@ -2065,9 +2065,8 @@ pub struct SourceScopeLocalData {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Operands
|
||||
|
||||
/// These are values that can appear inside an rvalue (or an index
|
||||
/// place). They are intentionally limited to prevent rvalues from
|
||||
/// being nested in one another.
|
||||
/// These are values that can appear inside an rvalue. They are intentionally
|
||||
/// limited to prevent rvalues from being nested in one another.
|
||||
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
|
||||
pub enum Operand<'tcx> {
|
||||
/// Copy: The value must be available for use afterwards.
|
||||
|
@ -412,7 +412,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
flags.push(("crate_local".to_owned(), None));
|
||||
}
|
||||
|
||||
// Allow targetting all integers using `{integral}`, even if the exact type was resolved
|
||||
// Allow targeting all integers using `{integral}`, even if the exact type was resolved
|
||||
if self_ty.is_integral() {
|
||||
flags.push(("_Self".to_owned(), Some("{integral}".to_owned())));
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ impl<'a, 'b, 'gcx, 'tcx> AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
|
||||
let value = self.selcx.infcx().resolve_type_vars_if_possible(value);
|
||||
|
||||
if !value.has_projections() {
|
||||
value.clone()
|
||||
value
|
||||
} else {
|
||||
value.fold_with(self)
|
||||
}
|
||||
|
@ -967,7 +967,7 @@ impl<'tcx> PolyFnSig<'tcx> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
|
||||
}
|
||||
pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.output().clone())
|
||||
self.map_bound_ref(|fn_sig| fn_sig.output())
|
||||
}
|
||||
pub fn variadic(&self) -> bool {
|
||||
self.skip_binder().variadic
|
||||
|
@ -761,7 +761,7 @@ impl Builder<'a, 'll, 'tcx> {
|
||||
fty, asm, cons, volatile, alignstack, dia);
|
||||
Some(self.call(v, inputs, None))
|
||||
} else {
|
||||
// LLVM has detected an issue with our constaints, bail out
|
||||
// LLVM has detected an issue with our constraints, bail out
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -284,8 +284,13 @@ impl UnusedParens {
|
||||
parser::contains_exterior_struct_lit(&inner)
|
||||
};
|
||||
if !necessary {
|
||||
let pattern = pprust::expr_to_string(value);
|
||||
Self::remove_outer_parens(cx, value.span, &pattern, msg);
|
||||
let expr_text = if let Ok(snippet) = cx.sess().source_map()
|
||||
.span_to_snippet(value.span) {
|
||||
snippet
|
||||
} else {
|
||||
pprust::expr_to_string(value)
|
||||
};
|
||||
Self::remove_outer_parens(cx, value.span, &expr_text, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -295,8 +300,13 @@ impl UnusedParens {
|
||||
value: &ast::Pat,
|
||||
msg: &str) {
|
||||
if let ast::PatKind::Paren(_) = value.node {
|
||||
let pattern = pprust::pat_to_string(value);
|
||||
Self::remove_outer_parens(cx, value.span, &pattern, msg);
|
||||
let pattern_text = if let Ok(snippet) = cx.sess().source_map()
|
||||
.span_to_snippet(value.span) {
|
||||
snippet
|
||||
} else {
|
||||
pprust::pat_to_string(value)
|
||||
};
|
||||
Self::remove_outer_parens(cx, value.span, &pattern_text, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ macro_rules! provide {
|
||||
|
||||
let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
|
||||
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
|
||||
.expect("CrateStore crated ata is not a CrateMetadata");
|
||||
.expect("CrateStore created data is not a CrateMetadata");
|
||||
$compute
|
||||
})*
|
||||
|
||||
|
@ -129,7 +129,7 @@ pub fn op_to_const<'tcx>(
|
||||
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= op.layout.size.bytes());
|
||||
let mut alloc = alloc.clone();
|
||||
alloc.align = align;
|
||||
// FIXME shouldnt it be the case that `mark_static_initialized` has already
|
||||
// FIXME shouldn't it be the case that `mark_static_initialized` has already
|
||||
// interned this? I thought that is the entire point of that `FinishStatic` stuff?
|
||||
let alloc = ecx.tcx.intern_const_alloc(alloc);
|
||||
ConstValue::ByRef(ptr.alloc_id, alloc, ptr.offset)
|
||||
|
@ -2279,7 +2279,7 @@ fn demo<'a>(s: &'a mut S<'a>) -> &'a mut String { let p = &mut *(*s).data; p }
|
||||
|
||||
Note that this approach needs a reference to S with lifetime `'a`.
|
||||
Nothing shorter than `'a` will suffice: a shorter lifetime would imply
|
||||
that after `demo` finishes excuting, something else (such as the
|
||||
that after `demo` finishes executing, something else (such as the
|
||||
destructor!) could access `s.data` after the end of that shorter
|
||||
lifetime, which would again violate the `&mut`-borrow's exclusive
|
||||
access.
|
||||
|
@ -1048,7 +1048,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
if let Some(constructors) = pat_constructors(cx, v[0], pcx) {
|
||||
debug!("is_useful - expanding constructors: {:#?}", constructors);
|
||||
split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
|
||||
is_useful_specialized(cx, matrix, v, c.clone(), pcx.ty, witness)
|
||||
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
|
||||
).find(|result| result.is_useful()).unwrap_or(NotUseful)
|
||||
} else {
|
||||
debug!("is_useful - expanding wildcard");
|
||||
@ -1096,7 +1096,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
|
||||
if missing_ctors.is_empty() && !is_non_exhaustive {
|
||||
split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
|
||||
is_useful_specialized(cx, matrix, v, c.clone(), pcx.ty, witness)
|
||||
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
|
||||
}).find(|result| result.is_useful()).unwrap_or(NotUseful)
|
||||
} else {
|
||||
let matrix = rows.iter().filter_map(|r| {
|
||||
|
@ -556,7 +556,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
)?;
|
||||
}
|
||||
} else {
|
||||
// Uh, that shouln't happen... the function did not intend to return
|
||||
// Uh, that shouldn't happen... the function did not intend to return
|
||||
return err!(Unreachable);
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ impl<'a, 'b, 'c, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Really we shouldnt clone memory, ever. Snapshot machinery should instad
|
||||
// FIXME: Really we shouldn't clone memory, ever. Snapshot machinery should instead
|
||||
// carefully copy only the reachable parts.
|
||||
impl<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>>
|
||||
Clone for Memory<'a, 'mir, 'tcx, M>
|
||||
@ -658,7 +658,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
}
|
||||
|
||||
/// It is the caller's responsibility to handle undefined and pointer bytes.
|
||||
/// However, this still checks that there are no relocations on the *egdes*.
|
||||
/// However, this still checks that there are no relocations on the *edges*.
|
||||
#[inline]
|
||||
fn get_bytes_with_undef_and_ptr(
|
||||
&self,
|
||||
@ -1098,7 +1098,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Error if there are relocations overlapping with the egdes of the
|
||||
/// Error if there are relocations overlapping with the edges of the
|
||||
/// given memory range.
|
||||
#[inline]
|
||||
fn check_relocation_edges(&self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
|
||||
|
@ -357,14 +357,14 @@ fn from_known_layout<'tcx>(
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
/// Try reading a value in memory; this is interesting particularily for ScalarPair.
|
||||
/// Try reading a value in memory; this is interesting particularly for ScalarPair.
|
||||
/// Return None if the layout does not permit loading this as a value.
|
||||
pub(super) fn try_read_value_from_mplace(
|
||||
&self,
|
||||
mplace: MPlaceTy<'tcx, M::PointerTag>,
|
||||
) -> EvalResult<'tcx, Option<Value<M::PointerTag>>> {
|
||||
if mplace.layout.is_unsized() {
|
||||
// Dont touch unsized
|
||||
// Don't touch unsized
|
||||
return Ok(None);
|
||||
}
|
||||
let (ptr, ptr_align) = mplace.to_scalar_ptr_align();
|
||||
|
@ -230,7 +230,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
),
|
||||
}
|
||||
}
|
||||
// non-ZST also have to be dereferencable
|
||||
// non-ZST also have to be dereferenceable
|
||||
if size != Size::ZERO {
|
||||
let ptr = try_validation!(place.ptr.to_ptr(),
|
||||
"integer pointer in non-ZST reference", path);
|
||||
@ -272,7 +272,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
// FIXME: Check if the signature matches
|
||||
}
|
||||
// This should be all the primitive types
|
||||
ty::Never => bug!("Uninhabited type should have been catched earlier"),
|
||||
ty::Never => bug!("Uninhabited type should have been caught earlier"),
|
||||
_ => bug!("Unexpected primitive type {}", value.layout.ty)
|
||||
}
|
||||
Ok(())
|
||||
|
@ -166,12 +166,12 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// With eRFC 2497, we need to check whether an expression is ambigious and warn or error
|
||||
/// With eRFC 2497, we need to check whether an expression is ambiguous and warn or error
|
||||
/// depending on the edition, this function handles that.
|
||||
fn while_if_let_ambiguity(&self, expr: &P<Expr>) {
|
||||
if let Some((span, op_kind)) = self.while_if_let_expr_ambiguity(&expr) {
|
||||
let mut err = self.err_handler().struct_span_err(
|
||||
span, &format!("ambigious use of `{}`", op_kind.to_string())
|
||||
span, &format!("ambiguous use of `{}`", op_kind.to_string())
|
||||
);
|
||||
|
||||
err.note(
|
||||
@ -193,9 +193,9 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
|
||||
/// With eRFC 2497 adding if-let chains, there is a requirement that the parsing of
|
||||
/// `&&` and `||` in a if-let statement be unambigious. This function returns a span and
|
||||
/// a `BinOpKind` (either `&&` or `||` depending on what was ambigious) if it is determined
|
||||
/// that the current expression parsed is ambigious and will break in future.
|
||||
/// `&&` and `||` in a if-let statement be unambiguous. This function returns a span and
|
||||
/// a `BinOpKind` (either `&&` or `||` depending on what was ambiguous) if it is determined
|
||||
/// that the current expression parsed is ambiguous and will break in future.
|
||||
fn while_if_let_expr_ambiguity(&self, expr: &P<Expr>) -> Option<(Span, BinOpKind)> {
|
||||
debug!("while_if_let_expr_ambiguity: expr.node: {:?}", expr.node);
|
||||
match &expr.node {
|
||||
@ -203,12 +203,12 @@ impl<'a> AstValidator<'a> {
|
||||
Some((expr.span, op.node))
|
||||
},
|
||||
ExprKind::Range(ref lhs, ref rhs, _) => {
|
||||
let lhs_ambigious = lhs.as_ref()
|
||||
let lhs_ambiguous = lhs.as_ref()
|
||||
.and_then(|lhs| self.while_if_let_expr_ambiguity(lhs));
|
||||
let rhs_ambigious = rhs.as_ref()
|
||||
let rhs_ambiguous = rhs.as_ref()
|
||||
.and_then(|rhs| self.while_if_let_expr_ambiguity(rhs));
|
||||
|
||||
lhs_ambigious.or(rhs_ambigious)
|
||||
lhs_ambiguous.or(rhs_ambiguous)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ impl Align {
|
||||
}
|
||||
|
||||
/// Lower the alignment, if necessary, such that the given offset
|
||||
/// is aligned to it (the offset is a multiple of the aligment).
|
||||
/// is aligned to it (the offset is a multiple of the alignment).
|
||||
pub fn restrict_for_offset(self, offset: Size) -> Align {
|
||||
self.min(Align::max_for_offset(offset))
|
||||
}
|
||||
|
@ -111,34 +111,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let expr_ty = self.resolve_type_vars_with_obligations(checked_ty);
|
||||
let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
|
||||
|
||||
// If the expected type is an enum with any variants whose sole
|
||||
// field is of the found type, suggest such variants. See Issue
|
||||
// #42764.
|
||||
// If the expected type is an enum (Issue #55250) with any variants whose
|
||||
// sole field is of the found type, suggest such variants. (Issue #42764)
|
||||
if let ty::Adt(expected_adt, substs) = expected.sty {
|
||||
let mut compatible_variants = expected_adt.variants
|
||||
.iter()
|
||||
.filter(|variant| variant.fields.len() == 1)
|
||||
.filter_map(|variant| {
|
||||
let sole_field = &variant.fields[0];
|
||||
let sole_field_ty = sole_field.ty(self.tcx, substs);
|
||||
if self.can_coerce(expr_ty, sole_field_ty) {
|
||||
let variant_path = self.tcx.item_path_str(variant.did);
|
||||
Some(variant_path.trim_left_matches("std::prelude::v1::").to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).peekable();
|
||||
if expected_adt.is_enum() {
|
||||
let mut compatible_variants = expected_adt.variants
|
||||
.iter()
|
||||
.filter(|variant| variant.fields.len() == 1)
|
||||
.filter_map(|variant| {
|
||||
let sole_field = &variant.fields[0];
|
||||
let sole_field_ty = sole_field.ty(self.tcx, substs);
|
||||
if self.can_coerce(expr_ty, sole_field_ty) {
|
||||
let variant_path = self.tcx.item_path_str(variant.did);
|
||||
Some(variant_path.trim_left_matches("std::prelude::v1::").to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).peekable();
|
||||
|
||||
if compatible_variants.peek().is_some() {
|
||||
let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr));
|
||||
let suggestions = compatible_variants.map(|v|
|
||||
format!("{}({})", v, expr_text)).collect::<Vec<_>>();
|
||||
err.span_suggestions_with_applicability(
|
||||
expr.span,
|
||||
"try using a variant of the expected type",
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
if compatible_variants.peek().is_some() {
|
||||
let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr));
|
||||
let suggestions = compatible_variants
|
||||
.map(|v| format!("{}({})", v, expr_text)).collect::<Vec<_>>();
|
||||
err.span_suggestions_with_applicability(
|
||||
expr.span,
|
||||
"try using a variant of the expected type",
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5198,7 +5198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
} else {
|
||||
// If no type arguments were provided, we have to infer them.
|
||||
// This case also occurs as a result of some malformed input, e.g.
|
||||
// a lifetime argument being given instead of a type paramter.
|
||||
// a lifetime argument being given instead of a type parameter.
|
||||
// Using inference instead of `Error` gives better error messages.
|
||||
self.var_for_def(span, param)
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
|
||||
} // if may_define_existential_type
|
||||
|
||||
// now register the bounds on the parameters of the existential type
|
||||
// so the parameters given by the function need to fulfil them
|
||||
// so the parameters given by the function need to fulfill them
|
||||
// ```rust
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// fn foo<U>() -> Foo<U> { .. *}
|
||||
|
@ -269,7 +269,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||
// exactly one (non-phantom) field has changed its
|
||||
// type, which we will expect to be the pointer that
|
||||
// is becoming fat (we could probably generalize this
|
||||
// to mutiple thin pointers of the same type becoming
|
||||
// to multiple thin pointers of the same type becoming
|
||||
// fat, but we don't). In this case:
|
||||
//
|
||||
// - `extra` has type `T` before and type `T` after
|
||||
|
@ -3632,7 +3632,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
|
||||
fields.iter().map(|&Spanned { node: ref fp, .. }|
|
||||
format!("{}: {}", fp.ident, name_from_pat(&*fp.pat)))
|
||||
.collect::<Vec<String>>().join(", "),
|
||||
if etc { ", ..." } else { "" }
|
||||
if etc { ", .." } else { "" }
|
||||
)
|
||||
}
|
||||
PatKind::Tuple(ref elts, _) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
|
||||
|
@ -198,12 +198,12 @@ impl f32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a number composed of the magnitude of one number and the sign of
|
||||
/// another.
|
||||
/// Returns a number composed of the magnitude of `self` and the sign of
|
||||
/// `y`.
|
||||
///
|
||||
/// Equal to `self` if the sign of `self` and `y` are the same, otherwise
|
||||
/// equal to `-y`. If `self` is a `NAN`, then a `NAN` with the sign of `y`
|
||||
/// is returned.
|
||||
/// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
|
||||
/// `y` is returned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -176,12 +176,12 @@ impl f64 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a number composed of the magnitude of one number and the sign of
|
||||
/// another.
|
||||
/// Returns a number composed of the magnitude of `self` and the sign of
|
||||
/// `y`.
|
||||
///
|
||||
/// Equal to `self` if the sign of `self` and `y` are the same, otherwise
|
||||
/// equal to `-y`. If `self` is a `NAN`, then a `NAN` with the sign of `y`
|
||||
/// is returned.
|
||||
/// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
|
||||
/// `y` is returned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -8,72 +8,713 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[doc(keyword = "fn")]
|
||||
#[doc(keyword = "as")]
|
||||
//
|
||||
/// The `fn` keyword.
|
||||
/// The keyword for casting a value to a type.
|
||||
///
|
||||
/// The `fn` keyword is used to declare a function.
|
||||
///
|
||||
/// Example:
|
||||
/// `as` is most commonly used to turn primitive types into other primitive types, but it has other
|
||||
/// uses that include turning pointers into addresses, addresses into pointers, and pointers into
|
||||
/// other pointers.
|
||||
///
|
||||
/// ```rust
|
||||
/// fn some_function() {
|
||||
/// // code goes in here
|
||||
/// let thing1: u8 = 89.0 as u8;
|
||||
/// assert_eq!('B' as u32, 66);
|
||||
/// assert_eq!(thing1 as char, 'Y');
|
||||
/// let thing2: f32 = thing1 as f32 + 10.5;
|
||||
/// assert_eq!(true as u8 + thing2 as u8, 100);
|
||||
/// ```
|
||||
///
|
||||
/// In general, any cast that can be performed via ascribing the type can also be done using `as`,
|
||||
/// so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: `let x: u32
|
||||
/// = 123` would be best in that situation). The same is not true in the other direction, however,
|
||||
/// explicitly using `as` allows a few more coercions that aren't allowed implicitly, such as
|
||||
/// changing the type of a raw pointer or turning closures into raw pointers.
|
||||
///
|
||||
/// Other places `as` is used include as extra syntax for [`crate`] and `use`, to change the name
|
||||
/// something is imported as.
|
||||
///
|
||||
/// For more information on what `as` is capable of, see the [Reference]
|
||||
///
|
||||
/// [Reference]:
|
||||
/// https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
|
||||
/// [`crate`]: keyword.crate.html
|
||||
mod as_keyword { }
|
||||
|
||||
#[doc(keyword = "const")]
|
||||
//
|
||||
/// The keyword for defining constants.
|
||||
///
|
||||
/// Sometimes a certain value is used many times throughout a program, and it can become
|
||||
/// inconvenient to copy it over and over. What's more, it's not always possible or desirable to
|
||||
/// make it a variable that gets carried around to each function that needs it. In these cases, the
|
||||
/// `const` keyword provides a convenient alternative to code duplication.
|
||||
///
|
||||
/// ```rust
|
||||
/// const THING: u32 = 0xABAD1DEA;
|
||||
///
|
||||
/// let foo = 123 + THING;
|
||||
/// ```
|
||||
///
|
||||
/// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the
|
||||
/// compiler figure it out. Any constant value can be defined in a const, which in practice happens
|
||||
/// to be most things that would be reasonable to have a constant (barring `const fn`s, coming
|
||||
/// soon). For example, you can't have a File as a `const`.
|
||||
///
|
||||
/// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses
|
||||
/// all others in a Rust program. For example, if you wanted to define a constant string, it would
|
||||
/// look like this:
|
||||
///
|
||||
/// ```rust
|
||||
/// const WORDS: &'static str = "hello rust!";
|
||||
/// ```
|
||||
///
|
||||
/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
|
||||
///
|
||||
/// ```rust
|
||||
/// const WORDS: &str = "hello convenience!";
|
||||
/// ```
|
||||
///
|
||||
/// `const` items looks remarkably similar to `static` items, which introduces some confusion as
|
||||
/// to which one should be used at which times. To put it simply, constants are inlined wherever
|
||||
/// they're used, making using them identical to simply replacing the name of the const with its
|
||||
/// value. Static variables on the other hand point to a single location in memory, which all
|
||||
/// accesses share. This means that, unlike with constants, they can't have destructors, and act as
|
||||
/// a single value across the entire codebase.
|
||||
///
|
||||
/// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE.
|
||||
///
|
||||
/// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const
|
||||
/// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs.
|
||||
///
|
||||
/// For more detail on `const`, see the [Rust Book] or the [Reference]
|
||||
///
|
||||
/// [pointer]: primitive.pointer.html
|
||||
/// [Rust Book]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html
|
||||
mod const_keyword { }
|
||||
|
||||
#[doc(keyword = "crate")]
|
||||
//
|
||||
/// The `crate` keyword.
|
||||
///
|
||||
/// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are
|
||||
/// used to specify a dependency on a crate external to the one it's declared in. Crates are the
|
||||
/// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can
|
||||
/// be read about crates in the [Reference].
|
||||
///
|
||||
/// ```rust ignore
|
||||
/// extern crate rand;
|
||||
/// extern crate my_crate as thing;
|
||||
/// extern crate std; // implicitly added to the root of every Rust project
|
||||
/// ```
|
||||
///
|
||||
/// The `as` keyword can be used to change what the crate is referred to as in your project. If a
|
||||
/// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores.
|
||||
///
|
||||
/// `crate` is also used as in conjunction with `pub` to signify that the item it's attached to
|
||||
/// is public only to other members of the same crate it's in.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_imports)]
|
||||
/// pub(crate) use std::io::Error as IoError;
|
||||
/// pub(crate) enum CoolMarkerType { }
|
||||
/// pub struct PublicThing {
|
||||
/// pub(crate) semi_secret_thing: bool,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// For more information about functions, take a look at the [Rust Book][book].
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html
|
||||
mod crate_keyword { }
|
||||
|
||||
#[doc(keyword = "enum")]
|
||||
//
|
||||
/// For defining enumerations.
|
||||
///
|
||||
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
|
||||
/// Enums in Rust are similar to those of other compiled languages like C, but have important
|
||||
/// differences that make them considerably more powerful. What Rust calls enums are more commonly
|
||||
/// known as [Algebraic Data Types] if you're coming from a functional programming background. The
|
||||
/// important detail is that each enum variant can have data to go along with it.
|
||||
///
|
||||
/// ```rust
|
||||
/// # struct Coord;
|
||||
/// enum SimpleEnum {
|
||||
/// FirstVariant,
|
||||
/// SecondVariant,
|
||||
/// ThirdVariant,
|
||||
/// }
|
||||
///
|
||||
/// enum Location {
|
||||
/// Unknown,
|
||||
/// Anonymous,
|
||||
/// Known(Coord),
|
||||
/// }
|
||||
///
|
||||
/// enum ComplexEnum {
|
||||
/// Nothing,
|
||||
/// Something(u32),
|
||||
/// LotsOfThings {
|
||||
/// usual_struct_stuff: bool,
|
||||
/// blah: String,
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// enum EmptyEnum { }
|
||||
/// ```
|
||||
///
|
||||
/// The first enum shown is the usual kind of enum you'd find in a C-style language. The second
|
||||
/// shows off a hypothetical example of something storing location data, with `Coord` being any
|
||||
/// other type that's needed, for example a struct. The third example demonstrates the kind of
|
||||
/// data a variant can store, ranging from nothing, to a tuple, to an anonymous struct.
|
||||
///
|
||||
/// Instantiating enum variants involves explicitly using the enum's name as its namespace,
|
||||
/// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above.
|
||||
/// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data
|
||||
/// is added as the type describes, for example `Option::Some(123)`. The same follows with
|
||||
/// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff:
|
||||
/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be
|
||||
/// instantiated at all, and are used mainly to mess with the type system in interesting ways.
|
||||
///
|
||||
/// For more information, take a look at the [Rust Book] or the [Reference]
|
||||
///
|
||||
/// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type
|
||||
/// [`Option`]: option/enum.Option.html
|
||||
/// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html
|
||||
mod enum_keyword { }
|
||||
|
||||
#[doc(keyword = "extern")]
|
||||
//
|
||||
/// For external connections in Rust code.
|
||||
///
|
||||
/// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`]
|
||||
/// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate
|
||||
/// lazy_static;`. The other use is in foreign function interfaces (FFI).
|
||||
///
|
||||
/// `extern` is used in two different contexts within FFI. The first is in the form of external
|
||||
/// blocks, for declaring function interfaces that Rust code can call foreign code by.
|
||||
///
|
||||
/// ```rust ignore
|
||||
/// #[link(name = "my_c_library")]
|
||||
/// extern "C" {
|
||||
/// fn my_c_function(x: i32) -> bool;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This code would attempt to link with `libmy_c_library.so` on unix-like systems and
|
||||
/// `my_c_library.dll` on Windows at runtime, and panic if it can't find something to link to. Rust
|
||||
/// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with
|
||||
/// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs.
|
||||
///
|
||||
/// The mirror use case of FFI is also done via the `extern` keyword:
|
||||
///
|
||||
/// ```rust
|
||||
/// #[no_mangle]
|
||||
/// pub extern fn callable_from_c(x: i32) -> bool {
|
||||
/// x % 3 == 0
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the
|
||||
/// function could be used as if it was from any other library.
|
||||
///
|
||||
/// For more information on FFI, check the [Rust book] or the [Reference].
|
||||
///
|
||||
/// [Rust book]:
|
||||
/// https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html
|
||||
mod extern_keyword { }
|
||||
|
||||
#[doc(keyword = "fn")]
|
||||
//
|
||||
/// The keyword for defining functions.
|
||||
///
|
||||
/// Functions are the primary way code is executed within Rust. Function blocks, usually just
|
||||
/// called functions, can be defined in a variety of different places and be assigned many
|
||||
/// different attributes and modifiers.
|
||||
///
|
||||
/// Standalone functions that just sit within a module not attached to anything else are common,
|
||||
/// but most functions will end up being inside [`impl`] blocks, either on another type itself, or
|
||||
/// as a trait impl for that type.
|
||||
///
|
||||
/// ```rust
|
||||
/// fn standalone_function() {
|
||||
/// // code
|
||||
/// }
|
||||
///
|
||||
/// pub fn public_thing(argument: bool) -> String {
|
||||
/// // code
|
||||
/// # "".to_string()
|
||||
/// }
|
||||
///
|
||||
/// struct Thing {
|
||||
/// foo: i32,
|
||||
/// }
|
||||
///
|
||||
/// impl Thing {
|
||||
/// pub fn new() -> Self {
|
||||
/// Self {
|
||||
/// foo: 42,
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`,
|
||||
/// functions can also declare a list of type parameters along with trait bounds that they fall
|
||||
/// into.
|
||||
///
|
||||
/// ```rust
|
||||
/// fn generic_function<T: Clone>(x: T) -> (T, T, T) {
|
||||
/// (x.clone(), x.clone(), x.clone())
|
||||
/// }
|
||||
///
|
||||
/// fn generic_where<T>(x: T) -> T
|
||||
/// where T: std::ops::Add<Output=T> + Copy
|
||||
/// {
|
||||
/// x + x + x
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Declaring trait bounds in the angle brackets is functionally identical to using a `where`
|
||||
/// clause. It's up to the programmer to decide which works better in each situation, but `where`
|
||||
/// tends to be better when things get longer than one line.
|
||||
///
|
||||
/// Along with being made public via `pub`, `fn` can also have an [`extern`] added for use in
|
||||
/// FFI.
|
||||
///
|
||||
/// For more information on the various types of functions and how they're used, consult the [Rust
|
||||
/// book] or the [Reference].
|
||||
///
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [`extern`]: keyword.extern.html
|
||||
/// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/functions.html
|
||||
mod fn_keyword { }
|
||||
|
||||
#[doc(keyword = "for")]
|
||||
//
|
||||
/// The `for` keyword.
|
||||
///
|
||||
/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as
|
||||
/// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more
|
||||
/// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice
|
||||
/// within Rust, which is to loop over an iterator until that iterator returns None (or `break`
|
||||
/// is called).
|
||||
///
|
||||
/// ```rust
|
||||
/// for i in 0..5 {
|
||||
/// println!("{}", i * 2);
|
||||
/// }
|
||||
///
|
||||
/// for i in std::iter::repeat(5) {
|
||||
/// println!("turns out {} never stops being 5", i);
|
||||
/// break; // would loop forever otherwise
|
||||
/// }
|
||||
///
|
||||
/// 'outer: for x in 5..50 {
|
||||
/// for y in 0..10 {
|
||||
/// if x == y {
|
||||
/// break 'outer;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// As shown in the example above, `for` loops (along with all other loops) can be tagged, using
|
||||
/// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the
|
||||
/// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely
|
||||
/// not a goto.
|
||||
///
|
||||
/// A `for` loop expands as shown:
|
||||
///
|
||||
/// ```rust
|
||||
/// # fn code() { }
|
||||
/// # let iterator = 0..2;
|
||||
/// for loop_variable in iterator {
|
||||
/// code()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```rust
|
||||
/// # fn code() { }
|
||||
/// # let iterator = 0..2;
|
||||
/// {
|
||||
/// let mut _iter = std::iter::IntoIterator::into_iter(iterator);
|
||||
/// loop {
|
||||
/// match _iter.next() {
|
||||
/// Some(loop_variable) => {
|
||||
/// code()
|
||||
/// },
|
||||
/// None => break,
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// More details on the functionality shown can be seen at the [`IntoIterator`] docs.
|
||||
///
|
||||
/// For more information on for-loops, see the [Rust book] or the [Reference].
|
||||
///
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [`IntoIterator`]: iter/trait.IntoIterator.html
|
||||
/// [Rust book]:
|
||||
/// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops
|
||||
mod for_keyword { }
|
||||
|
||||
#[doc(keyword = "if")]
|
||||
//
|
||||
/// If statements and expressions.
|
||||
///
|
||||
/// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in
|
||||
/// your code. However, unlike in most languages, `if` blocks can also act as expressions.
|
||||
///
|
||||
/// ```rust
|
||||
/// # let rude = true;
|
||||
/// if 1 == 2 {
|
||||
/// println!("whoops, mathematics broke");
|
||||
/// } else {
|
||||
/// println!("everything's fine!");
|
||||
/// }
|
||||
///
|
||||
/// let greeting = if rude {
|
||||
/// "sup nerd."
|
||||
/// } else {
|
||||
/// "hello, friend!"
|
||||
/// };
|
||||
///
|
||||
/// if let Ok(x) = "123".parse::<i32>() {
|
||||
/// println!("{} double that and you get {}!", greeting, x * 2);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Shown above are the three typical forms an `if` block comes in. First is the usual kind of
|
||||
/// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an
|
||||
/// expression, which is only possible if all branches return the same type. An `if` expression can
|
||||
/// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which
|
||||
/// behaves similarly to using a `match` expression:
|
||||
///
|
||||
/// ```rust
|
||||
/// if let Some(x) = Some(123) {
|
||||
/// // code
|
||||
/// # let _ = x;
|
||||
/// } else {
|
||||
/// // something else
|
||||
/// }
|
||||
///
|
||||
/// match Some(123) {
|
||||
/// Some(x) => {
|
||||
/// // code
|
||||
/// # let _ = x;
|
||||
/// },
|
||||
/// _ => {
|
||||
/// // something else
|
||||
/// },
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Each kind of `if` expression can be mixed and matched as needed.
|
||||
///
|
||||
/// ```rust
|
||||
/// if true == false {
|
||||
/// println!("oh no");
|
||||
/// } else if "something" == "other thing" {
|
||||
/// println!("oh dear");
|
||||
/// } else if let Some(200) = "blarg".parse::<i32>().ok() {
|
||||
/// println!("uh oh");
|
||||
/// } else {
|
||||
/// println!("phew, nothing's broken");
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching
|
||||
/// itself, allowing patterns such as `Some(x) if x > 200` to be used.
|
||||
///
|
||||
/// For more information on `if` expressions, see the [Rust book] or the [Reference].
|
||||
///
|
||||
/// [Rust book]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html
|
||||
mod if_keyword { }
|
||||
|
||||
#[doc(keyword = "impl")]
|
||||
//
|
||||
/// The implementation-defining keyword.
|
||||
///
|
||||
/// The `impl` keyword is primarily used to define implementations on types. Inherent
|
||||
/// implementations are standalone, while trait implementations are used to implement traits for
|
||||
/// types, or other traits.
|
||||
///
|
||||
/// Functions and consts can both be defined in an implementation. A function defined in an
|
||||
/// `impl` block can be standalone, meaning it would be called like `Foo::bar()`. If the function
|
||||
/// takes `self`, `&self`, or `&mut self` as its first argument, it can also be called using
|
||||
/// method-call syntax, a familiar feature to any object oriented programmer, like `foo.bar()`.
|
||||
///
|
||||
/// ```rust
|
||||
/// struct Example {
|
||||
/// number: i32,
|
||||
/// }
|
||||
///
|
||||
/// impl Example {
|
||||
/// fn boo() {
|
||||
/// println!("boo! Example::boo() was called!");
|
||||
/// }
|
||||
///
|
||||
/// fn answer(&mut self) {
|
||||
/// self.number += 42;
|
||||
/// }
|
||||
///
|
||||
/// fn get_number(&self) -> i32 {
|
||||
/// self.number
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// trait Thingy {
|
||||
/// fn do_thingy(&self);
|
||||
/// }
|
||||
///
|
||||
/// impl Thingy for Example {
|
||||
/// fn do_thingy(&self) {
|
||||
/// println!("doing a thing! also, number is {}!", self.number);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// For more information on implementations, see the [Rust book][book1] or the [Reference].
|
||||
///
|
||||
/// The other use of the `impl` keyword is in `impl Trait` syntax, which can be seen as a shorthand
|
||||
/// for "a concrete type that implements this trait". Its primary use is working with closures,
|
||||
/// which have type definitions generated at compile time that can't be simply typed out.
|
||||
///
|
||||
/// ```rust
|
||||
/// fn thing_returning_closure() -> impl Fn(i32) -> bool {
|
||||
/// println!("here's a closure for you!");
|
||||
/// |x: i32| x % 3 == 0
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// For more information on `impl Trait` syntax, see the [Rust book][book2].
|
||||
///
|
||||
/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch05-03-method-syntax.html
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/implementations.html
|
||||
/// [book2]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch10-02-traits.html#returning-traits
|
||||
mod impl_keyword { }
|
||||
|
||||
#[doc(keyword = "let")]
|
||||
//
|
||||
/// The `let` keyword.
|
||||
/// The variable binding keyword.
|
||||
///
|
||||
/// The `let` keyword is used to declare a variable.
|
||||
///
|
||||
/// Example:
|
||||
/// The primary use for the `let` keyword is in `let` statements, which are used to introduce a new
|
||||
/// set of variables into the current scope, as given by a pattern.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![allow(unused_assignments)]
|
||||
/// let x = 3; // We create a variable named `x` with the value `3`.
|
||||
/// let thing1: i32 = 100;
|
||||
/// let thing2 = 200 + thing1;
|
||||
///
|
||||
/// let mut changing_thing = true;
|
||||
/// changing_thing = false;
|
||||
///
|
||||
/// let (part1, part2) = ("first", "second");
|
||||
///
|
||||
/// struct Example {
|
||||
/// a: bool,
|
||||
/// b: u64,
|
||||
/// }
|
||||
///
|
||||
/// let Example { a, b: _ } = Example {
|
||||
/// a: true,
|
||||
/// b: 10004,
|
||||
/// };
|
||||
/// assert!(a);
|
||||
/// ```
|
||||
///
|
||||
/// By default, all variables are **not** mutable. If you want a mutable variable,
|
||||
/// you'll have to use the `mut` keyword.
|
||||
/// The pattern is most commonly a single variable, which means no pattern matching is done and
|
||||
/// the expression given is bound to the variable. Apart from that, patterns used in `let` bindings
|
||||
/// can be as complicated as needed, given that the pattern is exhaustive. See the [Rust
|
||||
/// book][book1] for more information on pattern matching. The type of the pattern is optionally
|
||||
/// given afterwards, but if left blank is automatically inferred by the compiler if possible.
|
||||
///
|
||||
/// Example:
|
||||
/// Variables in Rust are immutable by default, and require the `mut` keyword to be made mutable.
|
||||
///
|
||||
/// Multiple variables can be defined with the same name, known as shadowing. This doesn't affect
|
||||
/// the original variable in any way beyond being unable to directly access it beyond the point of
|
||||
/// shadowing. It continues to remain in scope, getting dropped only when it falls out of scope.
|
||||
/// Shadowed variables don't need to have the same type as the variables shadowing them.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![allow(unused_assignments)]
|
||||
/// let mut x = 3; // We create a mutable variable named `x` with the value `3`.
|
||||
///
|
||||
/// x += 4; // `x` is now equal to `7`.
|
||||
/// let shadowing_example = true;
|
||||
/// let shadowing_example = 123.4;
|
||||
/// let shadowing_example = shadowing_example as u32;
|
||||
/// let mut shadowing_example = format!("cool! {}", shadowing_example);
|
||||
/// shadowing_example += " something else!"; // not shadowing
|
||||
/// ```
|
||||
///
|
||||
/// For more information about the `let` keyword, take a look at the [Rust Book][book].
|
||||
/// Other places the `let` keyword is used include along with [`if`], in the form of `if let`
|
||||
/// expressions. They're useful if the pattern being matched isn't exhaustive, such as with
|
||||
/// enumerations. `while let` also exists, which runs a loop with a pattern matched value until
|
||||
/// that pattern can't be matched.
|
||||
///
|
||||
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html
|
||||
/// For more information on the `let` keyword, see the [Rust book] or the [Reference]
|
||||
///
|
||||
/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch06-02-match.html
|
||||
/// [`if`]: keyword.if.html
|
||||
/// [book2]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch18-01-all-the-places-for-patterns.html#let-statements
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/statements.html#let-statements
|
||||
mod let_keyword { }
|
||||
|
||||
#[doc(keyword = "struct")]
|
||||
#[doc(keyword = "loop")]
|
||||
//
|
||||
/// The `struct` keyword.
|
||||
/// The loop-defining keyword.
|
||||
///
|
||||
/// The `struct` keyword is used to define a struct type.
|
||||
/// `loop` is used to define the simplest kind of loop supported in Rust. It runs the code inside
|
||||
/// it until the code uses `break` or the program exits.
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// println!("hello world forever!");
|
||||
/// # break;
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
/// struct Foo {
|
||||
/// field1: u32,
|
||||
/// field2: String,
|
||||
/// let mut i = 0;
|
||||
/// loop {
|
||||
/// println!("i is {}", i);
|
||||
/// if i > 10 {
|
||||
/// break;
|
||||
/// }
|
||||
/// i += 1;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// There are different kinds of structs. For more information, take a look at the
|
||||
/// [Rust Book][book].
|
||||
/// Unlike the other kinds of loops in Rust (`while`, `while let`, and `for`), loops can be used as
|
||||
/// expressions that return values via `break`.
|
||||
///
|
||||
/// ```rust
|
||||
/// let mut i = 1;
|
||||
/// let something = loop {
|
||||
/// i *= 2;
|
||||
/// if i > 100 {
|
||||
/// break i;
|
||||
/// }
|
||||
/// };
|
||||
/// assert_eq!(something, 128);
|
||||
/// ```
|
||||
///
|
||||
/// Every `break` in a loop has to have the same type. When it's not explicitly giving something,
|
||||
/// `break;` returns `()`.
|
||||
///
|
||||
/// For more information on `loop` and loops in general, see the [Reference].
|
||||
///
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html
|
||||
mod loop_keyword { }
|
||||
|
||||
#[doc(keyword = "struct")]
|
||||
//
|
||||
/// The keyword used to define structs.
|
||||
///
|
||||
/// Structs in Rust come in three flavours: Structs with named fields, tuple structs, and unit
|
||||
/// structs.
|
||||
///
|
||||
/// ```rust
|
||||
/// struct Regular {
|
||||
/// field1: f32,
|
||||
/// field2: String,
|
||||
/// pub field3: bool
|
||||
/// }
|
||||
///
|
||||
/// struct Tuple(u32, String);
|
||||
///
|
||||
/// struct Unit;
|
||||
/// ```
|
||||
///
|
||||
/// Regular structs are the most commonly used. Each field defined within them has a name and a
|
||||
/// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a
|
||||
/// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding
|
||||
/// `pub` to a field makes it visible to code in other modules, as well as allowing it to be
|
||||
/// directly accessed and modified.
|
||||
///
|
||||
/// Tuple structs are similar to regular structs, but its fields have no names. They are used like
|
||||
/// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax. For accessing
|
||||
/// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`,
|
||||
/// etc, starting at zero.
|
||||
///
|
||||
/// Unit structs are most commonly used as marker. They have a size of zero bytes, but unlike empty
|
||||
/// enums they can be instantiated, making them isomorphic to the unit type `()`. Unit structs are
|
||||
/// useful when you need to implement a trait on something, but don't need to store any data inside
|
||||
/// it.
|
||||
///
|
||||
/// # Instantiation
|
||||
///
|
||||
/// Structs can be instantiated in different ways, all of which can be mixed and
|
||||
/// matched as needed. The most common way to make a new struct is via a constructor method such as
|
||||
/// `new()`, but when that isn't available (or you're writing the constructor itself), struct
|
||||
/// literal syntax is used:
|
||||
///
|
||||
/// ```rust
|
||||
/// # struct Foo { field1: f32, field2: String, etc: bool }
|
||||
/// let example = Foo {
|
||||
/// field1: 42.0,
|
||||
/// field2: "blah".to_string(),
|
||||
/// etc: true,
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// It's only possible to directly instantiate a struct using struct literal syntax when all of its
|
||||
/// fields are visible to you.
|
||||
///
|
||||
/// There are a handful of shortcuts provided to make writing constructors more convenient, most
|
||||
/// common of which is the Field Init shorthand. When there is a variable and a field of the same
|
||||
/// name, the assignment can be simplified from `field: field` into simply `field`. The following
|
||||
/// example of a hypothetical constructor demonstrates this:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct User {
|
||||
/// name: String,
|
||||
/// admin: bool,
|
||||
/// }
|
||||
///
|
||||
/// impl User {
|
||||
/// pub fn new(name: String) -> Self {
|
||||
/// Self {
|
||||
/// name,
|
||||
/// admin: false,
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Another shortcut for struct instantiation is available, used when you need to make a new
|
||||
/// struct that has the same values as most of a previous struct of the same type, called struct
|
||||
/// update syntax:
|
||||
///
|
||||
/// ```rust
|
||||
/// # struct Foo { field1: String, field2: () }
|
||||
/// # let thing = Foo { field1: "".to_string(), field2: () };
|
||||
/// let updated_thing = Foo {
|
||||
/// field1: "a new value".to_string(),
|
||||
/// ..thing
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's
|
||||
/// name as a prefix: `Foo(123, false, 0.1)`.
|
||||
///
|
||||
/// Empty structs are instantiated with just their name, and don't need anything else. `let thing =
|
||||
/// EmptyStruct;`
|
||||
///
|
||||
/// # Style conventions
|
||||
///
|
||||
/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a
|
||||
/// struct's list of fields can be omitted, it's usually kept for convenience in adding and
|
||||
/// removing fields down the line.
|
||||
///
|
||||
/// For more information on structs, take a look at the [Rust Book][book] or the
|
||||
/// [Reference][reference].
|
||||
///
|
||||
/// [`PhantomData`]: marker/struct.PhantomData.html
|
||||
/// [book]: https://doc.rust-lang.org/book/second-edition/ch05-01-defining-structs.html
|
||||
/// [reference]: https://doc.rust-lang.org/reference/items/structs.html
|
||||
mod struct_keyword { }
|
||||
|
@ -43,12 +43,12 @@ use time::Duration;
|
||||
/// use std::io::prelude::*;
|
||||
/// use std::net::TcpStream;
|
||||
///
|
||||
/// {
|
||||
/// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
/// let mut stream = TcpStream::connect("127.0.0.1:34254")?;
|
||||
///
|
||||
/// // ignore the Result
|
||||
/// let _ = stream.write(&[1]);
|
||||
/// let _ = stream.read(&mut [0; 128]); // ignore here too
|
||||
/// stream.write(&[1])?;
|
||||
/// stream.read(&mut [0; 128])?;
|
||||
/// Ok(())
|
||||
/// } // the stream is closed here
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -323,8 +323,8 @@ mod prim_never { }
|
||||
/// let s = String::from("love: ❤️");
|
||||
/// let v: Vec<char> = s.chars().collect();
|
||||
///
|
||||
/// assert_eq!(12, s.len() * std::mem::size_of::<u8>());
|
||||
/// assert_eq!(32, v.len() * std::mem::size_of::<char>());
|
||||
/// assert_eq!(12, std::mem::size_of_val(&s[..]));
|
||||
/// assert_eq!(32, std::mem::size_of_val(&v[..]));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
mod prim_char { }
|
||||
|
@ -1016,6 +1016,28 @@ impl fmt::Debug for Stdio {
|
||||
|
||||
#[stable(feature = "stdio_from", since = "1.20.0")]
|
||||
impl From<ChildStdin> for Stdio {
|
||||
/// Converts a `ChildStdin` into a `Stdio`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// `ChildStdin` will be converted to `Stdio` using `Stdio::from` under the hood.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::process::{Command, Stdio};
|
||||
///
|
||||
/// let reverse = Command::new("rev")
|
||||
/// .stdin(Stdio::piped())
|
||||
/// .spawn()
|
||||
/// .expect("failed reverse command");
|
||||
///
|
||||
/// let _echo = Command::new("echo")
|
||||
/// .arg("Hello, world!")
|
||||
/// .stdout(reverse.stdin.unwrap()) // Converted into a Stdio here
|
||||
/// .output()
|
||||
/// .expect("failed echo command");
|
||||
///
|
||||
/// // "!dlrow ,olleH" echoed to console
|
||||
/// ```
|
||||
fn from(child: ChildStdin) -> Stdio {
|
||||
Stdio::from_inner(child.into_inner().into())
|
||||
}
|
||||
@ -1023,6 +1045,28 @@ impl From<ChildStdin> for Stdio {
|
||||
|
||||
#[stable(feature = "stdio_from", since = "1.20.0")]
|
||||
impl From<ChildStdout> for Stdio {
|
||||
/// Converts a `ChildStdout` into a `Stdio`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// `ChildStdout` will be converted to `Stdio` using `Stdio::from` under the hood.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::process::{Command, Stdio};
|
||||
///
|
||||
/// let hello = Command::new("echo")
|
||||
/// .arg("Hello, world!")
|
||||
/// .stdout(Stdio::piped())
|
||||
/// .spawn()
|
||||
/// .expect("failed echo command");
|
||||
///
|
||||
/// let reverse = Command::new("rev")
|
||||
/// .stdin(hello.stdout.unwrap()) // Converted into a Stdio here
|
||||
/// .output()
|
||||
/// .expect("failed reverse command");
|
||||
///
|
||||
/// assert_eq!(reverse.stdout, b"!dlrow ,olleH\n");
|
||||
/// ```
|
||||
fn from(child: ChildStdout) -> Stdio {
|
||||
Stdio::from_inner(child.into_inner().into())
|
||||
}
|
||||
@ -1030,6 +1074,30 @@ impl From<ChildStdout> for Stdio {
|
||||
|
||||
#[stable(feature = "stdio_from", since = "1.20.0")]
|
||||
impl From<ChildStderr> for Stdio {
|
||||
/// Converts a `ChildStderr` into a `Stdio`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use std::process::{Command, Stdio};
|
||||
///
|
||||
/// let reverse = Command::new("rev")
|
||||
/// .arg("non_existing_file.txt")
|
||||
/// .stderr(Stdio::piped())
|
||||
/// .spawn()
|
||||
/// .expect("failed reverse command");
|
||||
///
|
||||
/// let cat = Command::new("cat")
|
||||
/// .arg("-")
|
||||
/// .stdin(reverse.stderr.unwrap()) // Converted into a Stdio here
|
||||
/// .output()
|
||||
/// .expect("failed echo command");
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// String::from_utf8_lossy(&cat.stdout),
|
||||
/// "rev: cannot open non_existing_file.txt: No such file or directory\n"
|
||||
/// );
|
||||
/// ```
|
||||
fn from(child: ChildStderr) -> Stdio {
|
||||
Stdio::from_inner(child.into_inner().into())
|
||||
}
|
||||
@ -1037,6 +1105,26 @@ impl From<ChildStderr> for Stdio {
|
||||
|
||||
#[stable(feature = "stdio_from", since = "1.20.0")]
|
||||
impl From<fs::File> for Stdio {
|
||||
/// Converts a `File` into a `Stdio`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// `File` will be converted to `Stdio` using `Stdio::from` under the hood.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use std::fs::File;
|
||||
/// use std::process::Command;
|
||||
///
|
||||
/// // With the `foo.txt` file containing `Hello, world!"
|
||||
/// let file = File::open("foo.txt").unwrap();
|
||||
///
|
||||
/// let reverse = Command::new("rev")
|
||||
/// .stdin(file) // Implicit File convertion into a Stdio
|
||||
/// .output()
|
||||
/// .expect("failed reverse command");
|
||||
///
|
||||
/// assert_eq!(reverse.stdout, b"!dlrow ,olleH");
|
||||
/// ```
|
||||
fn from(file: fs::File) -> Stdio {
|
||||
Stdio::from_inner(file.into_inner().into())
|
||||
}
|
||||
|
@ -97,7 +97,7 @@
|
||||
//! - A **multiprocessor** system executing multiple hardware threads
|
||||
//! at the same time: In multi-threaded scenarios, you can use two
|
||||
//! kinds of primitives to deal with synchronization:
|
||||
//! - [memory fences] to ensure memory accesses are made visibile to
|
||||
//! - [memory fences] to ensure memory accesses are made visible to
|
||||
//! other CPUs in the right order.
|
||||
//! - [atomic operations] to ensure simultaneous access to the same
|
||||
//! memory location doesn't lead to undefined behavior.
|
||||
|
@ -290,8 +290,8 @@ impl Once {
|
||||
}
|
||||
|
||||
/// Returns true if some `call_once` call has completed
|
||||
/// successfuly. Specifically, `is_completed` will return false in
|
||||
/// the following situtations:
|
||||
/// successfully. Specifically, `is_completed` will return false in
|
||||
/// the following situations:
|
||||
/// * `call_once` was not called at all,
|
||||
/// * `call_once` was called, but has not yet completed,
|
||||
/// * the `Once` instance is poisoned
|
||||
|
@ -96,7 +96,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
/// when the configuration predicate is true, or otherwise expand into an
|
||||
/// empty list of attributes.
|
||||
///
|
||||
/// Gives a compiler warning when the `cfg_attr` contains no attribtes and
|
||||
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
|
||||
/// is in the original source file. Gives a compiler error if the syntax of
|
||||
/// the attribute is incorrect
|
||||
fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
|
||||
@ -138,7 +138,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
};
|
||||
|
||||
// Check feature gate and lint on zero attributes in source. Even if the feature is gated,
|
||||
// we still compute as if it wasn't, since the emitted error will stop compilation futher
|
||||
// we still compute as if it wasn't, since the emitted error will stop compilation further
|
||||
// along the compilation.
|
||||
match (expanded_attrs.len(), gate_cfg_attr_multi) {
|
||||
(0, false) => {
|
||||
|
@ -905,7 +905,8 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result<bool, (String, &'
|
||||
"path" | "ty" => match *tok {
|
||||
TokenTree::Token(_, ref tok) => match *tok {
|
||||
OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) |
|
||||
Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true),
|
||||
Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi |
|
||||
BinOp(token::Or) => Ok(true),
|
||||
Ident(i, false) if i.name == "as" || i.name == "where" => Ok(true),
|
||||
_ => Ok(false)
|
||||
},
|
||||
|
@ -965,7 +965,7 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
|
||||
polarity,
|
||||
defaultness,
|
||||
folder.fold_generics(generics),
|
||||
ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref.clone())),
|
||||
ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref)),
|
||||
folder.fold_ty(ty),
|
||||
impl_items.move_flat_map(|item| folder.fold_impl_item(item)),
|
||||
),
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 307650500de5b44dc1047dc9d15e449e09d92b57
|
||||
Subproject commit 431766a3fbcfb6dafb2d5a3866c1609bf44ee554
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// run-pass
|
||||
// Test for issue #18804, #[linkage] does not propagate thorugh generic
|
||||
// Test for issue #18804, #[linkage] does not propagate through generic
|
||||
// functions. Failure results in a linker error.
|
||||
|
||||
// ignore-asmjs no weak symbol support
|
||||
|
16
src/test/run-pass/macros/issue-25274.rs
Normal file
16
src/test/run-pass/macros/issue-25274.rs
Normal file
@ -0,0 +1,16 @@
|
||||
macro_rules! test {
|
||||
(
|
||||
fn fun() -> Option<Box<$t:ty>>;
|
||||
) => {
|
||||
fn fun(x: $t) -> Option<Box<$t>>
|
||||
{ Some(Box::new(x)) }
|
||||
}
|
||||
}
|
||||
|
||||
test! {
|
||||
fn fun() -> Option<Box<i32>>;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", fun(0).unwrap());
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
// compile-flags:--test
|
||||
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
|
||||
// failure-status: 101
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
|
||||
// doctest fails at runtime
|
||||
/// ```
|
||||
|
@ -1,22 +1,22 @@
|
||||
|
||||
running 2 tests
|
||||
test $DIR/failed-doctest-output.rs - OtherStruct (line 26) ... FAILED
|
||||
test $DIR/failed-doctest-output.rs - SomeStruct (line 20) ... FAILED
|
||||
test $DIR/failed-doctest-output.rs - OtherStruct (line 27) ... FAILED
|
||||
test $DIR/failed-doctest-output.rs - SomeStruct (line 21) ... FAILED
|
||||
|
||||
failures:
|
||||
|
||||
---- $DIR/failed-doctest-output.rs - OtherStruct (line 26) stdout ----
|
||||
---- $DIR/failed-doctest-output.rs - OtherStruct (line 27) stdout ----
|
||||
error[E0425]: cannot find value `no` in this scope
|
||||
--> $DIR/failed-doctest-output.rs:27:1
|
||||
--> $DIR/failed-doctest-output.rs:28:1
|
||||
|
|
||||
3 | no
|
||||
| ^^ not found in this scope
|
||||
|
||||
thread '$DIR/failed-doctest-output.rs - OtherStruct (line 26)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13
|
||||
thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13
|
||||
note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
||||
|
||||
---- $DIR/failed-doctest-output.rs - SomeStruct (line 20) stdout ----
|
||||
thread '$DIR/failed-doctest-output.rs - SomeStruct (line 20)' panicked at 'test executable failed:
|
||||
---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ----
|
||||
thread '$DIR/failed-doctest-output.rs - SomeStruct (line 21)' panicked at 'test executable failed:
|
||||
|
||||
thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
|
||||
note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
||||
@ -25,8 +25,8 @@ note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
||||
|
||||
|
||||
failures:
|
||||
$DIR/failed-doctest-output.rs - OtherStruct (line 26)
|
||||
$DIR/failed-doctest-output.rs - SomeStruct (line 20)
|
||||
$DIR/failed-doctest-output.rs - OtherStruct (line 27)
|
||||
$DIR/failed-doctest-output.rs - SomeStruct (line 21)
|
||||
|
||||
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
|
||||
|
||||
|
42
src/test/rustdoc/issue-54478-demo-allocator.rs
Normal file
42
src/test/rustdoc/issue-54478-demo-allocator.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// Issue #54478: regression test showing that we can demonstrate
|
||||
// `#[global_allocator]` in code blocks built by `rustdoc`.
|
||||
//
|
||||
// ## Background
|
||||
//
|
||||
// Changes in lang-item visibility injected failures that were only
|
||||
// exposed when compiling with `-C prefer-dynamic`. But `rustdoc` used
|
||||
// `-C prefer-dynamic` (and had done so for years, for reasons we did
|
||||
// not document at that time).
|
||||
//
|
||||
// Rather than try to revise the visbility semanics, we instead
|
||||
// decided to change `rustdoc` to behave more like the compiler's
|
||||
// default setting, by leaving off `-C prefer-dynamic`.
|
||||
|
||||
// compile-flags:--test
|
||||
|
||||
//! This is a doc comment
|
||||
//!
|
||||
//! ```rust
|
||||
//! use std::alloc::*;
|
||||
//!
|
||||
//! #[global_allocator]
|
||||
//! static ALLOC: A = A;
|
||||
//!
|
||||
//! static mut HIT: bool = false;
|
||||
//!
|
||||
//! struct A;
|
||||
//!
|
||||
//! unsafe impl GlobalAlloc for A {
|
||||
//! unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
//! HIT = true;
|
||||
//! System.alloc(layout)
|
||||
//! }
|
||||
//! unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
//! System.dealloc(ptr, layout);
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! assert!(unsafe { HIT });
|
||||
//! }
|
||||
//! ```
|
@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/bound-lifetime-in-binding-only.rs:62:23
|
||||
|
|
||||
LL | fn elision<T: Fn() -> &i32>() {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it a 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/bound-lifetime-in-return-only.rs:44:23
|
||||
|
|
||||
LL | fn elision(_: fn() -> &i32) {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it a 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we do some basic error correcton in the tokeniser (and don't spew
|
||||
// Test that we do some basic error correction in the tokeniser (and don't spew
|
||||
// too many bogus errors).
|
||||
|
||||
fn foo() -> usize {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Test that cfg_attr doesn't emit any attributes when the
|
||||
// configuation variable is false. This mirrors `cfg-attr-multi-true.rs`
|
||||
// configuration variable is false. This mirrors `cfg-attr-multi-true.rs`
|
||||
|
||||
// compile-pass
|
||||
|
||||
|
@ -20,4 +20,20 @@ fn main() {
|
||||
let n: usize = 42;
|
||||
this_function_expects_a_double_option(n);
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try using a variant of the expected type
|
||||
}
|
||||
|
||||
|
||||
// But don't issue the "try using a variant" help if the one-"variant" ADT is
|
||||
// actually a one-field struct.
|
||||
|
||||
struct Payload;
|
||||
|
||||
struct Wrapper { payload: Payload }
|
||||
|
||||
struct Context { wrapper: Wrapper }
|
||||
|
||||
fn overton() {
|
||||
let _c = Context { wrapper: Payload{} };
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
@ -13,6 +13,15 @@ LL | this_function_expects_a_double_option(DoubleOption::FirstSome(n));
|
||||
LL | this_function_expects_a_double_option(DoubleOption::AlternativeSome(n));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-42764.rs:37:33
|
||||
|
|
||||
LL | let _c = Context { wrapper: Payload{} };
|
||||
| ^^^^^^^^^ expected struct `Wrapper`, found struct `Payload`
|
||||
|
|
||||
= note: expected type `Wrapper`
|
||||
found type `Payload`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
18
src/test/ui/foreign-fn-return-lifetime.fixed
Normal file
18
src/test/ui/foreign-fn-return-lifetime.fixed
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
extern "C" {
|
||||
pub fn g(_: &u8) -> &u8; // OK
|
||||
pub fn f() -> &'static u8; //~ ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -8,9 +8,11 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
extern "C" {
|
||||
fn g(_: &u8) -> &u8; // OK
|
||||
fn f() -> &u8; //~ ERROR missing lifetime specifier
|
||||
pub fn g(_: &u8) -> &u8; // OK
|
||||
pub fn f() -> &u8; //~ ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,10 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/foreign-fn-return-lifetime.rs:13:15
|
||||
--> $DIR/foreign-fn-return-lifetime.rs:15:19
|
||||
|
|
||||
LL | fn f() -> &u8; //~ ERROR missing lifetime specifier
|
||||
| ^ expected lifetime parameter
|
||||
LL | pub fn f() -> &u8; //~ ERROR missing lifetime specifier
|
||||
| ^ help: consider giving it a 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-13497.rs:12:5
|
||||
|
|
||||
LL | &str //~ ERROR missing lifetime specifier
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it a 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -10,19 +10,17 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-26638.rs:14:40
|
||||
|
|
||||
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
|
||||
= help: consider giving it an explicit bounded or 'static lifetime
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-26638.rs:17:22
|
||||
|
|
||||
LL | fn parse_type_3() -> &str { unimplemented!() }
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it a 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:12:11
|
||||
|
|
||||
LL | fn f() -> &isize { //~ ERROR missing lifetime specifier
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it a 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:33
|
||||
@ -27,28 +26,25 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:31:20
|
||||
|
|
||||
LL | fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
|
||||
= help: consider giving it an explicit bounded or 'static lifetime
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:44:24
|
||||
|
|
||||
LL | fn j(_x: StaticStr) -> &isize { //~ ERROR missing lifetime specifier
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
|
||||
= help: consider giving it an explicit bounded or 'static lifetime
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:50:49
|
||||
|
|
||||
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
|
||||
= help: consider giving it an explicit bounded or 'static lifetime
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
12
src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
Normal file
12
src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
Normal file
@ -0,0 +1,12 @@
|
||||
trait Future {
|
||||
type Item;
|
||||
type Error;
|
||||
}
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
fn foo() -> impl Future<Item=(), Error=Box<Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,11 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-trait.rs:8:44
|
||||
|
|
||||
LL | fn foo() -> impl Future<Item=(), Error=Box<Error>> {
|
||||
| ^^^^^ help: consider giving it a 'static lifetime: `Error + 'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0106`.
|
@ -56,7 +56,7 @@ fn main() {
|
||||
while true {
|
||||
//~^ WARN denote infinite loops
|
||||
//~| HELP use `loop`
|
||||
let mut a = (1);
|
||||
let mut registry_no = (format!("NX-{}", 74205));
|
||||
//~^ WARN does not need to be mutable
|
||||
//~| HELP remove this `mut`
|
||||
//~| WARN unnecessary parentheses
|
||||
@ -72,6 +72,6 @@ fn main() {
|
||||
//~^ WARN this pattern is redundant
|
||||
//~| HELP remove this
|
||||
}
|
||||
println!("{} {}", a, b);
|
||||
println!("{} {}", registry_no, b);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
warning: unnecessary parentheses around assigned value
|
||||
--> $DIR/suggestions.rs:59:21
|
||||
--> $DIR/suggestions.rs:59:31
|
||||
|
|
||||
LL | let mut a = (1);
|
||||
| ^^^ help: remove these parentheses
|
||||
LL | let mut registry_no = (format!("NX-{}", 74205));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/suggestions.rs:13:21
|
||||
@ -21,8 +21,8 @@ LL | #[no_debug] // should suggest removal of deprecated attribute
|
||||
warning: variable does not need to be mutable
|
||||
--> $DIR/suggestions.rs:59:13
|
||||
|
|
||||
LL | let mut a = (1);
|
||||
| ----^
|
||||
LL | let mut registry_no = (format!("NX-{}", 74205));
|
||||
| ----^^^^^^^^^^^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
|
@ -66,7 +66,7 @@ impl<F> R<F> { fn new(f: F) -> Self { R { w: 0, f } } }
|
||||
// It got pretty monotonous writing the same code over and over, and I
|
||||
// feared I would forget details. So I abstracted some desiderata into
|
||||
// macros. But I left the initialization code inline, because that's
|
||||
// where the errors for #54986 will be emited.
|
||||
// where the errors for #54986 will be emitted.
|
||||
|
||||
macro_rules! use_fully {
|
||||
(struct $s:expr) => { {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// rust-lang/rust#52059: Regardless of whether you are moving out of a
|
||||
// Drop type or just introducing an inadvertant alias via a borrow of
|
||||
// Drop type or just introducing an inadvertent alias via a borrow of
|
||||
// one of its fields, it is useful to be reminded of the significance
|
||||
// of the fact that the type implements Drop.
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we do some basic error correcton in the tokeniser (and don't ICE).
|
||||
// Test that we do some basic error correction in the tokeniser (and don't ICE).
|
||||
|
||||
fn main() {
|
||||
if foo {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// ignore-cloudabi no std::fs support
|
||||
|
||||
// Test that we do some basic error correcton in the tokeniser (and don't spew
|
||||
// Test that we do some basic error correction in the tokeniser (and don't spew
|
||||
// too many bogus errors).
|
||||
|
||||
pub mod raw {
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we do some basic error correcton in the tokeniser.
|
||||
// Test that we do some basic error correction in the tokeniser.
|
||||
|
||||
fn main() {
|
||||
foo(bar(;
|
||||
|
@ -19,22 +19,22 @@ fn main() {
|
||||
use std::ops::Range;
|
||||
|
||||
if let Range { start: _, end: _ } = true..true && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
if let Range { start: _, end: _ } = true..true || false { }
|
||||
//~^ ERROR ambigious use of `||`
|
||||
//~^ ERROR ambiguous use of `||`
|
||||
|
||||
while let Range { start: _, end: _ } = true..true && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
while let Range { start: _, end: _ } = true..true || false { }
|
||||
//~^ ERROR ambigious use of `||`
|
||||
//~^ ERROR ambiguous use of `||`
|
||||
|
||||
if let true = false && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
while let true = (1 == 2) && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
// The following cases are not an error as parenthesis are used to
|
||||
// clarify intent:
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2015.rs:21:47
|
||||
|
|
||||
LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||
@ -7,7 +7,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `||`
|
||||
error: ambiguous use of `||`
|
||||
--> $DIR/syntax-ambiguity-2015.rs:24:47
|
||||
|
|
||||
LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||
@ -16,7 +16,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2015.rs:27:50
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||
@ -25,7 +25,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `||`
|
||||
error: ambiguous use of `||`
|
||||
--> $DIR/syntax-ambiguity-2015.rs:30:50
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||
@ -34,7 +34,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2015.rs:33:19
|
||||
|
|
||||
LL | if let true = false && false { }
|
||||
@ -43,7 +43,7 @@ LL | if let true = false && false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2015.rs:36:22
|
||||
|
|
||||
LL | while let true = (1 == 2) && false { }
|
||||
|
@ -19,22 +19,22 @@ fn main() {
|
||||
use std::ops::Range;
|
||||
|
||||
if let Range { start: _, end: _ } = true..true && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
if let Range { start: _, end: _ } = true..true || false { }
|
||||
//~^ ERROR ambigious use of `||`
|
||||
//~^ ERROR ambiguous use of `||`
|
||||
|
||||
while let Range { start: _, end: _ } = true..true && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
while let Range { start: _, end: _ } = true..true || false { }
|
||||
//~^ ERROR ambigious use of `||`
|
||||
//~^ ERROR ambiguous use of `||`
|
||||
|
||||
if let true = false && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
while let true = (1 == 2) && false { }
|
||||
//~^ ERROR ambigious use of `&&`
|
||||
//~^ ERROR ambiguous use of `&&`
|
||||
|
||||
// The following cases are not an error as parenthesis are used to
|
||||
// clarify intent:
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2018.rs:21:47
|
||||
|
|
||||
LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||
@ -7,7 +7,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `||`
|
||||
error: ambiguous use of `||`
|
||||
--> $DIR/syntax-ambiguity-2018.rs:24:47
|
||||
|
|
||||
LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||
@ -16,7 +16,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2018.rs:27:50
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||
@ -25,7 +25,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `||`
|
||||
error: ambiguous use of `||`
|
||||
--> $DIR/syntax-ambiguity-2018.rs:30:50
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||
@ -34,7 +34,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2018.rs:33:19
|
||||
|
|
||||
LL | if let true = false && false { }
|
||||
@ -43,7 +43,7 @@ LL | if let true = false && false { }
|
||||
= note: this will be a error until the `let_chains` feature is stabilized
|
||||
= note: see rust-lang/rust#53668 for more information
|
||||
|
||||
error: ambigious use of `&&`
|
||||
error: ambiguous use of `&&`
|
||||
--> $DIR/syntax-ambiguity-2018.rs:36:22
|
||||
|
|
||||
LL | while let true = (1 == 2) && false { }
|
||||
|
@ -24,7 +24,7 @@ use std::fmt::{Debug, Display};
|
||||
// • one generic parameter (T) bound inline
|
||||
// • one parameter (T) with a where clause
|
||||
// • two parameters (T and U), both bound inline
|
||||
// • two paramters (T and U), one bound inline, one with a where clause
|
||||
// • two parameters (T and U), one bound inline, one with a where clause
|
||||
// • two parameters (T and U), both with where clauses
|
||||
//
|
||||
// —and for every permutation of 0, 1, or 2 lifetimes to outlive and 0 or 1
|
||||
|
@ -24,7 +24,7 @@ use std::fmt::{Debug, Display};
|
||||
// • one generic parameter (T) bound inline
|
||||
// • one parameter (T) with a where clause
|
||||
// • two parameters (T and U), both bound inline
|
||||
// • two paramters (T and U), one bound inline, one with a where clause
|
||||
// • two parameters (T and U), one bound inline, one with a where clause
|
||||
// • two parameters (T and U), both with where clauses
|
||||
//
|
||||
// —and for every permutation of 0, 1, or 2 lifetimes to outlive and 0 or 1
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
// Regression test for #52050: when inserting the blanket impl `I`
|
||||
// into the tree, we had to replace the child node for `Foo`, which
|
||||
// led to the struture of the tree being messed up.
|
||||
// led to the structure of the tree being messed up.
|
||||
|
||||
use std::iter::Iterator;
|
||||
|
||||
|
@ -20,10 +20,9 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/underscore-lifetime-binders.rs:20:29
|
||||
|
|
||||
LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ help: consider giving it a 'static lifetime: `'static`
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
= help: consider giving it a 'static lifetime
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/underscore-lifetime-binders.rs:26:35
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5afdf8b78507ddf015d192858aef56e72c17de16
|
||||
Subproject commit b1d0343749bdc87e5cbbe7f1aeaa9d2a2c9dbc5b
|
@ -163,7 +163,7 @@ fn check_cfgs(contents: &mut String, file: &Path,
|
||||
|
||||
fn find_test_mod(contents: &str) -> usize {
|
||||
if let Some(mod_tests_idx) = contents.find("mod tests") {
|
||||
// Also capture a previos line indicating "mod tests" in cfg-ed out
|
||||
// Also capture a previous line indicating "mod tests" in cfg-ed out
|
||||
let prev_newline_idx = contents[..mod_tests_idx].rfind('\n').unwrap_or(mod_tests_idx);
|
||||
let prev_newline_idx = contents[..prev_newline_idx].rfind('\n');
|
||||
if let Some(nl) = prev_newline_idx {
|
||||
|
Loading…
Reference in New Issue
Block a user