Auto merge of #107328 - matthiaskrgr:rollup-lfqwo0o, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #106904 (Preserve split DWARF files when building archives.) - #106971 (Handle diagnostics customization on the fluent side (for one specific diagnostic)) - #106978 (Migrate mir_build's borrow conflicts) - #107150 (`ty::tls` cleanups) - #107168 (Use a type-alias-impl-trait in `ObligationForest`) - #107189 (Encode info for Adt in a single place.) - #107322 (Custom mir: Add support for some remaining, easy to support constructs) - #107323 (Disable ConstGoto opt in cleanup blocks) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c62665e09c
36 changed files with 641 additions and 611 deletions
|
@ -367,18 +367,6 @@ fn check_opaque_type_parameter_valid(
|
|||
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
|
||||
let arg_is_param = match arg.unpack() {
|
||||
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
|
||||
GenericArgKind::Lifetime(lt) if lt.is_static() => {
|
||||
tcx.sess
|
||||
.struct_span_err(span, "non-defining opaque type use in defining scope")
|
||||
.span_label(
|
||||
tcx.def_span(opaque_generics.param_at(i, tcx).def_id),
|
||||
"cannot use static lifetime; use a bound lifetime \
|
||||
instead or remove the lifetime parameter from the \
|
||||
opaque type",
|
||||
)
|
||||
.emit();
|
||||
return false;
|
||||
}
|
||||
GenericArgKind::Lifetime(lt) => {
|
||||
matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
|
||||
}
|
||||
|
|
|
@ -1301,12 +1301,6 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> (bool, bool) {
|
|||
return (false, false);
|
||||
}
|
||||
|
||||
// If we're only producing artifacts that are archives, no need to preserve
|
||||
// the objects as they're losslessly contained inside the archives.
|
||||
if sess.crate_types().iter().all(|&x| x.is_archive()) {
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
match (sess.split_debuginfo(), sess.opts.unstable_opts.split_dwarf_kind) {
|
||||
// If there is no split debuginfo then do not preserve objects.
|
||||
(SplitDebuginfo::Off, _) => (false, false),
|
||||
|
|
|
@ -139,8 +139,7 @@ pub enum ProcessResult<O, E> {
|
|||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
struct ObligationTreeId(usize);
|
||||
|
||||
type ObligationTreeIdGenerator =
|
||||
std::iter::Map<std::ops::RangeFrom<usize>, fn(usize) -> ObligationTreeId>;
|
||||
type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
|
||||
|
||||
pub struct ObligationForest<O: ForestObligation> {
|
||||
/// The list of obligations. In between calls to [Self::process_obligations],
|
||||
|
|
|
@ -123,4 +123,7 @@ borrowck_cannot_move_when_borrowed =
|
|||
|
||||
borrowck_opaque_type_non_generic_param =
|
||||
expected generic {$kind} parameter, found `{$ty}`
|
||||
.label = this generic parameter must be used with a generic {$kind} parameter
|
||||
.label = {STREQ($ty, "'static") ->
|
||||
[true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
|
||||
*[other] this generic parameter must be used with a generic {$kind} parameter
|
||||
}
|
||||
|
|
|
@ -147,8 +147,6 @@ infer_region_explanation = {$pref_kind ->
|
|||
}{$desc_kind ->
|
||||
*[should_not_happen] [{$desc_kind}]
|
||||
[restatic] the static lifetime
|
||||
[reempty] the empty lifetime
|
||||
[reemptyuni] the empty lifetime in universe {$desc_arg}
|
||||
[revar] lifetime {$desc_arg}
|
||||
|
||||
[as_defined] the lifetime `{$desc_arg}` as defined here
|
||||
|
|
|
@ -299,10 +299,18 @@ mir_build_borrow_of_moved_value = borrow of moved value
|
|||
.suggestion = borrow this binding in the pattern to avoid moving the value
|
||||
|
||||
mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time
|
||||
.label = first mutable borrow, by `{$name}`, occurs here
|
||||
.mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here
|
||||
.immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here
|
||||
.moved = also moved into `{$name_moved}` here
|
||||
|
||||
mir_build_already_borrowed = cannot borrow value as mutable because it is also borrowed as immutable
|
||||
|
||||
mir_build_already_mut_borrowed = cannot borrow value as immutable because it is also borrowed as mutable
|
||||
|
||||
mir_build_moved_while_borrowed = cannot move out of value because it is borrowed
|
||||
|
||||
mir_build_mutable_borrow = value is mutably borrowed by `{$name}` here
|
||||
|
||||
mir_build_borrow = value is borrowed by `{$name}` here
|
||||
|
||||
mir_build_moved = value is moved into `{$name}` here
|
||||
|
||||
mir_build_union_pattern = cannot use unions in constant patterns
|
||||
|
||||
|
|
|
@ -182,6 +182,9 @@ pub fn fluent_bundle(
|
|||
trace!(?locale);
|
||||
let mut bundle = new_bundle(vec![locale]);
|
||||
|
||||
// Add convenience functions available to ftl authors.
|
||||
register_functions(&mut bundle);
|
||||
|
||||
// Fluent diagnostics can insert directionality isolation markers around interpolated variables
|
||||
// indicating that there may be a shift from right-to-left to left-to-right text (or
|
||||
// vice-versa). These are disabled because they are sometimes visible in the error output, but
|
||||
|
@ -244,6 +247,15 @@ pub fn fluent_bundle(
|
|||
Ok(Some(bundle))
|
||||
}
|
||||
|
||||
fn register_functions(bundle: &mut FluentBundle) {
|
||||
bundle
|
||||
.add_function("STREQ", |positional, _named| match positional {
|
||||
[FluentValue::String(a), FluentValue::String(b)] => format!("{}", (a == b)).into(),
|
||||
_ => FluentValue::Error,
|
||||
})
|
||||
.expect("Failed to add a function to the bundle.");
|
||||
}
|
||||
|
||||
/// Type alias for the result of `fallback_fluent_bundle` - a reference-counted pointer to a lazily
|
||||
/// evaluated fluent bundle.
|
||||
pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBundle>>;
|
||||
|
@ -256,6 +268,9 @@ pub fn fallback_fluent_bundle(
|
|||
) -> LazyFallbackBundle {
|
||||
Lrc::new(Lazy::new(move || {
|
||||
let mut fallback_bundle = new_bundle(vec![langid!("en-US")]);
|
||||
|
||||
register_functions(&mut fallback_bundle);
|
||||
|
||||
// See comment in `fluent_bundle`.
|
||||
fallback_bundle.set_use_isolating(with_directionality_markers);
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ use rustc_span::symbol::{sym, Symbol};
|
|||
use rustc_span::{
|
||||
self, DebuggerVisualizerFile, ExternalSource, FileName, SourceFile, Span, SyntaxContext,
|
||||
};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::hash::Hash;
|
||||
|
@ -1189,8 +1188,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
|
||||
}
|
||||
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
|
||||
let params_in_repr = self.tcx.params_in_repr(def_id);
|
||||
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
|
||||
self.encode_info_for_adt(def_id);
|
||||
}
|
||||
if should_encode_trait_impl_trait_tys(tcx, def_id)
|
||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
|
@ -1213,46 +1211,53 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn encode_info_for_adt(&mut self, def_id: DefId) {
|
||||
let tcx = self.tcx;
|
||||
let variant = &def.variant(index);
|
||||
let def_id = variant.def_id;
|
||||
debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
|
||||
let adt_def = tcx.adt_def(def_id);
|
||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||
|
||||
let data = VariantData {
|
||||
discr: variant.discr,
|
||||
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
};
|
||||
let params_in_repr = self.tcx.params_in_repr(def_id);
|
||||
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
|
||||
|
||||
record!(self.tables.variant_data[def_id] <- data);
|
||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
||||
record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
|
||||
assert!(f.did.is_local());
|
||||
f.did.index
|
||||
}));
|
||||
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
|
||||
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
|
||||
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
|
||||
if adt_def.is_enum() {
|
||||
record_array!(self.tables.children[def_id] <- iter::from_generator(||
|
||||
for variant in tcx.adt_def(def_id).variants() {
|
||||
yield variant.def_id.index;
|
||||
// Encode constructors which take a separate slot in value namespace.
|
||||
if let Some(ctor_def_id) = variant.ctor_def_id() {
|
||||
yield ctor_def_id.index;
|
||||
}
|
||||
}
|
||||
));
|
||||
} else {
|
||||
// For non-enum, there is only one variant, and its def_id is the adt's.
|
||||
debug_assert_eq!(adt_def.variants().len(), 1);
|
||||
debug_assert_eq!(adt_def.non_enum_variant().def_id, def_id);
|
||||
// Therefore, the loop over variants will encode its fields as the adt's children.
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
|
||||
let variant = &def.variant(index);
|
||||
let Some((ctor_kind, def_id)) = variant.ctor else { return };
|
||||
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
|
||||
for variant in adt_def.variants().iter() {
|
||||
let data = VariantData {
|
||||
discr: variant.discr,
|
||||
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
};
|
||||
record!(self.tables.variant_data[variant.def_id] <- data);
|
||||
|
||||
// FIXME(eddyb) encode only the `CtorKind` for constructors.
|
||||
let data = VariantData {
|
||||
discr: variant.discr,
|
||||
ctor: Some((ctor_kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
};
|
||||
self.tables.constness.set(variant.def_id.index, hir::Constness::Const);
|
||||
record_array!(self.tables.children[variant.def_id] <- variant.fields.iter().map(|f| {
|
||||
assert!(f.did.is_local());
|
||||
f.did.index
|
||||
}));
|
||||
|
||||
record!(self.tables.variant_data[def_id] <- data);
|
||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
||||
if ctor_kind == CtorKind::Fn {
|
||||
record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
|
||||
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
|
||||
self.tables.constness.set(ctor_def_id.index, hir::Constness::Const);
|
||||
let fn_sig = tcx.fn_sig(ctor_def_id);
|
||||
record!(self.tables.fn_sig[ctor_def_id] <- fn_sig);
|
||||
// FIXME only encode signature for ctor_def_id
|
||||
record!(self.tables.fn_sig[variant.def_id] <- fn_sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1305,25 +1310,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>) {
|
||||
let variant = adt_def.non_enum_variant();
|
||||
let Some((ctor_kind, def_id)) = variant.ctor else { return };
|
||||
debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
|
||||
|
||||
let data = VariantData {
|
||||
discr: variant.discr,
|
||||
ctor: Some((ctor_kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
};
|
||||
|
||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||
record!(self.tables.variant_data[def_id] <- data);
|
||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
||||
if ctor_kind == CtorKind::Fn {
|
||||
record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_explicit_item_bounds(&mut self, def_id: DefId) {
|
||||
debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id);
|
||||
let bounds = self.tcx.explicit_item_bounds(def_id);
|
||||
|
@ -1532,33 +1518,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
self.tables.is_type_alias_impl_trait.set_nullable(def_id.index, true);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Enum(..) => {
|
||||
let adt_def = self.tcx.adt_def(def_id);
|
||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||
}
|
||||
hir::ItemKind::Struct(..) => {
|
||||
let adt_def = self.tcx.adt_def(def_id);
|
||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
||||
|
||||
let variant = adt_def.non_enum_variant();
|
||||
record!(self.tables.variant_data[def_id] <- VariantData {
|
||||
discr: variant.discr,
|
||||
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
});
|
||||
}
|
||||
hir::ItemKind::Union(..) => {
|
||||
let adt_def = self.tcx.adt_def(def_id);
|
||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||
|
||||
let variant = adt_def.non_enum_variant();
|
||||
record!(self.tables.variant_data[def_id] <- VariantData {
|
||||
discr: variant.discr,
|
||||
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
});
|
||||
}
|
||||
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
|
||||
self.tables.impl_defaultness.set(def_id.index, *defaultness);
|
||||
self.tables.constness.set(def_id.index, *constness);
|
||||
|
@ -1597,31 +1556,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
}
|
||||
hir::ItemKind::Static(..)
|
||||
| hir::ItemKind::Const(..)
|
||||
| hir::ItemKind::Enum(..)
|
||||
| hir::ItemKind::Struct(..)
|
||||
| hir::ItemKind::Union(..)
|
||||
| hir::ItemKind::ForeignMod { .. }
|
||||
| hir::ItemKind::GlobalAsm(..)
|
||||
| hir::ItemKind::TyAlias(..) => {}
|
||||
};
|
||||
// FIXME(eddyb) there should be a nicer way to do this.
|
||||
match item.kind {
|
||||
hir::ItemKind::Enum(..) => {
|
||||
record_array!(self.tables.children[def_id] <- iter::from_generator(||
|
||||
for variant in tcx.adt_def(def_id).variants() {
|
||||
yield variant.def_id.index;
|
||||
// Encode constructors which take a separate slot in value namespace.
|
||||
if let Some(ctor_def_id) = variant.ctor_def_id() {
|
||||
yield ctor_def_id.index;
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
|
||||
record_array!(self.tables.children[def_id] <-
|
||||
self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
|
||||
assert!(f.did.is_local());
|
||||
f.did.index
|
||||
})
|
||||
)
|
||||
}
|
||||
hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
|
||||
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
|
||||
record_array!(self.tables.children[def_id] <-
|
||||
|
@ -1649,17 +1592,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
// so it's easier to do that here then to wait until we would encounter
|
||||
// normally in the visitor walk.
|
||||
match item.kind {
|
||||
hir::ItemKind::Enum(..) => {
|
||||
let def = self.tcx.adt_def(item.owner_id.to_def_id());
|
||||
for (i, _) in def.variants().iter_enumerated() {
|
||||
self.encode_enum_variant_info(def, i);
|
||||
self.encode_enum_variant_ctor(def, i);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Struct(..) => {
|
||||
let def = self.tcx.adt_def(item.owner_id.to_def_id());
|
||||
self.encode_struct_ctor(def);
|
||||
}
|
||||
hir::ItemKind::Impl { .. } => {
|
||||
for &trait_item_def_id in
|
||||
self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#![feature(min_specialization)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(strict_provenance)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#![allow(rustc::usage_of_ty_tykind)]
|
||||
|
||||
pub mod tls;
|
||||
|
||||
use crate::arena::Arena;
|
||||
use crate::dep_graph::{DepGraph, DepKindStruct};
|
||||
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
|
||||
|
@ -1212,178 +1214,6 @@ CloneLiftImpls! { for<'tcx> {
|
|||
Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
|
||||
} }
|
||||
|
||||
pub mod tls {
|
||||
use super::{ptr_eq, GlobalCtxt, TyCtxt};
|
||||
|
||||
use crate::dep_graph::TaskDepsRef;
|
||||
use crate::ty::query;
|
||||
use rustc_data_structures::sync::{self, Lock};
|
||||
use rustc_errors::Diagnostic;
|
||||
use std::mem;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
#[cfg(not(parallel_compiler))]
|
||||
use std::cell::Cell;
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
use rustc_rayon_core as rayon_core;
|
||||
|
||||
/// This is the implicit state of rustc. It contains the current
|
||||
/// `TyCtxt` and query. It is updated when creating a local interner or
|
||||
/// executing a new query. Whenever there's a `TyCtxt` value available
|
||||
/// you should also have access to an `ImplicitCtxt` through the functions
|
||||
/// in this module.
|
||||
#[derive(Clone)]
|
||||
pub struct ImplicitCtxt<'a, 'tcx> {
|
||||
/// The current `TyCtxt`.
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// The current query job, if any. This is updated by `JobOwner::start` in
|
||||
/// `ty::query::plumbing` when executing a query.
|
||||
pub query: Option<query::QueryJobId>,
|
||||
|
||||
/// Where to store diagnostics for the current query job, if any.
|
||||
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
|
||||
pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
|
||||
|
||||
/// Used to prevent queries from calling too deeply.
|
||||
pub query_depth: usize,
|
||||
|
||||
/// The current dep graph task. This is used to add dependencies to queries
|
||||
/// when executing them.
|
||||
pub task_deps: TaskDepsRef<'a>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
|
||||
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
|
||||
let tcx = TyCtxt { gcx };
|
||||
ImplicitCtxt {
|
||||
tcx,
|
||||
query: None,
|
||||
diagnostics: None,
|
||||
query_depth: 0,
|
||||
task_deps: TaskDepsRef::Ignore,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
|
||||
/// to `value` during the call to `f`. It is restored to its previous value after.
|
||||
/// This is used to set the pointer to the new `ImplicitCtxt`.
|
||||
#[cfg(parallel_compiler)]
|
||||
#[inline]
|
||||
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
|
||||
rayon_core::tlv::with(value, f)
|
||||
}
|
||||
|
||||
/// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
|
||||
/// This is used to get the pointer to the current `ImplicitCtxt`.
|
||||
#[cfg(parallel_compiler)]
|
||||
#[inline]
|
||||
pub fn get_tlv() -> usize {
|
||||
rayon_core::tlv::get()
|
||||
}
|
||||
|
||||
#[cfg(not(parallel_compiler))]
|
||||
thread_local! {
|
||||
/// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
|
||||
static TLV: Cell<usize> = const { Cell::new(0) };
|
||||
}
|
||||
|
||||
/// Sets TLV to `value` during the call to `f`.
|
||||
/// It is restored to its previous value after.
|
||||
/// This is used to set the pointer to the new `ImplicitCtxt`.
|
||||
#[cfg(not(parallel_compiler))]
|
||||
#[inline]
|
||||
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
|
||||
let old = get_tlv();
|
||||
let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
|
||||
TLV.with(|tlv| tlv.set(value));
|
||||
f()
|
||||
}
|
||||
|
||||
/// Gets the pointer to the current `ImplicitCtxt`.
|
||||
#[cfg(not(parallel_compiler))]
|
||||
#[inline]
|
||||
fn get_tlv() -> usize {
|
||||
TLV.with(|tlv| tlv.get())
|
||||
}
|
||||
|
||||
/// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
|
||||
#[inline]
|
||||
pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
|
||||
{
|
||||
set_tlv(context as *const _ as usize, || f(&context))
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt` in a closure if one is available.
|
||||
#[inline]
|
||||
pub fn with_context_opt<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
|
||||
{
|
||||
let context = get_tlv();
|
||||
if context == 0 {
|
||||
f(None)
|
||||
} else {
|
||||
// We could get an `ImplicitCtxt` pointer from another thread.
|
||||
// Ensure that `ImplicitCtxt` is `Sync`.
|
||||
sync::assert_sync::<ImplicitCtxt<'_, '_>>();
|
||||
|
||||
unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt`.
|
||||
/// Panics if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
pub fn with_context<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
|
||||
{
|
||||
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
|
||||
/// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
|
||||
/// as the `TyCtxt` passed in.
|
||||
/// This will panic if you pass it a `TyCtxt` which is different from the current
|
||||
/// `ImplicitCtxt`'s `tcx` field.
|
||||
#[inline]
|
||||
pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
|
||||
{
|
||||
with_context(|context| unsafe {
|
||||
assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
|
||||
let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
|
||||
f(context)
|
||||
})
|
||||
}
|
||||
|
||||
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
|
||||
/// Panics if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
pub fn with<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
|
||||
{
|
||||
with_context(|context| f(context.tcx))
|
||||
}
|
||||
|
||||
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
|
||||
/// The closure is passed None if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
pub fn with_opt<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
|
||||
{
|
||||
with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! sty_debug_print {
|
||||
($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
|
||||
// Curious inner module to allow variant names to be used as
|
||||
|
@ -2416,12 +2246,6 @@ pub struct DeducedParamAttrs {
|
|||
pub read_only: bool,
|
||||
}
|
||||
|
||||
// We are comparing types with different invariant lifetimes, so `ptr::eq`
|
||||
// won't work for us.
|
||||
fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
|
||||
t as *const () == u as *const ()
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
providers.module_reexports =
|
||||
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
|
||||
|
|
187
compiler/rustc_middle/src/ty/context/tls.rs
Normal file
187
compiler/rustc_middle/src/ty/context/tls.rs
Normal file
|
@ -0,0 +1,187 @@
|
|||
use super::{GlobalCtxt, TyCtxt};
|
||||
|
||||
use crate::dep_graph::TaskDepsRef;
|
||||
use crate::ty::query;
|
||||
use rustc_data_structures::sync::{self, Lock};
|
||||
use rustc_errors::Diagnostic;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
/// This is the implicit state of rustc. It contains the current
|
||||
/// `TyCtxt` and query. It is updated when creating a local interner or
|
||||
/// executing a new query. Whenever there's a `TyCtxt` value available
|
||||
/// you should also have access to an `ImplicitCtxt` through the functions
|
||||
/// in this module.
|
||||
#[derive(Clone)]
|
||||
pub struct ImplicitCtxt<'a, 'tcx> {
|
||||
/// The current `TyCtxt`.
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// The current query job, if any. This is updated by `JobOwner::start` in
|
||||
/// `ty::query::plumbing` when executing a query.
|
||||
pub query: Option<query::QueryJobId>,
|
||||
|
||||
/// Where to store diagnostics for the current query job, if any.
|
||||
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
|
||||
pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
|
||||
|
||||
/// Used to prevent queries from calling too deeply.
|
||||
pub query_depth: usize,
|
||||
|
||||
/// The current dep graph task. This is used to add dependencies to queries
|
||||
/// when executing them.
|
||||
pub task_deps: TaskDepsRef<'a>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
|
||||
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
|
||||
let tcx = TyCtxt { gcx };
|
||||
ImplicitCtxt {
|
||||
tcx,
|
||||
query: None,
|
||||
diagnostics: None,
|
||||
query_depth: 0,
|
||||
task_deps: TaskDepsRef::Ignore,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
mod tlv {
|
||||
use rustc_rayon_core as rayon_core;
|
||||
use std::ptr;
|
||||
|
||||
/// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
|
||||
/// This is used to get the pointer to the current `ImplicitCtxt`.
|
||||
#[inline]
|
||||
pub(super) fn get_tlv() -> *const () {
|
||||
ptr::from_exposed_addr(rayon_core::tlv::get())
|
||||
}
|
||||
|
||||
/// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
|
||||
/// to `value` during the call to `f`. It is restored to its previous value after.
|
||||
/// This is used to set the pointer to the new `ImplicitCtxt`.
|
||||
#[inline]
|
||||
pub(super) fn with_tlv<F: FnOnce() -> R, R>(value: *const (), f: F) -> R {
|
||||
rayon_core::tlv::with(value.expose_addr(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(parallel_compiler))]
|
||||
mod tlv {
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
|
||||
thread_local! {
|
||||
/// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
|
||||
static TLV: Cell<*const ()> = const { Cell::new(ptr::null()) };
|
||||
}
|
||||
|
||||
/// Gets the pointer to the current `ImplicitCtxt`.
|
||||
#[inline]
|
||||
pub(super) fn get_tlv() -> *const () {
|
||||
TLV.with(|tlv| tlv.get())
|
||||
}
|
||||
|
||||
/// Sets TLV to `value` during the call to `f`.
|
||||
/// It is restored to its previous value after.
|
||||
/// This is used to set the pointer to the new `ImplicitCtxt`.
|
||||
#[inline]
|
||||
pub(super) fn with_tlv<F: FnOnce() -> R, R>(value: *const (), f: F) -> R {
|
||||
let old = get_tlv();
|
||||
let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
|
||||
TLV.with(|tlv| tlv.set(value));
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn erase(context: &ImplicitCtxt<'_, '_>) -> *const () {
|
||||
context as *const _ as *const ()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn downcast<'a, 'tcx>(context: *const ()) -> &'a ImplicitCtxt<'a, 'tcx> {
|
||||
&*(context as *const ImplicitCtxt<'a, 'tcx>)
|
||||
}
|
||||
|
||||
/// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
|
||||
#[inline]
|
||||
pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
|
||||
{
|
||||
tlv::with_tlv(erase(context), || f(&context))
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt` in a closure if one is available.
|
||||
#[inline]
|
||||
pub fn with_context_opt<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
|
||||
{
|
||||
let context = tlv::get_tlv();
|
||||
if context.is_null() {
|
||||
f(None)
|
||||
} else {
|
||||
// We could get an `ImplicitCtxt` pointer from another thread.
|
||||
// Ensure that `ImplicitCtxt` is `Sync`.
|
||||
sync::assert_sync::<ImplicitCtxt<'_, '_>>();
|
||||
|
||||
unsafe { f(Some(downcast(context))) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt`.
|
||||
/// Panics if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
pub fn with_context<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
|
||||
{
|
||||
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
|
||||
/// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
|
||||
/// as the `TyCtxt` passed in.
|
||||
/// This will panic if you pass it a `TyCtxt` which is different from the current
|
||||
/// `ImplicitCtxt`'s `tcx` field.
|
||||
#[inline]
|
||||
pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
|
||||
{
|
||||
with_context(|context| {
|
||||
// The two gcx have different invariant lifetimes, so we need to erase them for the comparison.
|
||||
assert!(ptr::eq(
|
||||
context.tcx.gcx as *const _ as *const (),
|
||||
tcx.gcx as *const _ as *const ()
|
||||
));
|
||||
|
||||
let context: &ImplicitCtxt<'_, '_> = unsafe { mem::transmute(context) };
|
||||
|
||||
f(context)
|
||||
})
|
||||
}
|
||||
|
||||
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
|
||||
/// Panics if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
pub fn with<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
|
||||
{
|
||||
with_context(|context| f(context.tcx))
|
||||
}
|
||||
|
||||
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
|
||||
/// The closure is passed None if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
pub fn with_opt<F, R>(f: F) -> R
|
||||
where
|
||||
F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
|
||||
{
|
||||
with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
|
||||
}
|
|
@ -18,6 +18,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||
@call("mir_storage_dead", args) => {
|
||||
Ok(StatementKind::StorageDead(self.parse_local(args[0])?))
|
||||
},
|
||||
@call("mir_deinit", args) => {
|
||||
Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
|
||||
},
|
||||
@call("mir_retag", args) => {
|
||||
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
|
||||
},
|
||||
|
@ -141,6 +144,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||
fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
|
||||
parse_by_kind!(self, expr_id, _, "rvalue",
|
||||
@call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
|
||||
@call("mir_checked", args) => {
|
||||
parse_by_kind!(self, args[0], _, "binary op",
|
||||
ExprKind::Binary { op, lhs, rhs } => Ok(Rvalue::CheckedBinaryOp(
|
||||
*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
|
||||
)),
|
||||
)
|
||||
},
|
||||
@call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
|
||||
ExprKind::Borrow { borrow_kind, arg } => Ok(
|
||||
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
|
||||
),
|
||||
|
@ -153,6 +164,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||
ExprKind::Unary { op, arg } => Ok(
|
||||
Rvalue::UnaryOp(*op, self.parse_operand(*arg)?)
|
||||
),
|
||||
ExprKind::Repeat { value, count } => Ok(
|
||||
Rvalue::Repeat(self.parse_operand(*value)?, *count)
|
||||
),
|
||||
_ => self.parse_operand(expr_id).map(Rvalue::Use),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -600,32 +600,56 @@ pub struct BorrowOfMovedValue<'tcx> {
|
|||
pub struct MultipleMutBorrows {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub binding_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<MultipleMutBorrowOccurence>,
|
||||
pub name: Ident,
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_already_borrowed)]
|
||||
pub struct AlreadyBorrowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_already_mut_borrowed)]
|
||||
pub struct AlreadyMutBorrowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_moved_while_borrowed)]
|
||||
pub struct MovedWhileBorrowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum MultipleMutBorrowOccurence {
|
||||
#[label(mutable_borrow)]
|
||||
Mutable {
|
||||
pub enum Conflict {
|
||||
#[label(mir_build_mutable_borrow)]
|
||||
Mut {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name_mut: Ident,
|
||||
name: Ident,
|
||||
},
|
||||
#[label(immutable_borrow)]
|
||||
Immutable {
|
||||
#[label(mir_build_borrow)]
|
||||
Ref {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name_immut: Ident,
|
||||
name: Ident,
|
||||
},
|
||||
#[label(moved)]
|
||||
#[label(mir_build_moved)]
|
||||
Moved {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name_moved: Ident,
|
||||
name: Ident,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -926,58 +926,55 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||
sub.each_binding(|_, hir_id, span, name| {
|
||||
match typeck_results.extract_binding_mode(sess, hir_id, span) {
|
||||
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
|
||||
(Mutability::Not, Mutability::Not) => {} // Both sides are `ref`.
|
||||
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
|
||||
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
|
||||
// Both sides are `ref`.
|
||||
(Mutability::Not, Mutability::Not) => {}
|
||||
// 2x `ref mut`.
|
||||
(Mutability::Mut, Mutability::Mut) => {
|
||||
conflicts_mut_mut.push(Conflict::Mut { span, name })
|
||||
}
|
||||
(Mutability::Not, Mutability::Mut) => {
|
||||
conflicts_mut_ref.push(Conflict::Mut { span, name })
|
||||
}
|
||||
(Mutability::Mut, Mutability::Not) => {
|
||||
conflicts_mut_ref.push(Conflict::Ref { span, name })
|
||||
}
|
||||
},
|
||||
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id) => {
|
||||
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
|
||||
conflicts_move.push(Conflict::Moved { span, name }) // `ref mut?` + by-move conflict.
|
||||
}
|
||||
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
|
||||
}
|
||||
});
|
||||
|
||||
// Report errors if any.
|
||||
if !conflicts_mut_mut.is_empty() {
|
||||
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
|
||||
let mut occurences = vec![];
|
||||
let report_mut_mut = !conflicts_mut_mut.is_empty();
|
||||
let report_mut_ref = !conflicts_mut_ref.is_empty();
|
||||
let report_move_conflict = !conflicts_move.is_empty();
|
||||
|
||||
for (span, name_mut) in conflicts_mut_mut {
|
||||
occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut });
|
||||
}
|
||||
for (span, name_immut) in conflicts_mut_ref {
|
||||
occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut });
|
||||
}
|
||||
for (span, name_moved) in conflicts_move {
|
||||
occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved });
|
||||
}
|
||||
sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name });
|
||||
} else if !conflicts_mut_ref.is_empty() {
|
||||
let mut occurences = match mut_outer {
|
||||
Mutability::Mut => vec![Conflict::Mut { span: binding_span, name }],
|
||||
Mutability::Not => vec![Conflict::Ref { span: binding_span, name }],
|
||||
};
|
||||
occurences.extend(conflicts_mut_mut);
|
||||
occurences.extend(conflicts_mut_ref);
|
||||
occurences.extend(conflicts_move);
|
||||
|
||||
// Report errors if any.
|
||||
if report_mut_mut {
|
||||
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
|
||||
sess.emit_err(MultipleMutBorrows { span: pat.span, occurences });
|
||||
} else if report_mut_ref {
|
||||
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
|
||||
let (primary, also) = match mut_outer {
|
||||
Mutability::Mut => ("mutable", "immutable"),
|
||||
Mutability::Not => ("immutable", "mutable"),
|
||||
match mut_outer {
|
||||
Mutability::Mut => {
|
||||
sess.emit_err(AlreadyMutBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
Mutability::Not => {
|
||||
sess.emit_err(AlreadyBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
};
|
||||
let msg =
|
||||
format!("cannot borrow value as {} because it is also borrowed as {}", also, primary);
|
||||
let mut err = sess.struct_span_err(pat.span, &msg);
|
||||
err.span_label(binding_span, format!("{} borrow, by `{}`, occurs here", primary, name));
|
||||
for (span, name) in conflicts_mut_ref {
|
||||
err.span_label(span, format!("{} borrow, by `{}`, occurs here", also, name));
|
||||
}
|
||||
for (span, name) in conflicts_move {
|
||||
err.span_label(span, format!("also moved into `{}` here", name));
|
||||
}
|
||||
err.emit();
|
||||
} else if !conflicts_move.is_empty() {
|
||||
} else if report_move_conflict {
|
||||
// Report by-ref and by-move conflicts, e.g. `ref x @ y`.
|
||||
let mut err =
|
||||
sess.struct_span_err(pat.span, "cannot move out of value because it is borrowed");
|
||||
err.span_label(binding_span, format!("value borrowed, by `{}`, here", name));
|
||||
for (span, name) in conflicts_move {
|
||||
err.span_label(span, format!("value moved into `{}` here", name));
|
||||
}
|
||||
err.emit();
|
||||
sess.emit_err(MovedWhileBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,15 @@ impl<'tcx> MirPass<'tcx> for ConstGoto {
|
|||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
|
||||
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &BasicBlockData<'tcx>) {
|
||||
if data.is_cleanup {
|
||||
// Because of the restrictions around control flow in cleanup blocks, we don't perform
|
||||
// this optimization at all in such blocks.
|
||||
return;
|
||||
}
|
||||
self.super_basic_block_data(block, data);
|
||||
}
|
||||
|
||||
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
|
||||
let _: Option<_> = try {
|
||||
let target = terminator.kind.as_goto()?;
|
||||
|
|
|
@ -864,18 +864,6 @@ pub enum CrateType {
|
|||
ProcMacro,
|
||||
}
|
||||
|
||||
impl CrateType {
|
||||
/// When generated, is this crate type an archive?
|
||||
pub fn is_archive(&self) -> bool {
|
||||
match *self {
|
||||
CrateType::Rlib | CrateType::Staticlib => true,
|
||||
CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
|
||||
pub enum Passes {
|
||||
Some(Vec<String>),
|
||||
|
|
|
@ -211,13 +211,16 @@
|
|||
//!
|
||||
//! #### Statements
|
||||
//! - Assign statements work via normal Rust assignment.
|
||||
//! - [`Retag`] statements have an associated function.
|
||||
//! - [`Retag`], [`StorageLive`], [`StorageDead`], [`Deinit`] statements have an associated function.
|
||||
//!
|
||||
//! #### Rvalues
|
||||
//!
|
||||
//! - Operands implicitly convert to `Use` rvalues.
|
||||
//! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
|
||||
//! - [`Discriminant`] has an associated function.
|
||||
//! - [`Discriminant`] and [`Len`] have associated functions.
|
||||
//! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
|
||||
//! - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
|
||||
//! - Array repetition syntax (`[foo; 10]`) creates the associated rvalue.
|
||||
//!
|
||||
//! #### Terminators
|
||||
//!
|
||||
|
@ -261,6 +264,9 @@ define!("mir_drop_and_replace", fn DropAndReplace<T>(place: T, value: T, goto: B
|
|||
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
|
||||
define!("mir_storage_live", fn StorageLive<T>(local: T));
|
||||
define!("mir_storage_dead", fn StorageDead<T>(local: T));
|
||||
define!("mir_deinit", fn Deinit<T>(place: T));
|
||||
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
|
||||
define!("mir_len", fn Len<T>(place: T) -> usize);
|
||||
define!("mir_retag", fn Retag<T>(place: T));
|
||||
define!("mir_move", fn Move<T>(place: T) -> T);
|
||||
define!("mir_static", fn Static<T>(s: T) -> &'static T);
|
||||
|
|
14
tests/mir-opt/building/custom/arrays.arrays.built.after.mir
Normal file
14
tests/mir-opt/building/custom/arrays.arrays.built.after.mir
Normal file
|
@ -0,0 +1,14 @@
|
|||
// MIR for `arrays` after built
|
||||
|
||||
fn arrays() -> usize {
|
||||
let mut _0: usize; // return place in scope 0 at $DIR/arrays.rs:+0:32: +0:37
|
||||
let mut _1: [i32; C]; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
|
||||
bb0: {
|
||||
_1 = [const 5_i32; C]; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
_2 = Len(_1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
_0 = _2; // scope 0 at $DIR/arrays.rs:+4:9: +4:16
|
||||
return; // scope 0 at $DIR/arrays.rs:+5:9: +5:17
|
||||
}
|
||||
}
|
19
tests/mir-opt/building/custom/arrays.rs
Normal file
19
tests/mir-opt/building/custom/arrays.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
#![feature(custom_mir, core_intrinsics, inline_const)]
|
||||
|
||||
extern crate core;
|
||||
use core::intrinsics::mir::*;
|
||||
|
||||
// EMIT_MIR arrays.arrays.built.after.mir
|
||||
#[custom_mir(dialect = "built")]
|
||||
fn arrays<const C: usize>() -> usize {
|
||||
mir!({
|
||||
let x = [5_i32; C];
|
||||
let c = Len(x);
|
||||
RET = c;
|
||||
Return()
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(arrays::<20>(), 20);
|
||||
}
|
|
@ -86,6 +86,7 @@ fn switch_option_repr(option: Bool) -> bool {
|
|||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
fn set_discr(option: &mut Option<()>) {
|
||||
mir!({
|
||||
Deinit(*option);
|
||||
SetDiscriminant(*option, 0);
|
||||
Return()
|
||||
})
|
||||
|
|
|
@ -4,7 +4,8 @@ fn set_discr(_1: &mut Option<()>) -> () {
|
|||
let mut _0: (); // return place in scope 0 at $DIR/enums.rs:+0:39: +0:39
|
||||
|
||||
bb0: {
|
||||
discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+2:9: +2:36
|
||||
return; // scope 0 at $DIR/enums.rs:+3:9: +3:17
|
||||
Deinit((*_1)); // scope 0 at $DIR/enums.rs:+2:9: +2:24
|
||||
discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+3:9: +3:36
|
||||
return; // scope 0 at $DIR/enums.rs:+4:9: +4:17
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
fn f(_1: i32, _2: bool) -> i32 {
|
||||
let mut _0: i32; // return place in scope 0 at $DIR/operators.rs:+0:30: +0:33
|
||||
let mut _3: (i32, bool); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
|
||||
bb0: {
|
||||
_1 = Neg(_1); // scope 0 at $DIR/operators.rs:+2:9: +2:15
|
||||
|
@ -20,7 +21,10 @@ fn f(_1: i32, _2: bool) -> i32 {
|
|||
_2 = Le(_1, _1); // scope 0 at $DIR/operators.rs:+15:9: +15:19
|
||||
_2 = Ge(_1, _1); // scope 0 at $DIR/operators.rs:+16:9: +16:19
|
||||
_2 = Gt(_1, _1); // scope 0 at $DIR/operators.rs:+17:9: +17:18
|
||||
_0 = _1; // scope 0 at $DIR/operators.rs:+18:9: +18:16
|
||||
return; // scope 0 at $DIR/operators.rs:+19:9: +19:17
|
||||
_3 = CheckedAdd(_1, _1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
_2 = (_3.1: bool); // scope 0 at $DIR/operators.rs:+19:9: +19:18
|
||||
_1 = (_3.0: i32); // scope 0 at $DIR/operators.rs:+20:9: +20:18
|
||||
_0 = _1; // scope 0 at $DIR/operators.rs:+21:9: +21:16
|
||||
return; // scope 0 at $DIR/operators.rs:+22:9: +22:17
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ pub fn f(a: i32, b: bool) -> i32 {
|
|||
b = a <= a;
|
||||
b = a >= a;
|
||||
b = a > a;
|
||||
let res = Checked(a + a);
|
||||
b = res.1;
|
||||
a = res.0;
|
||||
RET = a;
|
||||
Return()
|
||||
})
|
||||
|
|
|
@ -254,12 +254,12 @@ unpacked-remapped-single:
|
|||
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
|
||||
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
|
||||
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
|
||||
ls $(TMPDIR)/*.o
|
||||
rm $(TMPDIR)/*.o
|
||||
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
|
||||
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
|
||||
rm $(TMPDIR)/$(call BIN,foo)
|
||||
|
||||
unpacked-crosscrate: packed-crosscrate-split packed-crosscrate-single
|
||||
unpacked-crosscrate: unpacked-crosscrate-split unpacked-crosscrate-single
|
||||
|
||||
# - Debuginfo in `.dwo` files
|
||||
# - (bar) `.rlib` file created, contains `.dwo`
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref foo @ [.., ref mut bar] => (),
|
||||
| -------^^^^^^^^-----------^
|
||||
| | |
|
||||
| | mutable borrow, by `bar`, occurs here
|
||||
| immutable borrow, by `foo`, occurs here
|
||||
| | value is mutably borrowed by `bar` here
|
||||
| value is borrowed by `foo` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9
|
||||
|
@ -13,8 +13,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref foo @ Some(box ref mut s) => (),
|
||||
| -------^^^^^^^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `s`, occurs here
|
||||
| immutable borrow, by `foo`, occurs here
|
||||
| | value is mutably borrowed by `s` here
|
||||
| value is borrowed by `foo` here
|
||||
|
||||
error[E0382]: borrow of moved value: `x`
|
||||
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:18:5
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | Some(ref _y @ _z) => {}
|
||||
| ------^^^--
|
||||
| | |
|
||||
| | value moved into `_z` here
|
||||
| value borrowed, by `_y`, here
|
||||
| | value is moved into `_z` here
|
||||
| value is borrowed by `_y` here
|
||||
|
||||
error: borrow of moved value
|
||||
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:14
|
||||
|
@ -28,8 +28,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | Some(ref mut _y @ _z) => {}
|
||||
| ----------^^^--
|
||||
| | |
|
||||
| | value moved into `_z` here
|
||||
| value borrowed, by `_y`, here
|
||||
| | value is moved into `_z` here
|
||||
| value is mutably borrowed by `_y` here
|
||||
|
||||
error: borrow of moved value
|
||||
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:33:14
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ box b = Box::new(NC);
|
||||
| -----^^^^^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:34:9
|
||||
|
@ -13,8 +13,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ box ref mut b = Box::new(nc());
|
||||
| -----^^^^^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:36:9
|
||||
|
@ -22,8 +22,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ box ref mut b = Box::new(NC);
|
||||
| -----^^^^^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:38:9
|
||||
|
@ -31,8 +31,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ box ref mut b = Box::new(NC);
|
||||
| -----^^^^^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:42:9
|
||||
|
@ -40,8 +40,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ box ref mut b = Box::new(NC);
|
||||
| -----^^^^^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:48:9
|
||||
|
@ -49,8 +49,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | let ref mut a @ box ref b = Box::new(NC);
|
||||
| ---------^^^^^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:62:9
|
||||
|
@ -58,8 +58,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ box ref b => {
|
||||
| ---------^^^^^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:54:11
|
||||
|
@ -67,8 +67,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
|
||||
| ---------^^^^^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error[E0382]: borrow of moved value
|
||||
--> $DIR/borrowck-pat-at-and-box.rs:31:9
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ b = U;
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:26:9
|
||||
|
@ -13,9 +13,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
|
||||
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^
|
||||
| | | |
|
||||
| | | value moved into `e` here
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `e` here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:26:18
|
||||
|
@ -23,8 +23,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
|
||||
| -----^^^-----
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `b` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:26:33
|
||||
|
@ -32,8 +32,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `e` here
|
||||
| value borrowed, by `d`, here
|
||||
| | value is moved into `e` here
|
||||
| value is borrowed by `d` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:30:9
|
||||
|
@ -41,9 +41,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref mut a @ [b, mut c] = [U, U];
|
||||
| ---------^^^^-^^-----^
|
||||
| | | |
|
||||
| | | value moved into `c` here
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `c` here
|
||||
| | value is moved into `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:9
|
||||
|
@ -51,8 +51,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ b = u();
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:9
|
||||
|
@ -60,9 +60,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
|
||||
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^
|
||||
| | | |
|
||||
| | | value moved into `e` here
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `e` here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:18
|
||||
|
@ -70,8 +70,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
|
||||
| -----^^^-----
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `b` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:33
|
||||
|
@ -79,8 +79,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `e` here
|
||||
| value borrowed, by `d`, here
|
||||
| | value is moved into `e` here
|
||||
| value is borrowed by `d` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:42:9
|
||||
|
@ -88,9 +88,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref mut a @ [b, mut c] = [u(), u()];
|
||||
| ---------^^^^-^^-----^
|
||||
| | | |
|
||||
| | | value moved into `c` here
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `c` here
|
||||
| | value is moved into `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:47:9
|
||||
|
@ -98,8 +98,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some(b) => {}
|
||||
| -----^^^^^^^^-^
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:52:9
|
||||
|
@ -107,9 +107,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
|
||||
| -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
|
||||
| | | |
|
||||
| | | value moved into `e` here
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `e` here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:52:23
|
||||
|
@ -117,8 +117,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
|
||||
| -----^^^-----
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `b` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:52:38
|
||||
|
@ -126,8 +126,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `e` here
|
||||
| value borrowed, by `d`, here
|
||||
| | value is moved into `e` here
|
||||
| value is borrowed by `d` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:59:9
|
||||
|
@ -135,9 +135,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref mut a @ Some([b, mut c]) => {}
|
||||
| ---------^^^^^^^^^-^^-----^^
|
||||
| | | |
|
||||
| | | value moved into `c` here
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `c` here
|
||||
| | value is moved into `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:64:9
|
||||
|
@ -145,8 +145,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some(b) => {}
|
||||
| -----^^^^^^^^-^
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:9
|
||||
|
@ -154,9 +154,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
|
||||
| -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
|
||||
| | | |
|
||||
| | | value moved into `e` here
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `e` here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:23
|
||||
|
@ -164,8 +164,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
|
||||
| -----^^^-----
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `b` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:38
|
||||
|
@ -173,8 +173,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `e` here
|
||||
| value borrowed, by `d`, here
|
||||
| | value is moved into `e` here
|
||||
| value is borrowed by `d` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:78:9
|
||||
|
@ -182,9 +182,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref mut a @ Some([b, mut c]) => {}
|
||||
| ---------^^^^^^^^^-^^-----^^
|
||||
| | | |
|
||||
| | | value moved into `c` here
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `c` here
|
||||
| | value is moved into `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:11:11
|
||||
|
@ -192,8 +192,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f1(ref a @ b: U) {}
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:11
|
||||
|
@ -201,9 +201,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
|
||||
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^
|
||||
| | | |
|
||||
| | | value moved into `e` here
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `e` here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:20
|
||||
|
@ -211,8 +211,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
|
||||
| -----^^^-----
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is borrowed by `b` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:35
|
||||
|
@ -220,8 +220,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `e` here
|
||||
| value borrowed, by `d`, here
|
||||
| | value is moved into `e` here
|
||||
| value is borrowed by `d` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:20:11
|
||||
|
@ -229,9 +229,9 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
|
||||
| ---------^^^^-^^-----^
|
||||
| | | |
|
||||
| | | value moved into `c` here
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | | value is moved into `c` here
|
||||
| | value is moved into `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error[E0382]: borrow of partially moved value
|
||||
--> $DIR/borrowck-pat-by-move-and-ref.rs:30:9
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut z @ &mut Some(ref a) => {
|
||||
| ---------^^^^^^^^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `a`, occurs here
|
||||
| mutable borrow, by `z`, occurs here
|
||||
| | value is borrowed by `a` here
|
||||
| value is mutably borrowed by `z` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:9
|
||||
|
@ -13,9 +13,9 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
|
||||
| ---------^^^^-----------------^
|
||||
| | | |
|
||||
| | | another mutable borrow, by `c`, occurs here
|
||||
| | also borrowed as immutable, by `b`, here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | | value is mutably borrowed by `c` here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:22
|
||||
|
@ -23,8 +23,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
|
||||
| -----^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `c`, occurs here
|
||||
| immutable borrow, by `b`, occurs here
|
||||
| | value is mutably borrowed by `c` here
|
||||
| value is borrowed by `b` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9
|
||||
|
@ -32,8 +32,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ ref mut b = U;
|
||||
| -----^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
|
||||
|
@ -41,8 +41,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | let ref mut a @ ref b = U;
|
||||
| ---------^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
|
||||
|
@ -50,9 +50,9 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
|
||||
| -----^^^^---------^^---------^
|
||||
| | | |
|
||||
| | | mutable borrow, by `c`, occurs here
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | | value is mutably borrowed by `c` here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9
|
||||
|
@ -60,9 +60,9 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | let ref mut a @ (ref b, ref c) = (U, U);
|
||||
| ---------^^^^-----^^-----^
|
||||
| | | |
|
||||
| | | immutable borrow, by `c`, occurs here
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | | value is borrowed by `c` here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9
|
||||
|
@ -70,8 +70,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | let ref mut a @ ref b = u();
|
||||
| ---------^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:51:9
|
||||
|
@ -79,8 +79,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ ref mut b = u();
|
||||
| -----^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:57:9
|
||||
|
@ -88,8 +88,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | let ref mut a @ ref b = U;
|
||||
| ---------^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:61:9
|
||||
|
@ -97,8 +97,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ ref mut b = U;
|
||||
| -----^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:9
|
||||
|
@ -106,8 +106,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
|
||||
| ---------^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:33
|
||||
|
@ -115,8 +115,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
|
||||
| ---------^^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:9
|
||||
|
@ -124,8 +124,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
|
||||
| -----^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:33
|
||||
|
@ -133,8 +133,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
|
||||
| -----^^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:9
|
||||
|
@ -142,8 +142,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
|
||||
| -----^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:33
|
||||
|
@ -151,8 +151,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
|
||||
| -----^^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:9
|
||||
|
@ -160,8 +160,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
|
||||
| ---------^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:33
|
||||
|
@ -169,8 +169,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
|
||||
| ---------^^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:9
|
||||
|
@ -178,8 +178,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
|
||||
| -----^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:33
|
||||
|
@ -187,8 +187,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
|
||||
| -----^^^^^^^---------^
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:9
|
||||
|
@ -196,8 +196,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
|
||||
| ---------^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:33
|
||||
|
@ -205,8 +205,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
|
||||
| ---------^^^^^^^-----^
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9
|
||||
|
@ -214,9 +214,9 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
|
||||
| -----^^^^---------^^---------^
|
||||
| | | |
|
||||
| | | mutable borrow, by `c`, occurs here
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | | value is mutably borrowed by `c` here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
|
||||
|
@ -224,9 +224,9 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
|
||||
| -----^^^^---------^^---------^
|
||||
| | | |
|
||||
| | | mutable borrow, by `c`, occurs here
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | | value is mutably borrowed by `c` here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9
|
||||
|
@ -234,9 +234,9 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
|
||||
| -----^^^^---------^^---------^
|
||||
| | | |
|
||||
| | | mutable borrow, by `c`, occurs here
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | | value is mutably borrowed by `c` here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:134:9
|
||||
|
@ -244,9 +244,9 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | let ref mut a @ (ref b, ref c) = (U, U);
|
||||
| ---------^^^^-----^^-----^
|
||||
| | | |
|
||||
| | | immutable borrow, by `c`, occurs here
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | | value is borrowed by `c` here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11
|
||||
|
@ -254,8 +254,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | fn f1(ref a @ ref mut b: U) {}
|
||||
| -----^^^---------
|
||||
| | |
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11
|
||||
|
@ -263,8 +263,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
|
|||
LL | fn f2(ref mut a @ ref b: U) {}
|
||||
| ---------^^^-----
|
||||
| | |
|
||||
| | immutable borrow, by `b`, occurs here
|
||||
| mutable borrow, by `a`, occurs here
|
||||
| | value is borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11
|
||||
|
@ -272,8 +272,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
|
||||
| -----^^^^^^^^^^^----------------^^^^^^^^
|
||||
| | |
|
||||
| | mutable borrow, by `mid`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `mid` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22
|
||||
|
@ -281,9 +281,9 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
|
|||
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
|
||||
| -----^^^-------------
|
||||
| | | |
|
||||
| | | also moved into `c` here
|
||||
| | mutable borrow, by `b`, occurs here
|
||||
| immutable borrow, by `a`, occurs here
|
||||
| | | value is moved into `c` here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30
|
||||
|
@ -291,8 +291,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
|
||||
| ---------^^^-
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is mutably borrowed by `b` here
|
||||
|
||||
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ ref mut b = U;
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:29:9
|
||||
|
@ -13,8 +13,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ ref mut b = U;
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:33:9
|
||||
|
@ -22,8 +22,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ ref mut b = U;
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:36:9
|
||||
|
@ -31,8 +31,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ ref mut b = U;
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:39:9
|
||||
|
@ -40,8 +40,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ ref mut b = U;
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:44:9
|
||||
|
@ -49,18 +49,18 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ (
|
||||
| ^--------
|
||||
| |
|
||||
| _________first mutable borrow, by `a`, occurs here
|
||||
| _________value is mutably borrowed by `a` here
|
||||
| |
|
||||
LL | |
|
||||
LL | | ref mut b,
|
||||
| | --------- another mutable borrow, by `b`, occurs here
|
||||
| | --------- value is mutably borrowed by `b` here
|
||||
LL | | [
|
||||
LL | | ref mut c,
|
||||
| | --------- another mutable borrow, by `c`, occurs here
|
||||
| | --------- value is mutably borrowed by `c` here
|
||||
LL | | ref mut d,
|
||||
| | --------- another mutable borrow, by `d`, occurs here
|
||||
| | --------- value is mutably borrowed by `d` here
|
||||
LL | | ref e,
|
||||
| | ----- also borrowed as immutable, by `e`, here
|
||||
| | ----- value is borrowed by `e` here
|
||||
LL | | ]
|
||||
LL | | ) = (U, [U, U, U]);
|
||||
| |_____^
|
||||
|
@ -71,18 +71,18 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | let ref mut a @ (
|
||||
| ^--------
|
||||
| |
|
||||
| _________first mutable borrow, by `a`, occurs here
|
||||
| _________value is mutably borrowed by `a` here
|
||||
| |
|
||||
LL | |
|
||||
LL | | ref mut b,
|
||||
| | --------- another mutable borrow, by `b`, occurs here
|
||||
| | --------- value is mutably borrowed by `b` here
|
||||
LL | | [
|
||||
LL | | ref mut c,
|
||||
| | --------- another mutable borrow, by `c`, occurs here
|
||||
| | --------- value is mutably borrowed by `c` here
|
||||
LL | | ref mut d,
|
||||
| | --------- another mutable borrow, by `d`, occurs here
|
||||
| | --------- value is mutably borrowed by `d` here
|
||||
LL | | ref e,
|
||||
| | ----- also borrowed as immutable, by `e`, here
|
||||
| | ----- value is borrowed by `e` here
|
||||
LL | | ]
|
||||
LL | | ) = (u(), [u(), u(), u()]);
|
||||
| |_________^
|
||||
|
@ -157,8 +157,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:76:37
|
||||
|
@ -166,8 +166,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
|
||||
|
@ -175,8 +175,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
|
||||
|
@ -184,8 +184,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:9
|
||||
|
@ -193,8 +193,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:37
|
||||
|
@ -202,8 +202,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:9
|
||||
|
@ -211,8 +211,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:37
|
||||
|
@ -220,8 +220,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
|
||||
| ---------^^^^^^^---------^
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:8:11
|
||||
|
@ -229,8 +229,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | fn f1(ref mut a @ ref mut b: U) {}
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:10:11
|
||||
|
@ -238,8 +238,8 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | fn f2(ref mut a @ ref mut b: U) {}
|
||||
| ---------^^^---------
|
||||
| | |
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:13:9
|
||||
|
@ -247,13 +247,13 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | ref mut a @ [
|
||||
| ^--------
|
||||
| |
|
||||
| _________first mutable borrow, by `a`, occurs here
|
||||
| _________value is mutably borrowed by `a` here
|
||||
| |
|
||||
LL | |
|
||||
LL | | [ref b @ .., _],
|
||||
| | ---------- also borrowed as immutable, by `b`, here
|
||||
| | ---------- value is borrowed by `b` here
|
||||
LL | | [_, ref mut mid @ ..],
|
||||
| | ---------------- another mutable borrow, by `mid`, occurs here
|
||||
| | ---------------- value is mutably borrowed by `mid` here
|
||||
LL | | ..,
|
||||
LL | | [..],
|
||||
LL | | ] : [[U; 4]; 5]
|
||||
|
@ -265,9 +265,9 @@ error: cannot borrow value as mutable more than once at a time
|
|||
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
|
||||
| ---------^^^-------------
|
||||
| | | |
|
||||
| | | also moved into `c` here
|
||||
| | another mutable borrow, by `b`, occurs here
|
||||
| first mutable borrow, by `a`, occurs here
|
||||
| | | value is moved into `c` here
|
||||
| | value is mutably borrowed by `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:21:34
|
||||
|
@ -275,8 +275,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
|
||||
| ---------^^^-
|
||||
| | |
|
||||
| | value moved into `c` here
|
||||
| value borrowed, by `b`, here
|
||||
| | value is moved into `c` here
|
||||
| value is mutably borrowed by `b` here
|
||||
|
||||
error[E0499]: cannot borrow value as mutable more than once at a time
|
||||
--> $DIR/borrowck-pat-ref-mut-twice.rs:29:9
|
||||
|
|
|
@ -4,8 +4,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref a @ b = NotCopy;
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/default-binding-modes-both-sides-independent.rs:29:9
|
||||
|
@ -13,8 +13,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref mut a @ b = NotCopy;
|
||||
| ---------^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is mutably borrowed by `a` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/default-binding-modes-both-sides-independent.rs:34:12
|
||||
|
@ -22,8 +22,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | Ok(ref a @ b) | Err(b @ ref a) => {
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error: borrow of moved value
|
||||
--> $DIR/default-binding-modes-both-sides-independent.rs:34:29
|
||||
|
@ -46,8 +46,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | ref a @ b => {
|
||||
| -----^^^-
|
||||
| | |
|
||||
| | value moved into `b` here
|
||||
| value borrowed, by `a`, here
|
||||
| | value is moved into `b` here
|
||||
| value is borrowed by `a` here
|
||||
|
||||
error[E0382]: borrow of moved value
|
||||
--> $DIR/default-binding-modes-both-sides-independent.rs:29:9
|
||||
|
|
|
@ -19,8 +19,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref _moved @ _from = String::from("foo");
|
||||
| ----------^^^-----
|
||||
| | |
|
||||
| | value moved into `_from` here
|
||||
| value borrowed, by `_moved`, here
|
||||
| | value is moved into `_from` here
|
||||
| value is borrowed by `_moved` here
|
||||
|
||||
error: cannot move out of value because it is borrowed
|
||||
--> $DIR/ref-pattern-binding.rs:15:9
|
||||
|
@ -28,8 +28,8 @@ error: cannot move out of value because it is borrowed
|
|||
LL | let ref _moved @ S { f } = S { f: String::from("foo") };
|
||||
| ----------^^^^^^^-^^
|
||||
| | |
|
||||
| | value moved into `f` here
|
||||
| value borrowed, by `_moved`, here
|
||||
| | value is moved into `f` here
|
||||
| value is borrowed by `_moved` here
|
||||
|
||||
error: borrow of moved value
|
||||
--> $DIR/ref-pattern-binding.rs:18:9
|
||||
|
|
|
@ -8,7 +8,7 @@ type X<'a> = impl Into<&'static str> + From<&'a str>;
|
|||
fn f<'a: 'static>(t: &'a str) -> X<'a> {
|
||||
//~^ WARNING unnecessary lifetime parameter
|
||||
t
|
||||
//~^ ERROR non-defining opaque type use
|
||||
//~^ ERROR expected generic lifetime parameter, found `'static`
|
||||
}
|
||||
|
||||
fn extend_lt<'a>(o: &'a str) -> &'static str {
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | fn f<'a: 'static>(t: &'a str) -> X<'a> {
|
|||
|
|
||||
= help: you can use the `'static` lifetime directly, in place of `'a`
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
error[E0792]: expected generic lifetime parameter, found `'static`
|
||||
--> $DIR/bounds-are-checked.rs:10:5
|
||||
|
|
||||
LL | type X<'a> = impl Into<&'static str> + From<&'a str>;
|
||||
|
@ -17,3 +17,4 @@ LL | t
|
|||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
||||
|
|
|
@ -19,7 +19,7 @@ fn concrete_ty() -> OneTy<u32> {
|
|||
|
||||
fn concrete_lifetime() -> OneLifetime<'static> {
|
||||
6u32
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
//~^ ERROR expected generic lifetime parameter, found `'static`
|
||||
}
|
||||
|
||||
fn concrete_const() -> OneConst<{ 123 }> {
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | type OneTy<T> = impl Debug;
|
|||
LL | 5u32
|
||||
| ^^^^
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
error[E0792]: expected generic lifetime parameter, found `'static`
|
||||
--> $DIR/generic_nondefining_use.rs:21:5
|
||||
|
|
||||
LL | type OneLifetime<'a> = impl Debug;
|
||||
|
|
Loading…
Add table
Reference in a new issue