提交 207d9558 编写于 作者: B bors

Auto merge of #89047 - GuillaumeGomez:rollup-29gmr02, r=GuillaumeGomez

Rollup of 10 pull requests

Successful merges:

 - #86422 (Emit clearer diagnostics for parens around `for` loop heads)
 - #87460 (Point to closure when emitting 'cannot move out' for captured variable)
 - #87566 (Recover invalid assoc type bounds using `==`)
 - #88666 (Improve build command for compiler docs)
 - #88899 (Do not issue E0071 if a type error has already been reported)
 - #88949 (Fix handling of `hir::GenericArg::Infer` in `wrong_number_of_generic_args.rs`)
 - #88953 (Add chown functions to std::os::unix::fs to change the owner and group of files)
 - #88954 (Allow `panic!("{}", computed_str)` in const fn.)
 - #88964 (Add rustdoc version into the help popup)
 - #89012 (Suggest removing `#![feature]` for library features that have been stabilized)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
......@@ -702,10 +702,16 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
}
fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
// checks if `#![feature]` has been used to enable any lang feature
// does not check the same for lib features unless there's at least one
// declared lang feature
use rustc_errors::Applicability;
if !sess.opts.unstable_features.is_nightly_build() {
let lang_features = &sess.features_untracked().declared_lang_features;
if lang_features.len() == 0 {
return;
}
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
let mut err = struct_span_err!(
sess.parse_sess.span_diagnostic,
......
......@@ -336,15 +336,15 @@ fn report_cannot_move_from_borrowed_content(
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
{
let closure_kind_ty = closure_substs.as_closure().kind_ty();
let closure_kind = closure_kind_ty.to_opt_closure_kind();
let capture_description = match closure_kind {
Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure",
Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure",
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
Some(ty::ClosureKind::FnOnce) => {
bug!("closure kind does not match first argument type")
}
None => bug!("closure kind not inferred by borrowck"),
};
let capture_description =
format!("captured variable in an `{}` closure", closure_kind);
let upvar = &self.upvars[upvar_field.unwrap().index()];
let upvar_hir_id = upvar.place.get_root_variable();
......@@ -368,6 +368,10 @@ fn report_cannot_move_from_borrowed_content(
let mut diag = self.cannot_move_out_of(span, &place_description);
diag.span_label(upvar_span, "captured outer variable");
diag.span_label(
self.body.span,
format!("captured by this `{}` closure", closure_kind),
);
diag
}
......
......@@ -36,12 +36,17 @@ fn hook_panic_fn(
let def_id = instance.def_id();
if Some(def_id) == self.tcx.lang_items().panic_fn()
|| Some(def_id) == self.tcx.lang_items().panic_str()
|| Some(def_id) == self.tcx.lang_items().panic_display()
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
{
// &str
// &str or &&str
assert!(args.len() == 1);
let msg_place = self.deref_operand(&args[0])?;
let mut msg_place = self.deref_operand(&args[0])?;
while msg_place.layout.ty.is_ref() {
msg_place = self.deref_operand(&msg_place.into())?;
}
let msg = Symbol::intern(self.read_str(&msg_place)?);
let span = self.find_closest_untracked_caller_location();
let (file, line, col) = self.location_triple_for_span(span);
......
......@@ -888,6 +888,10 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
if is_lang_panic_fn(tcx, callee) {
self.check_op(ops::Panic);
// `begin_panic` and `panic_display` are generic functions that accept
// types other than str. Check to enforce that only str can be used in
// const-eval.
// const-eval of the `begin_panic` fn assumes the argument is `&str`
if Some(callee) == tcx.lang_items().begin_panic_fn() {
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
......@@ -896,6 +900,15 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
}
}
// const-eval of the `panic_display` fn assumes the argument is `&&str`
if Some(callee) == tcx.lang_items().panic_display() {
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
{}
_ => self.check_op(ops::PanicNonStr),
}
}
return;
}
......
......@@ -79,6 +79,7 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
// Keep in sync with what that function handles!
Some(def_id) == tcx.lang_items().panic_fn()
|| Some(def_id) == tcx.lang_items().panic_str()
|| Some(def_id) == tcx.lang_items().panic_display()
|| Some(def_id) == tcx.lang_items().begin_panic_fn()
|| Some(def_id) == tcx.lang_items().panic_fmt()
|| Some(def_id) == tcx.lang_items().begin_panic_fmt()
......
......@@ -15,13 +15,13 @@ form of initializer was used.
For example, the code above can be fixed to:
```
enum Foo {
FirstValue(i32)
}
type U32 = u32;
let t: U32 = 4;
```
fn main() {
let u = Foo::FirstValue(0i32);
or:
let t = 4;
}
```
struct U32 { value: u32 }
let t = U32 { value: 4 };
```
......@@ -283,6 +283,7 @@ pub fn extract<'a, F>(check_name: F, attrs: &'a [ast::Attribute]) -> Option<(Sym
// a weak lang item, but do not have it defined.
Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::None;
PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None;
PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None;
PanicStr, sym::panic_str, panic_str, Target::Fn, GenericRequirement::None;
ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None;
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::None;
......
......@@ -1334,30 +1334,25 @@ pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
pub(super) fn recover_parens_around_for_head(
&mut self,
pat: P<Pat>,
expr: &Expr,
begin_paren: Option<Span>,
) -> P<Pat> {
match (&self.token.kind, begin_paren) {
(token::CloseDelim(token::Paren), Some(begin_par_sp)) => {
self.bump();
let pat_str = self
// Remove the `(` from the span of the pattern:
.span_to_snippet(pat.span.trim_start(begin_par_sp).unwrap())
.unwrap_or_else(|_| pprust::pat_to_string(&pat));
self.struct_span_err(self.prev_token.span, "unexpected closing `)`")
.span_label(begin_par_sp, "opening `(`")
.span_suggestion(
begin_par_sp.to(self.prev_token.span),
"remove parenthesis in `for` loop",
format!("{} in {}", pat_str, pprust::expr_to_string(&expr)),
// With e.g. `for (x) in y)` this would replace `(x) in y)`
// with `x) in y)` which is syntactically invalid.
// However, this is prevented before we get here.
Applicability::MachineApplicable,
)
.emit();
self.struct_span_err(
MultiSpan::from_spans(vec![begin_par_sp, self.prev_token.span]),
"unexpected parenthesis surrounding `for` loop head",
)
.multipart_suggestion(
"remove parenthesis in `for` loop",
vec![(begin_par_sp, String::new()), (self.prev_token.span, String::new())],
// With e.g. `for (x) in y)` this would replace `(x) in y)`
// with `x) in y)` which is syntactically invalid.
// However, this is prevented before we get here.
Applicability::MachineApplicable,
)
.emit();
// Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint.
pat.and_then(|pat| match pat.kind {
......@@ -1955,7 +1950,19 @@ pub fn recover_const_arg(
}
match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
Ok(expr) => {
if token::Comma == self.token.kind || self.token.kind.should_end_const_arg() {
// Find a mistake like `MyTrait<Assoc == S::Assoc>`.
if token::EqEq == snapshot.token.kind {
err.span_suggestion(
snapshot.token.span,
"if you meant to use an associated type binding, replace `==` with `=`",
"=".to_string(),
Applicability::MaybeIncorrect,
);
let value = self.mk_expr_err(start.to(expr.span));
err.emit();
return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
} else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
{
// Avoid the following output by checking that we consumed a full const arg:
// help: expressions must be enclosed in braces to be used as const generic
// arguments
......
......@@ -2042,7 +2042,7 @@ fn parse_for_expr(
self.check_for_for_in_in_typo(self.prev_token.span);
let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
let pat = self.recover_parens_around_for_head(pat, &expr, begin_paren);
let pat = self.recover_parens_around_for_head(pat, begin_paren);
let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
attrs.extend(iattrs);
......
......@@ -929,6 +929,16 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
let declared_lib_features = &tcx.features().declared_lib_features;
let mut remaining_lib_features = FxHashMap::default();
for (feature, span) in declared_lib_features {
if !tcx.sess.opts.unstable_features.is_nightly_build() {
struct_span_err!(
tcx.sess,
*span,
E0554,
"`#![feature]` may not be used on the {} release channel",
env!("CFG_RELEASE_CHANNEL")
)
.emit();
}
if remaining_lib_features.contains_key(&feature) {
// Warn if the user enables a lib feature multiple times.
duplicate_feature_err(tcx.sess, *span, *feature);
......
......@@ -923,6 +923,7 @@
panic_2021,
panic_abort,
panic_bounds_check,
panic_display,
panic_fmt,
panic_handler,
panic_impl,
......
......@@ -532,15 +532,25 @@ pub fn check_struct_path(
Some((variant, ty))
} else {
struct_span_err!(
self.tcx.sess,
path_span,
E0071,
"expected struct, variant or union type, found {}",
ty.sort_string(self.tcx)
)
.span_label(path_span, "not a struct")
.emit();
match ty.kind() {
ty::Error(_) => {
// E0071 might be caused by a spelling error, which will have
// already caused an error message and probably a suggestion
// elsewhere. Refrain from emitting more unhelpful errors here
// (issue #88844).
}
_ => {
struct_span_err!(
self.tcx.sess,
path_span,
E0071,
"expected struct, variant or union type, found {}",
ty.sort_string(self.tcx)
)
.span_label(path_span, "not a struct")
.emit();
}
}
None
}
}
......
......@@ -136,10 +136,7 @@ fn num_provided_lifetime_args(&self) -> usize {
AngleBrackets::Missing => 0,
// Only lifetime arguments can be implied
AngleBrackets::Implied => self.gen_args.args.len(),
AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
hir::GenericArg::Lifetime(_) => acc + 1,
_ => acc,
}),
AngleBrackets::Available => self.gen_args.num_lifetime_params(),
}
}
......@@ -148,10 +145,7 @@ fn num_provided_type_or_const_args(&self) -> usize {
AngleBrackets::Missing => 0,
// Only lifetime arguments can be implied
AngleBrackets::Implied => 0,
AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => acc + 1,
_ => acc,
}),
AngleBrackets::Available => self.gen_args.num_generic_params(),
}
}
......@@ -651,7 +645,9 @@ fn suggest_removing_args_or_generics(&self, err: &mut DiagnosticBuilder<'_>) {
let mut found_redundant = false;
for arg in self.gen_args.args {
match arg {
hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => {
hir::GenericArg::Type(_)
| hir::GenericArg::Const(_)
| hir::GenericArg::Infer(_) => {
gen_arg_spans.push(arg.span());
if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
found_redundant = true;
......
......@@ -27,9 +27,14 @@
($msg:literal $(,)?) => (
$crate::panicking::panic($msg)
),
// Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
($msg:expr $(,)?) => (
$crate::panicking::panic_str($msg)
),
// Special-case the single-argument case for const_panic.
("{}", $arg:expr $(,)?) => (
$crate::panicking::panic_display(&$arg)
),
($fmt:expr, $($arg:tt)+) => (
$crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
),
......@@ -44,6 +49,10 @@
() => (
$crate::panicking::panic("explicit panic")
),
// Special-case the single-argument case for const_panic.
("{}", $arg:expr $(,)?) => (
$crate::panicking::panic_display(&$arg)
),
($($t:tt)+) => (
$crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
),
......
......@@ -60,6 +60,13 @@ pub fn panic_str(expr: &str) -> ! {
panic_fmt(format_args!("{}", expr));
}
#[inline]
#[track_caller]
#[cfg_attr(not(bootstrap), lang = "panic_display")] // needed for const-evaluated panics
pub fn panic_display<T: fmt::Display>(x: &T) -> ! {
panic_fmt(format_args!("{}", *x));
}
#[cold]
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[track_caller]
......
......@@ -258,6 +258,7 @@
#![feature(const_trait_impl)]
#![feature(container_error_extra)]
#![feature(core_intrinsics)]
#![feature(core_panic)]
#![feature(custom_test_frameworks)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
......
......@@ -5,6 +5,7 @@
use super::platform::fs::MetadataExt as _;
use crate::fs::{self, OpenOptions, Permissions};
use crate::io;
use crate::os::unix::io::{AsFd, AsRawFd};
use crate::path::Path;
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
......@@ -924,6 +925,75 @@ fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
}
}
/// Change the owner and group of the specified path.
///
/// Specifying either the uid or gid as `None` will leave it unchanged.
///
/// Changing the owner typically requires privileges, such as root or a specific capability.
/// Changing the group typically requires either being the owner and a member of the group, or
/// having privileges.
///
/// If called on a symbolic link, this will change the owner and group of the link target. To
/// change the owner and group of the link itself, see [`lchown`].
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_chown)]
/// use std::os::unix::fs;
///
/// fn main() -> std::io::Result<()> {
/// fs::chown("/sandbox", Some(0), Some(0))?;
/// Ok(())
/// }
/// ```
#[unstable(feature = "unix_chown", issue = "88989")]
pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
}
/// Change the owner and group of the file referenced by the specified open file descriptor.
///
/// For semantics and required privileges, see [`chown`].
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_chown)]
/// use std::os::unix::fs;
///
/// fn main() -> std::io::Result<()> {
/// let f = std::fs::File::open("/file")?;
/// fs::fchown(f, Some(0), Some(0))?;
/// Ok(())
/// }
/// ```
#[unstable(feature = "unix_chown", issue = "88989")]
pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
}
/// Change the owner and group of the specified path, without dereferencing symbolic links.
///
/// Identical to [`chown`], except that if called on a symbolic link, this will change the owner
/// and group of the link itself rather than the owner and group of the link target.
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_chown)]
/// use std::os::unix::fs;
///
/// fn main() -> std::io::Result<()> {
/// fs::lchown("/symlink", Some(0), Some(0))?;
/// Ok(())
/// }
/// ```
#[unstable(feature = "unix_chown", issue = "88989")]
pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
}
/// Change the root directory of the current process to the specified path.
///
/// This typically requires privileges, such as root or a specific capability.
......
......@@ -10,7 +10,7 @@
#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
#[allow_internal_unstable(libstd_sys_internals, const_format_args)]
#[allow_internal_unstable(libstd_sys_internals, const_format_args, core_panic)]
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2015 {
......@@ -20,6 +20,10 @@
($msg:expr $(,)?) => ({
$crate::rt::begin_panic($msg)
}),
// Special-case the single-argument case for const_panic.
("{}", $arg:expr $(,)?) => ({
$crate::rt::panic_display(&$arg)
}),
($fmt:expr, $($arg:tt)+) => ({
$crate::rt::begin_panic_fmt(&$crate::const_format_args!($fmt, $($arg)+))
}),
......
......@@ -16,6 +16,7 @@
// Re-export some of our utilities which are expected by other crates.
pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count};
pub use core::panicking::panic_display;
// To reduce the generated code of the new `lang_start`, this function is doing
// the real work.
......
......@@ -1416,6 +1416,23 @@ fn fclonefileat(
Ok(bytes_copied as u64)
}
pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
let path = cstr(path)?;
cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?;
Ok(())
}
pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> {
cvt(unsafe { libc::fchown(fd, uid as libc::uid_t, gid as libc::gid_t) })?;
Ok(())
}
pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
let path = cstr(path)?;
cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?;
Ok(())
}
#[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
pub fn chroot(dir: &Path) -> io::Result<()> {
let dir = cstr(dir)?;
......
......@@ -537,7 +537,7 @@ impl Step for Rustc {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
run.krate("rustc-main").default_condition(builder.config.docs)
run.krate("rustc-main").path("compiler").default_condition(builder.config.docs)
}
fn make_run(run: RunConfig<'_>) {
......@@ -553,9 +553,24 @@ fn make_run(run: RunConfig<'_>) {
fn run(self, builder: &Builder<'_>) {
let stage = self.stage;
let target = self.target;
let mut is_explicit_request = false;
builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
if !builder.config.compiler_docs {
let paths = builder
.paths
.iter()
.map(components_simplified)
.filter_map(|path| {
if path.get(0) == Some(&"compiler") {
is_explicit_request = true;
path.get(1).map(|p| p.to_owned())
} else {
None
}
})
.collect::<Vec<_>>();
if !builder.config.compiler_docs && !is_explicit_request {
builder.info("\tskipping - compiler/librustdoc docs disabled");
return;
}
......@@ -604,26 +619,54 @@ fn run(self, builder: &Builder<'_>) {
cargo.rustdocflag("--extern-html-root-url");
cargo.rustdocflag("ena=https://docs.rs/ena/latest/");
// Find dependencies for top level crates.
let mut compiler_crates = HashSet::new();
for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
compiler_crates.extend(
builder
.in_tree_crates(root_crate, Some(target))
.into_iter()
.map(|krate| krate.name),
);
if paths.is_empty() {
// Find dependencies for top level crates.
for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
compiler_crates.extend(
builder
.in_tree_crates(root_crate, Some(target))
.into_iter()
.map(|krate| krate.name),
);
}
} else {
for root_crate in paths {
if !builder.src.join("compiler").join(&root_crate).exists() {
builder.info(&format!(
"\tskipping - compiler/{} (unknown compiler crate)",
root_crate
));
} else {
compiler_crates.extend(
builder
.in_tree_crates(root_crate, Some(target))
.into_iter()
.map(|krate| krate.name),
);
}
}
}
let mut to_open = None;
for krate in &compiler_crates {
// Create all crate output directories first to make sure rustdoc uses
// relative links.
// FIXME: Cargo should probably do this itself.
t!(fs::create_dir_all(out_dir.join(krate)));
cargo.arg("-p").arg(krate);
if to_open.is_none() {
to_open = Some(krate);
}
}
builder.run(&mut cargo.into());
// Let's open the first crate documentation page:
if let Some(krate) = to_open {
let index = out.join(krate).join("index.html");
open(builder, &index);
}
}
}
......
......@@ -268,10 +268,18 @@ fn add_background_image_to_css(
// Maybe we can change the representation to move this out of main.js?
write_minify(
"main.js",
static_files::MAIN_JS.replace(
"/* INSERT THEMES HERE */",
&format!(" = {}", serde_json::to_string(&themes).unwrap()),
),
static_files::MAIN_JS
.replace(
"/* INSERT THEMES HERE */",
&format!(" = {}", serde_json::to_string(&themes).unwrap()),
)
.replace(
"/* INSERT RUSTDOC_VERSION HERE */",
&format!(
"rustdoc {}",
rustc_interface::util::version_str().unwrap_or("unknown version")
),
),
cx,
options,
)?;
......
......@@ -928,15 +928,24 @@ body.blur > :not(#help) {
display: block;
margin-right: 0.5rem;
}
#help > div > span {
#help span.top, #help span.bottom {
text-align: center;
display: block;
margin: 10px 0;
font-size: 18px;
border-bottom: 1px solid #ccc;
}
#help span.top {
text-align: center;
display: block;
margin: 10px 0;
border-bottom: 1px solid;
padding-bottom: 4px;
margin-bottom: 6px;
}
#help span.bottom {
clear: both;
border-top: 1px solid;
}
#help dd { margin: 5px 35px; }
#help .infos { padding-left: 0; }
#help h1, #help h2 { margin-top: 0; }
......
......@@ -286,8 +286,8 @@ details.undocumented > summary::before {
border-radius: 4px;
}
#help > div > span {
border-bottom-color: #5c6773;
#help span.bottom, #help span.top {
border-color: #5c6773;
}
.since {
......
......@@ -242,8 +242,8 @@ details.undocumented > summary::before {
border-color: #bfbfbf;
}
#help > div > span {
border-bottom-color: #bfbfbf;
#help span.bottom, #help span.top {
border-color: #bfbfbf;
}
#help dt {
......
......@@ -232,8 +232,8 @@ details.undocumented > summary::before {
border-color: #bfbfbf;
}
#help > div > span {
border-bottom-color: #bfbfbf;
#help span.bottom, #help span.top {
border-color: #bfbfbf;
}
.since {
......
......@@ -911,6 +911,7 @@ function hideThemeButtonState() {
});
var book_info = document.createElement("span");
book_info.className = "top";
book_info.innerHTML = "You can find more information in \
<a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
......@@ -961,6 +962,14 @@ function hideThemeButtonState() {
container.appendChild(div_shortcuts);
container.appendChild(div_infos);
var rustdoc_version = document.createElement("span");
rustdoc_version.className = "bottom";
var rustdoc_version_code = document.createElement("code");
rustdoc_version_code.innerText = "/* INSERT RUSTDOC_VERSION HERE */";
rustdoc_version.appendChild(rustdoc_version_code);
container.appendChild(rustdoc_version);
popup.appendChild(container);
insertAfter(popup, searchState.outputElement());
// So that it's only built once and then it'll do nothing when called!
......
......@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0);
| - captured outer variable
LL | Box::new(|| x)
| ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| ---^
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error: aborting due to previous error
......
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-move-by-capture.rs:9:29
|
LL | let bar: Box<_> = box 3;
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
LL | let _h = to_fn_once(move || -> isize { *bar });
| ^^^^^^^^^^^^^^^^ ----
| | |
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| | move occurs due to use in closure
| move out of `bar` occurs here
LL | let bar: Box<_> = box 3;
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
| ________________________-
LL | | let _h = to_fn_once(move || -> isize { *bar });
| | ^^^^^^^^^^^^^^^^ ----
| | | |
| | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| | | move occurs due to use in closure
| | move out of `bar` occurs here
LL | | });
| |_____- captured by this `FnMut` closure
error: aborting due to previous error
......
// Regression test for #87456.
fn take_mut(_val: impl FnMut()) {}
fn main() {
let val = String::new();
//~^ NOTE: captured outer variable
take_mut(|| {
//~^ NOTE: captured by this `FnMut` closure
let _foo: String = val;
//~^ ERROR: cannot move out of `val`, a captured variable in an `FnMut` closure [E0507]
//~| NOTE: move occurs because
})
}
error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure
--> $DIR/issue-87456-point-to-closure.rs:10:28
|
LL | let val = String::new();
| --- captured outer variable
LL |
LL | take_mut(|| {
| ______________-
LL | |
LL | | let _foo: String = val;
| | ^^^
| | |
| | move occurs because `val` has type `String`, which does not implement the `Copy` trait
| | help: consider borrowing here: `&val`
LL | |
LL | |
LL | | })
| |_____- captured by this `FnMut` closure
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.
error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
--> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:11:9
|
LL | let y = vec![format!("World")];
| - captured outer variable
LL | call(|| {
LL | y.into_iter();
| ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
LL | let y = vec![format!("World")];
| - captured outer variable
LL | call(|| {
| __________-
LL | | y.into_iter();
| | ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
LL | |
LL | | });
| |_____- captured by this `Fn` closure
error: aborting due to previous error
......
pub trait MyTrait {
type Assoc;
}
pub fn foo<S, T>(_s: S, _t: T)
where
S: MyTrait,
T: MyTrait<Assoc == S::Assoc>,
//~^ ERROR: expected one of `,` or `>`, found `==`
//~| ERROR: this trait takes 0 generic arguments but 1 generic argument was supplied
{
}
fn main() {}
error: expected one of `,` or `>`, found `==`
--> $DIR/issue-87493.rs:8:22
|
LL | T: MyTrait<Assoc == S::Assoc>,
| ^^ expected one of `,` or `>`
|
help: if you meant to use an associated type binding, replace `==` with `=`
|
LL | T: MyTrait<Assoc = S::Assoc>,
| ~
error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-87493.rs:8:8
|
LL | T: MyTrait<Assoc == S::Assoc>,
| ^^^^^^^------------------- help: remove these generics
| |
| expected 0 generic arguments
|
note: trait defined here, with 0 generic parameters
--> $DIR/issue-87493.rs:1:11
|
LL | pub trait MyTrait {
| ^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0107`.
......@@ -15,10 +15,13 @@
const X: () = std::unimplemented!();
//~^ ERROR evaluation of constant value failed
//
const W: () = std::panic!(MSG);
//~^ ERROR evaluation of constant value failed
const W2: () = std::panic!("{}", MSG);
//~^ ERROR evaluation of constant value failed
const Z_CORE: () = core::panic!("cheese");
//~^ ERROR evaluation of constant value failed
......@@ -33,3 +36,6 @@
const W_CORE: () = core::panic!(MSG);
//~^ ERROR evaluation of constant value failed
const W2_CORE: () = core::panic!("{}", MSG);
//~^ ERROR evaluation of constant value failed
......@@ -39,45 +39,61 @@ LL | const W: () = std::panic!(MSG);
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:22:20
--> $DIR/const_panic.rs:22:16
|
LL | const W2: () = std::panic!("{}", MSG);
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:22:16
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:25:20
|
LL | const Z_CORE: () = core::panic!("cheese");
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:22:20
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:25:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:25:21
--> $DIR/const_panic.rs:28:21
|
LL | const Z2_CORE: () = core::panic!();
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:25:21
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:28:21
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:28:20
--> $DIR/const_panic.rs:31:20
|
LL | const Y_CORE: () = core::unreachable!();
| ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:28:20
| ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:31:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:31:20
--> $DIR/const_panic.rs:34:20
|
LL | const X_CORE: () = core::unimplemented!();
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:31:20
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:34:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:34:20
--> $DIR/const_panic.rs:37:20
|
LL | const W_CORE: () = core::panic!(MSG);
| ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:34:20
| ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:37:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic.rs:40:21
|
LL | const W2_CORE: () = core::panic!("{}", MSG);
| ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:40:21
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors
error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0080`.
......@@ -2,6 +2,8 @@
#![feature(const_panic)]
#![crate_type = "lib"]
const MSG: &str = "hello";
const A: () = std::panic!("blåhaj");
//~^ ERROR evaluation of constant value failed
......@@ -14,14 +16,20 @@
const D: () = std::unimplemented!();
//~^ ERROR evaluation of constant value failed
const E: () = core::panic!("shark");
const E: () = std::panic!("{}", MSG);
//~^ ERROR evaluation of constant value failed
const A_CORE: () = core::panic!("shark");
//~^ ERROR evaluation of constant value failed
const B_CORE: () = core::panic!();
//~^ ERROR evaluation of constant value failed
const F: () = core::panic!();
const C_CORE: () = core::unreachable!();
//~^ ERROR evaluation of constant value failed
const G: () = core::unreachable!();
const D_CORE: () = core::unimplemented!();
//~^ ERROR evaluation of constant value failed
const H: () = core::unimplemented!();
const E_CORE: () = core::panic!("{}", MSG);
//~^ ERROR evaluation of constant value failed
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:5:15
--> $DIR/const_panic_2021.rs:7:15
|
LL | const A: () = std::panic!("blåhaj");
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blåhaj', $DIR/const_panic_2021.rs:5:15
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blåhaj', $DIR/const_panic_2021.rs:7:15
|
= note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:8:15
--> $DIR/const_panic_2021.rs:10:15
|
LL | const B: () = std::panic!();
| ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:8:15
| ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:10:15
|
= note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:11:15
--> $DIR/const_panic_2021.rs:13:15
|
LL | const C: () = std::unreachable!();
| ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:11:15
| ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:13:15
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:14:15
--> $DIR/const_panic_2021.rs:16:15
|
LL | const D: () = std::unimplemented!();
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:14:15
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:16:15
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:17:15
--> $DIR/const_panic_2021.rs:19:15
|
LL | const E: () = core::panic!("shark");
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:17:15
LL | const E: () = std::panic!("{}", MSG);
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:19:15
|
= note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:20:15
--> $DIR/const_panic_2021.rs:22:20
|
LL | const F: () = core::panic!();
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:20:15
LL | const A_CORE: () = core::panic!("shark");
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:22:20
|
= note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:23:15
--> $DIR/const_panic_2021.rs:25:20
|
LL | const G: () = core::unreachable!();
| ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:23:15
LL | const B_CORE: () = core::panic!();
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:25:20
|
= note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:28:20
|
LL | const C_CORE: () = core::unreachable!();
| ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:28:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:26:15
--> $DIR/const_panic_2021.rs:31:20
|
LL | const H: () = core::unimplemented!();
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:26:15
LL | const D_CORE: () = core::unimplemented!();
| ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:31:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 8 previous errors
error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_2021.rs:34:20
|
LL | const E_CORE: () = core::panic!("{}", MSG);
| ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:34:20
|
= note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0080`.
......@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMu
LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
| - captured outer variable
LL | id(Box::new(|| *v))
| ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
| ---^^
| | |
| | move occurs because `*v` has type `T`, which does not implement the `Copy` trait
| captured by this `FnMut` closure
error: aborting due to previous error
......
......@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
LL | let i = box 3;
| - captured outer variable
LL | let _f = to_fn(|| test(i));
| ^ move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
| --------^-
| | |
| | move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error: aborting due to previous error
......
......@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn`
LL | let x = (vec![22], vec![44]);
| - captured outer variable
LL | expect_fn(|| drop(x.0));
| ^^^ move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
| --------^^^-
| | |
| | move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error: aborting due to previous error
......
......@@ -9,7 +9,7 @@ fn main() {
for ( elem in vec ) {
//~^ ERROR expected one of `)`, `,`, `@`, or `|`, found keyword `in`
//~| ERROR unexpected closing `)`
//~| ERROR unexpected parenthesis surrounding `for` loop head
const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
}
}
......@@ -4,14 +4,17 @@ error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
LL | for ( elem in vec ) {
| ^^ expected one of `)`, `,`, `@`, or `|`
error: unexpected closing `)`
--> $DIR/recover-for-loop-parens-around-head.rs:10:23
error: unexpected parenthesis surrounding `for` loop head
--> $DIR/recover-for-loop-parens-around-head.rs:10:9
|
LL | for ( elem in vec ) {
| --------------^
| |
| opening `(`
| help: remove parenthesis in `for` loop: `elem in vec`
| ^ ^
|
help: remove parenthesis in `for` loop
|
LL - for ( elem in vec ) {
LL + for elem in vec {
|
error[E0308]: mismatched types
--> $DIR/recover-for-loop-parens-around-head.rs:13:38
......
......@@ -29,11 +29,17 @@ LL | f.f.call_mut(())
error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
|
LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
| ----- captured outer variable
LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
| ----- captured outer variable
...
LL | foo(f);
| ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
LL | f(Box::new(|a| {
| ________________-
LL | |
LL | | foo(f);
| | ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
LL | |
LL | | }), 3);
| |_____- captured by this `FnMut` closure
error[E0505]: cannot move out of `f` because it is borrowed
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
......
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move2.rs:9:9
|
LL | let mut var = None;
| ------- captured outer variable
...
LL | move || {
| ^^^^^^^ move out of `var` occurs here
LL |
LL | var = Some(NotCopyable);
| ---
| |
| move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
| move occurs due to use in closure
LL | let mut var = None;
| ------- captured outer variable
LL | func(|| {
| __________-
LL | | // Shouldn't suggest `move ||.as_ref()` here
LL | | move || {
| | ^^^^^^^ move out of `var` occurs here
LL | |
LL | | var = Some(NotCopyable);
| | ---
| | |
| | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
| | move occurs due to use in closure
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error: aborting due to previous error
......
// Regression test for #88844.
struct Struct { value: i32 }
//~^ NOTE: similarly named struct `Struct` defined here
impl Stuct {
//~^ ERROR: cannot find type `Stuct` in this scope [E0412]
//~| HELP: a struct with a similar name exists
fn new() -> Self {
Self { value: 42 }
}
}
fn main() {}
error[E0412]: cannot find type `Stuct` in this scope
--> $DIR/issue-88844.rs:6:6
|
LL | struct Struct { value: i32 }
| ------------- similarly named struct `Struct` defined here
...
LL | impl Stuct {
| ^^^^^ help: a struct with a similar name exists: `Struct`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0412`.
......@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0);
| - captured outer variable
LL | let f = to_fn(|| drop(x));
| ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| --------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
--> $DIR/unboxed-closure-illegal-move.rs:19:35
......@@ -12,7 +15,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
LL | let x = Box::new(0);
| - captured outer variable
LL | let f = to_fn_mut(|| drop(x));
| ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| --------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `FnMut` closure
error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
--> $DIR/unboxed-closure-illegal-move.rs:28:36
......@@ -20,7 +26,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0);
| - captured outer variable
LL | let f = to_fn(move || drop(x));
| ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| -------------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
--> $DIR/unboxed-closure-illegal-move.rs:32:40
......@@ -28,7 +37,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
LL | let x = Box::new(0);
| - captured outer variable
LL | let f = to_fn_mut(move || drop(x));
| ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| -------------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `FnMut` closure
error: aborting due to 4 previous errors
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册