Auto merge of #84822 - Dylan-DPC:rollup-wego8d6, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #84358 (Update closure capture error logging for disjoint captures for disjoint captures) - #84392 (Make AssertKind::fmt_assert_args public) - #84752 (Fix debuginfo for generators) - #84763 (shrink doctree::Module) - #84821 (Fix nit in rustc_session::options) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e10cbc33c1
68 changed files with 665 additions and 250 deletions
|
@ -309,6 +309,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
|
|||
unfinished_type,
|
||||
member_holding_stub,
|
||||
member_descriptions,
|
||||
None,
|
||||
);
|
||||
MetadataCreationResult::new(metadata_stub, true)
|
||||
}
|
||||
|
@ -1459,6 +1460,7 @@ struct EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
layout: TyAndLayout<'tcx>,
|
||||
tag_type_metadata: Option<&'ll DIType>,
|
||||
containing_scope: &'ll DIScope,
|
||||
common_members: Vec<Option<&'ll DIType>>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
|
@ -1493,10 +1495,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
} else {
|
||||
type_metadata(cx, self.enum_type, self.span)
|
||||
};
|
||||
let flags = match self.enum_type.kind() {
|
||||
ty::Generator(..) => DIFlags::FlagArtificial,
|
||||
_ => DIFlags::FlagZero,
|
||||
};
|
||||
|
||||
match self.layout.variants {
|
||||
Variants::Single { index } => {
|
||||
|
@ -1523,6 +1521,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
member_descriptions,
|
||||
Some(&self.common_members),
|
||||
);
|
||||
vec![MemberDescription {
|
||||
name: if fallback { String::new() } else { variant_info.variant_name() },
|
||||
|
@ -1530,7 +1529,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
offset: Size::ZERO,
|
||||
size: self.layout.size,
|
||||
align: self.layout.align.abi,
|
||||
flags,
|
||||
flags: DIFlags::FlagZero,
|
||||
discriminant: None,
|
||||
source_info: variant_info.source_info(cx),
|
||||
}]
|
||||
|
@ -1572,6 +1571,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
member_descriptions,
|
||||
Some(&self.common_members),
|
||||
);
|
||||
|
||||
MemberDescription {
|
||||
|
@ -1584,7 +1584,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
offset: Size::ZERO,
|
||||
size: self.layout.size,
|
||||
align: self.layout.align.abi,
|
||||
flags,
|
||||
flags: DIFlags::FlagZero,
|
||||
discriminant: Some(
|
||||
self.layout.ty.discriminant_for_variant(cx.tcx, i).unwrap().val
|
||||
as u64,
|
||||
|
@ -1621,6 +1621,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
variant_member_descriptions,
|
||||
Some(&self.common_members),
|
||||
);
|
||||
|
||||
// Encode the information about the null variant in the union
|
||||
|
@ -1667,7 +1668,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
offset: Size::ZERO,
|
||||
size: variant.size,
|
||||
align: variant.align.abi,
|
||||
flags,
|
||||
flags: DIFlags::FlagZero,
|
||||
discriminant: None,
|
||||
source_info: variant_info.source_info(cx),
|
||||
}]
|
||||
|
@ -1695,6 +1696,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
member_descriptions,
|
||||
Some(&self.common_members),
|
||||
);
|
||||
|
||||
let niche_value = if i == dataful_variant {
|
||||
|
@ -1717,7 +1719,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
offset: Size::ZERO,
|
||||
size: self.layout.size,
|
||||
align: self.layout.align.abi,
|
||||
flags,
|
||||
flags: DIFlags::FlagZero,
|
||||
discriminant: niche_value,
|
||||
source_info: variant_info.source_info(cx),
|
||||
}
|
||||
|
@ -1849,13 +1851,6 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn is_artificial(&self) -> bool {
|
||||
match self {
|
||||
VariantInfo::Generator { .. } => true,
|
||||
VariantInfo::Adt(..) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
|
||||
|
@ -1881,8 +1876,7 @@ fn describe_enum_variant(
|
|||
&variant_name,
|
||||
unique_type_id,
|
||||
Some(containing_scope),
|
||||
// FIXME(tmandry): This doesn't seem to have any effect.
|
||||
if variant.is_artificial() { DIFlags::FlagArtificial } else { DIFlags::FlagZero },
|
||||
DIFlags::FlagZero,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -1945,11 +1939,6 @@ fn prepare_enum_metadata(
|
|||
) -> RecursiveTypeDescription<'ll, 'tcx> {
|
||||
let tcx = cx.tcx;
|
||||
let enum_name = compute_debuginfo_type_name(tcx, enum_type, false);
|
||||
// FIXME(tmandry): This doesn't seem to have any effect.
|
||||
let enum_flags = match enum_type.kind() {
|
||||
ty::Generator(..) => DIFlags::FlagArtificial,
|
||||
_ => DIFlags::FlagZero,
|
||||
};
|
||||
|
||||
let containing_scope = get_namespace_for_item(cx, enum_def_id);
|
||||
// FIXME: This should emit actual file metadata for the enum, but we
|
||||
|
@ -2082,7 +2071,7 @@ fn prepare_enum_metadata(
|
|||
UNKNOWN_LINE_NUMBER,
|
||||
layout.size.bits(),
|
||||
layout.align.abi.bits() as u32,
|
||||
enum_flags,
|
||||
DIFlags::FlagZero,
|
||||
None,
|
||||
0, // RuntimeLang
|
||||
unique_type_id_str.as_ptr().cast(),
|
||||
|
@ -2102,6 +2091,7 @@ fn prepare_enum_metadata(
|
|||
layout,
|
||||
tag_type_metadata: discriminant_type_metadata,
|
||||
containing_scope,
|
||||
common_members: vec![],
|
||||
span,
|
||||
}),
|
||||
);
|
||||
|
@ -2171,7 +2161,7 @@ fn prepare_enum_metadata(
|
|||
}
|
||||
};
|
||||
|
||||
let mut outer_fields = match layout.variants {
|
||||
let outer_fields = match layout.variants {
|
||||
Variants::Single { .. } => vec![],
|
||||
Variants::Multiple { .. } => {
|
||||
let tuple_mdf = TupleMemberDescriptionFactory {
|
||||
|
@ -2203,18 +2193,21 @@ fn prepare_enum_metadata(
|
|||
UNKNOWN_LINE_NUMBER,
|
||||
layout.size.bits(),
|
||||
layout.align.abi.bits() as u32,
|
||||
enum_flags,
|
||||
DIFlags::FlagZero,
|
||||
discriminator_metadata,
|
||||
empty_array,
|
||||
variant_part_unique_type_id_str.as_ptr().cast(),
|
||||
variant_part_unique_type_id_str.len(),
|
||||
)
|
||||
};
|
||||
outer_fields.push(Some(variant_part));
|
||||
|
||||
let struct_wrapper = {
|
||||
// The variant part must be wrapped in a struct according to DWARF.
|
||||
let type_array = create_DIArray(DIB(cx), &outer_fields);
|
||||
// All fields except the discriminant (including `outer_fields`)
|
||||
// should be put into structures inside the variant part, which gives
|
||||
// an equivalent layout but offers us much better integration with
|
||||
// debuggers.
|
||||
let type_array = create_DIArray(DIB(cx), &[Some(variant_part)]);
|
||||
|
||||
let type_map = debug_context(cx).type_map.borrow();
|
||||
let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
|
||||
|
@ -2229,7 +2222,7 @@ fn prepare_enum_metadata(
|
|||
UNKNOWN_LINE_NUMBER,
|
||||
layout.size.bits(),
|
||||
layout.align.abi.bits() as u32,
|
||||
enum_flags,
|
||||
DIFlags::FlagZero,
|
||||
None,
|
||||
type_array,
|
||||
0,
|
||||
|
@ -2251,6 +2244,7 @@ fn prepare_enum_metadata(
|
|||
layout,
|
||||
tag_type_metadata: None,
|
||||
containing_scope,
|
||||
common_members: outer_fields,
|
||||
span,
|
||||
}),
|
||||
)
|
||||
|
@ -2283,7 +2277,13 @@ fn composite_type_metadata(
|
|||
DIFlags::FlagZero,
|
||||
);
|
||||
// ... and immediately create and add the member descriptions.
|
||||
set_members_of_composite_type(cx, composite_type, composite_type_metadata, member_descriptions);
|
||||
set_members_of_composite_type(
|
||||
cx,
|
||||
composite_type,
|
||||
composite_type_metadata,
|
||||
member_descriptions,
|
||||
None,
|
||||
);
|
||||
|
||||
composite_type_metadata
|
||||
}
|
||||
|
@ -2293,6 +2293,7 @@ fn set_members_of_composite_type(
|
|||
composite_type: Ty<'tcx>,
|
||||
composite_type_metadata: &'ll DICompositeType,
|
||||
member_descriptions: Vec<MemberDescription<'ll>>,
|
||||
common_members: Option<&Vec<Option<&'ll DIType>>>,
|
||||
) {
|
||||
// In some rare cases LLVM metadata uniquing would lead to an existing type
|
||||
// description being used instead of a new one created in
|
||||
|
@ -2311,10 +2312,13 @@ fn set_members_of_composite_type(
|
|||
}
|
||||
}
|
||||
|
||||
let member_metadata: Vec<_> = member_descriptions
|
||||
let mut member_metadata: Vec<_> = member_descriptions
|
||||
.into_iter()
|
||||
.map(|desc| Some(desc.into_metadata(cx, composite_type_metadata)))
|
||||
.collect();
|
||||
if let Some(other_members) = common_members {
|
||||
member_metadata.extend(other_members.iter());
|
||||
}
|
||||
|
||||
let type_params = compute_type_parameters(cx, composite_type);
|
||||
unsafe {
|
||||
|
|
|
@ -683,6 +683,15 @@ impl BorrowKind {
|
|||
BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn describe_mutability(&self) -> String {
|
||||
match *self {
|
||||
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => {
|
||||
"immutable".to_string()
|
||||
}
|
||||
BorrowKind::Mut { .. } => "mutable".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1340,7 +1349,7 @@ impl<O> AssertKind<O> {
|
|||
}
|
||||
|
||||
/// Format the message arguments for the `assert(cond, msg..)` terminator in MIR printing.
|
||||
fn fmt_assert_args<W: Write>(&self, f: &mut W) -> fmt::Result
|
||||
pub fn fmt_assert_args<W: Write>(&self, f: &mut W) -> fmt::Result
|
||||
where
|
||||
O: Debug,
|
||||
{
|
||||
|
@ -2369,6 +2378,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
};
|
||||
let mut struct_fmt = fmt.debug_struct(&name);
|
||||
|
||||
// FIXME(project-rfc-2229#48): This should be a list of capture names/places
|
||||
if let Some(upvars) = tcx.upvars_mentioned(def_id) {
|
||||
for (&var_id, place) in iter::zip(upvars.keys(), places) {
|
||||
let var_name = tcx.hir().name(var_id);
|
||||
|
@ -2388,6 +2398,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
let name = format!("[generator@{:?}]", tcx.hir().span(hir_id));
|
||||
let mut struct_fmt = fmt.debug_struct(&name);
|
||||
|
||||
// FIXME(project-rfc-2229#48): This should be a list of capture names/places
|
||||
if let Some(upvars) = tcx.upvars_mentioned(def_id) {
|
||||
for (&var_id, place) in iter::zip(upvars.keys(), places) {
|
||||
let var_name = tcx.hir().name(var_id);
|
||||
|
|
|
@ -151,6 +151,10 @@ pub struct CapturedPlace<'tcx> {
|
|||
}
|
||||
|
||||
impl CapturedPlace<'tcx> {
|
||||
pub fn to_string(&self, tcx: TyCtxt<'tcx>) -> String {
|
||||
place_to_string_for_capture(tcx, &self.place)
|
||||
}
|
||||
|
||||
/// Returns the hir-id of the root variable for the captured place.
|
||||
/// e.g., if `a.b.c` was captured, would return the hir-id for `a`.
|
||||
pub fn get_root_variable(&self) -> hir::HirId {
|
||||
|
@ -168,6 +172,22 @@ impl CapturedPlace<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return span pointing to use that resulted in selecting the captured path
|
||||
pub fn get_path_span(&self, tcx: TyCtxt<'tcx>) -> Span {
|
||||
if let Some(path_expr_id) = self.info.path_expr_id {
|
||||
tcx.hir().span(path_expr_id)
|
||||
} else if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
|
||||
tcx.hir().span(capture_kind_expr_id)
|
||||
} else {
|
||||
// Fallback on upvars mentioned if neither path or capture expr id is captured
|
||||
|
||||
// Safe to unwrap since we know this place is captured by the closure, therefore the closure must have upvars.
|
||||
tcx.upvars_mentioned(self.get_closure_local_def_id()).unwrap()
|
||||
[&self.get_root_variable()]
|
||||
.span
|
||||
}
|
||||
}
|
||||
|
||||
/// Return span pointing to use that resulted in selecting the current capture kind
|
||||
pub fn get_capture_kind_span(&self, tcx: TyCtxt<'tcx>) -> Span {
|
||||
if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
|
||||
|
|
|
@ -99,7 +99,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
);
|
||||
err.span_label(span, format!("use of possibly-uninitialized {}", item_msg));
|
||||
|
||||
use_spans.var_span_label(
|
||||
use_spans.var_span_label_path_only(
|
||||
&mut err,
|
||||
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
|
||||
);
|
||||
|
@ -255,6 +255,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
partially_str,
|
||||
move_spans.describe()
|
||||
),
|
||||
"moved",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +305,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
use_spans.var_span_label(
|
||||
use_spans.var_span_label_path_only(
|
||||
&mut err,
|
||||
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
|
||||
);
|
||||
|
@ -434,13 +435,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg));
|
||||
err.span_label(span, format!("move out of {} occurs here", value_msg));
|
||||
|
||||
borrow_spans.var_span_label(
|
||||
borrow_spans.var_span_label_path_only(
|
||||
&mut err,
|
||||
format!("borrow occurs due to use{}", borrow_spans.describe()),
|
||||
);
|
||||
|
||||
move_spans
|
||||
.var_span_label(&mut err, format!("move occurs due to use{}", move_spans.describe()));
|
||||
move_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("move occurs due to use{}", move_spans.describe()),
|
||||
"moved",
|
||||
);
|
||||
|
||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||
.add_explanation_to_diagnostic(
|
||||
|
@ -468,6 +472,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let use_spans = self.move_spans(place.as_ref(), location);
|
||||
let span = use_spans.var_or_use();
|
||||
|
||||
// If the attempted use is in a closure then we do not care about the path span of the place we are currently trying to use
|
||||
// we call `var_span_label` on `borrow_spans` to annotate if the existing borrow was in a closure
|
||||
let mut err = self.cannot_use_when_mutably_borrowed(
|
||||
span,
|
||||
&self.describe_any_place(place.as_ref()),
|
||||
|
@ -475,11 +481,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&self.describe_any_place(borrow.borrowed_place.as_ref()),
|
||||
);
|
||||
|
||||
borrow_spans.var_span_label(&mut err, {
|
||||
let place = &borrow.borrowed_place;
|
||||
let desc_place = self.describe_any_place(place.as_ref());
|
||||
format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe())
|
||||
});
|
||||
borrow_spans.var_span_label(
|
||||
&mut err,
|
||||
{
|
||||
let place = &borrow.borrowed_place;
|
||||
let desc_place = self.describe_any_place(place.as_ref());
|
||||
format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe())
|
||||
},
|
||||
"mutable",
|
||||
);
|
||||
|
||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||
.add_explanation_to_diagnostic(
|
||||
|
@ -591,6 +601,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
desc_place,
|
||||
borrow_spans.describe(),
|
||||
),
|
||||
"immutable",
|
||||
);
|
||||
|
||||
return err;
|
||||
|
@ -667,7 +678,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if issued_spans == borrow_spans {
|
||||
borrow_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe()),
|
||||
format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe(),),
|
||||
gen_borrow_kind.describe_mutability(),
|
||||
);
|
||||
} else {
|
||||
let borrow_place = &issued_borrow.borrowed_place;
|
||||
|
@ -679,6 +691,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
borrow_place_desc,
|
||||
issued_spans.describe(),
|
||||
),
|
||||
issued_borrow.kind.describe_mutability(),
|
||||
);
|
||||
|
||||
borrow_spans.var_span_label(
|
||||
|
@ -688,6 +701,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
desc_place,
|
||||
borrow_spans.describe(),
|
||||
),
|
||||
gen_borrow_kind.describe_mutability(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -847,7 +861,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
|
||||
|
||||
let borrow_spans = self.retrieve_borrow_spans(borrow);
|
||||
let borrow_span = borrow_spans.var_or_use();
|
||||
let borrow_span = borrow_spans.var_or_use_path_span();
|
||||
|
||||
assert!(root_place.projection.is_empty());
|
||||
let proper_span = self.body.local_decls[root_place.local].source_info.span;
|
||||
|
@ -987,7 +1001,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
location, name, borrow, drop_span, borrow_spans
|
||||
);
|
||||
|
||||
let borrow_span = borrow_spans.var_or_use();
|
||||
let borrow_span = borrow_spans.var_or_use_path_span();
|
||||
if let BorrowExplanation::MustBeValidFor {
|
||||
category,
|
||||
span,
|
||||
|
@ -1575,6 +1589,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
loan_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("borrow occurs due to use{}", loan_spans.describe()),
|
||||
loan.kind.describe_mutability(),
|
||||
);
|
||||
|
||||
err.buffer(&mut self.errors_buffer);
|
||||
|
@ -1585,8 +1600,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
|
||||
let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place);
|
||||
|
||||
loan_spans
|
||||
.var_span_label(&mut err, format!("borrow occurs due to use{}", loan_spans.describe()));
|
||||
loan_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("borrow occurs due to use{}", loan_spans.describe()),
|
||||
loan.kind.describe_mutability(),
|
||||
);
|
||||
|
||||
self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic(
|
||||
self.infcx.tcx,
|
||||
|
|
|
@ -24,8 +24,8 @@ use super::{find_use, RegionName, UseSpans};
|
|||
|
||||
#[derive(Debug)]
|
||||
pub(in crate::borrow_check) enum BorrowExplanation {
|
||||
UsedLater(LaterUseKind, Span),
|
||||
UsedLaterInLoop(LaterUseKind, Span),
|
||||
UsedLater(LaterUseKind, Span, Option<Span>),
|
||||
UsedLaterInLoop(LaterUseKind, Span, Option<Span>),
|
||||
UsedLaterWhenDropped {
|
||||
drop_loc: Location,
|
||||
dropped_local: Local,
|
||||
|
@ -67,7 +67,7 @@ impl BorrowExplanation {
|
|||
borrow_span: Option<Span>,
|
||||
) {
|
||||
match *self {
|
||||
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
|
||||
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
|
||||
let message = match later_use_kind {
|
||||
LaterUseKind::TraitCapture => "captured here by trait object",
|
||||
LaterUseKind::ClosureCapture => "captured here by closure",
|
||||
|
@ -75,14 +75,31 @@ impl BorrowExplanation {
|
|||
LaterUseKind::FakeLetRead => "stored here",
|
||||
LaterUseKind::Other => "used here",
|
||||
};
|
||||
if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) {
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, message),
|
||||
);
|
||||
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
|
||||
if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
|
||||
if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, message),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// path_span must be `Some` as otherwise the if condition is true
|
||||
let path_span = path_span.unwrap();
|
||||
// path_span is only present in the case of closure capture
|
||||
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
|
||||
if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) {
|
||||
let path_label = "used here by closure";
|
||||
let capture_kind_label = message;
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, capture_kind_label),
|
||||
);
|
||||
err.span_label(path_span, path_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
|
||||
BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span) => {
|
||||
let message = match later_use_kind {
|
||||
LaterUseKind::TraitCapture => {
|
||||
"borrow captured here by trait object, in later iteration of loop"
|
||||
|
@ -94,7 +111,24 @@ impl BorrowExplanation {
|
|||
LaterUseKind::FakeLetRead => "borrow later stored here",
|
||||
LaterUseKind::Other => "borrow used here, in later iteration of loop",
|
||||
};
|
||||
err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
|
||||
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
|
||||
if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
|
||||
err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
|
||||
} else {
|
||||
// path_span must be `Some` as otherwise the if condition is true
|
||||
let path_span = path_span.unwrap();
|
||||
// path_span is only present in the case of closure capture
|
||||
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
|
||||
if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
|
||||
let path_label = "used here by closure";
|
||||
let capture_kind_label = message;
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{}borrow later {}", borrow_desc, capture_kind_label),
|
||||
);
|
||||
err.span_label(path_span, path_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
BorrowExplanation::UsedLaterWhenDropped {
|
||||
drop_loc,
|
||||
|
@ -311,13 +345,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let borrow_location = location;
|
||||
if self.is_use_in_later_iteration_of_loop(borrow_location, location) {
|
||||
let later_use = self.later_use_kind(borrow, spans, location);
|
||||
BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1)
|
||||
BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1, later_use.2)
|
||||
} else {
|
||||
// Check if the location represents a `FakeRead`, and adapt the error
|
||||
// message to the `FakeReadCause` it is from: in particular,
|
||||
// the ones inserted in optimized `let var = <expr>` patterns.
|
||||
let later_use = self.later_use_kind(borrow, spans, location);
|
||||
BorrowExplanation::UsedLater(later_use.0, later_use.1)
|
||||
BorrowExplanation::UsedLater(later_use.0, later_use.1, later_use.2)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -498,16 +532,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
/// Determine how the borrow was later used.
|
||||
/// First span returned points to the location of the conflicting use
|
||||
/// Second span if `Some` is returned in the case of closures and points
|
||||
/// to the use of the path
|
||||
fn later_use_kind(
|
||||
&self,
|
||||
borrow: &BorrowData<'tcx>,
|
||||
use_spans: UseSpans<'tcx>,
|
||||
location: Location,
|
||||
) -> (LaterUseKind, Span) {
|
||||
) -> (LaterUseKind, Span, Option<Span>) {
|
||||
match use_spans {
|
||||
UseSpans::ClosureUse { var_span, .. } => {
|
||||
UseSpans::ClosureUse { capture_kind_span, path_span, .. } => {
|
||||
// Used in a closure.
|
||||
(LaterUseKind::ClosureCapture, var_span)
|
||||
(LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span))
|
||||
}
|
||||
UseSpans::PatUse(span)
|
||||
| UseSpans::OtherUse(span)
|
||||
|
@ -542,7 +579,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
};
|
||||
return (LaterUseKind::Call, function_span);
|
||||
return (LaterUseKind::Call, function_span, None);
|
||||
} else {
|
||||
LaterUseKind::Other
|
||||
}
|
||||
|
@ -550,7 +587,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
LaterUseKind::Other
|
||||
};
|
||||
|
||||
(kind, span)
|
||||
(kind, span, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ use rustc_span::{
|
|||
Span,
|
||||
};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use std::iter;
|
||||
|
||||
use super::borrow_set::BorrowData;
|
||||
use super::MirBorrowckCtxt;
|
||||
|
@ -216,11 +215,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
PlaceRef { local, projection: [proj_base @ .., elem] } => {
|
||||
match elem {
|
||||
ProjectionElem::Deref => {
|
||||
// FIXME(project-rfc_2229#36): print capture precisely here.
|
||||
let upvar_field_projection = self.is_upvar_field_projection(place);
|
||||
if let Some(field) = upvar_field_projection {
|
||||
let var_index = field.index();
|
||||
let name = self.upvars[var_index].name.to_string();
|
||||
let name = self.upvars[var_index].place.to_string(self.infcx.tcx);
|
||||
if self.upvars[var_index].by_ref {
|
||||
buf.push_str(&name);
|
||||
} else {
|
||||
|
@ -265,7 +263,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let upvar_field_projection = self.is_upvar_field_projection(place);
|
||||
if let Some(field) = upvar_field_projection {
|
||||
let var_index = field.index();
|
||||
let name = self.upvars[var_index].name.to_string();
|
||||
let name = self.upvars[var_index].place.to_string(self.infcx.tcx);
|
||||
buf.push_str(&name);
|
||||
} else {
|
||||
let field_name = self
|
||||
|
@ -550,8 +548,12 @@ pub(super) enum UseSpans<'tcx> {
|
|||
/// The span of the args of the closure, including the `move` keyword if
|
||||
/// it's present.
|
||||
args_span: Span,
|
||||
/// The span of the first use of the captured variable inside the closure.
|
||||
var_span: Span,
|
||||
/// The span of the use resulting in capture kind
|
||||
/// Check `ty::CaptureInfo` for more details
|
||||
capture_kind_span: Span,
|
||||
/// The span of the use resulting in the captured path
|
||||
/// Check `ty::CaptureInfo` for more details
|
||||
path_span: Span,
|
||||
},
|
||||
/// The access is caused by using a variable as the receiver of a method
|
||||
/// that takes 'self'
|
||||
|
@ -606,9 +608,23 @@ impl UseSpans<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the span of `self`, in the case of a `ClosureUse` returns the `path_span`
|
||||
pub(super) fn var_or_use_path_span(self) -> Span {
|
||||
match self {
|
||||
UseSpans::ClosureUse { path_span: span, .. }
|
||||
| UseSpans::PatUse(span)
|
||||
| UseSpans::OtherUse(span) => span,
|
||||
UseSpans::FnSelfUse {
|
||||
fn_call_span, kind: FnSelfUseKind::DerefCoercion { .. }, ..
|
||||
} => fn_call_span,
|
||||
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the span of `self`, in the case of a `ClosureUse` returns the `capture_kind_span`
|
||||
pub(super) fn var_or_use(self) -> Span {
|
||||
match self {
|
||||
UseSpans::ClosureUse { var_span: span, .. }
|
||||
UseSpans::ClosureUse { capture_kind_span: span, .. }
|
||||
| UseSpans::PatUse(span)
|
||||
| UseSpans::OtherUse(span) => span,
|
||||
UseSpans::FnSelfUse {
|
||||
|
@ -637,13 +653,34 @@ impl UseSpans<'_> {
|
|||
}
|
||||
|
||||
// Add a span label to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_span_label(
|
||||
// only adds label to the `path_span`
|
||||
pub(super) fn var_span_label_path_only(
|
||||
self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
message: impl Into<String>,
|
||||
) {
|
||||
if let UseSpans::ClosureUse { var_span, .. } = self {
|
||||
err.span_label(var_span, message);
|
||||
if let UseSpans::ClosureUse { path_span, .. } = self {
|
||||
err.span_label(path_span, message);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a span label to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_span_label(
|
||||
self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
message: impl Into<String>,
|
||||
kind_desc: impl Into<String>,
|
||||
) {
|
||||
if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self {
|
||||
if capture_kind_span == path_span {
|
||||
err.span_label(capture_kind_span, message);
|
||||
} else {
|
||||
let capture_kind_label =
|
||||
format!("capture is {} because of use here", kind_desc.into());
|
||||
let path_label = message;
|
||||
err.span_label(capture_kind_span, capture_kind_label);
|
||||
err.span_label(path_span, path_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -791,10 +828,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
box AggregateKind::Closure(def_id, _)
|
||||
| box AggregateKind::Generator(def_id, _, _) => {
|
||||
debug!("move_spans: def_id={:?} places={:?}", def_id, places);
|
||||
if let Some((args_span, generator_kind, var_span)) =
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(*def_id, moved_place, places)
|
||||
{
|
||||
return ClosureUse { generator_kind, args_span, var_span };
|
||||
return ClosureUse {
|
||||
generator_kind,
|
||||
args_span,
|
||||
capture_kind_span,
|
||||
path_span,
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -809,10 +851,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
| FakeReadCause::ForLet(Some(closure_def_id)) => {
|
||||
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
|
||||
let places = &[Operand::Move(*place)];
|
||||
if let Some((args_span, generator_kind, var_span)) =
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(closure_def_id, moved_place, places)
|
||||
{
|
||||
return ClosureUse { generator_kind, args_span, var_span };
|
||||
return ClosureUse {
|
||||
generator_kind,
|
||||
args_span,
|
||||
capture_kind_span,
|
||||
path_span,
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -972,10 +1019,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
"borrow_spans: def_id={:?} is_generator={:?} places={:?}",
|
||||
def_id, is_generator, places
|
||||
);
|
||||
if let Some((args_span, generator_kind, var_span)) =
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(*def_id, Place::from(target).as_ref(), places)
|
||||
{
|
||||
return ClosureUse { generator_kind, args_span, var_span };
|
||||
return ClosureUse { generator_kind, args_span, capture_kind_span, path_span };
|
||||
} else {
|
||||
return OtherUse(use_span);
|
||||
}
|
||||
|
@ -989,13 +1036,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
OtherUse(use_span)
|
||||
}
|
||||
|
||||
/// Finds the span of a captured variable within a closure or generator.
|
||||
/// Finds the spans of a captured place within a closure or generator.
|
||||
/// The first span is the location of the use resulting in the capture kind of the capture
|
||||
/// The second span is the location the use resulting in the captured path of the capture
|
||||
fn closure_span(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
target_place: PlaceRef<'tcx>,
|
||||
places: &[Operand<'tcx>],
|
||||
) -> Option<(Span, Option<GeneratorKind>, Span)> {
|
||||
) -> Option<(Span, Option<GeneratorKind>, Span, Span)> {
|
||||
debug!(
|
||||
"closure_span: def_id={:?} target_place={:?} places={:?}",
|
||||
def_id, target_place, places
|
||||
|
@ -1005,13 +1054,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind;
|
||||
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
|
||||
if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr {
|
||||
for (captured_place, place) in iter::zip(
|
||||
self.infcx.tcx.typeck(def_id.expect_local()).closure_min_captures_flattened(def_id),
|
||||
places,
|
||||
) {
|
||||
let upvar_hir_id = captured_place.get_root_variable();
|
||||
//FIXME(project-rfc-2229#8): Use better span from captured_place
|
||||
let span = self.infcx.tcx.upvars_mentioned(local_did)?[&upvar_hir_id].span;
|
||||
for (captured_place, place) in self
|
||||
.infcx
|
||||
.tcx
|
||||
.typeck(def_id.expect_local())
|
||||
.closure_min_captures_flattened(def_id)
|
||||
.zip(places)
|
||||
{
|
||||
match place {
|
||||
Operand::Copy(place) | Operand::Move(place)
|
||||
if target_place == place.as_ref() =>
|
||||
|
@ -1020,18 +1069,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let body = self.infcx.tcx.hir().body(*body_id);
|
||||
let generator_kind = body.generator_kind();
|
||||
|
||||
// If we have a more specific span available, point to that.
|
||||
// We do this even though this span might be part of a borrow error
|
||||
// message rather than a move error message. Our goal is to point
|
||||
// to a span that shows why the upvar is used in the closure,
|
||||
// so a move-related span is as good as any (and potentially better,
|
||||
// if the overall error is due to a move of the upvar).
|
||||
|
||||
let usage_span = match captured_place.info.capture_kind {
|
||||
ty::UpvarCapture::ByValue(Some(span)) => span,
|
||||
_ => span,
|
||||
};
|
||||
return Some((*args_span, generator_kind, usage_span));
|
||||
return Some((
|
||||
*args_span,
|
||||
generator_kind,
|
||||
captured_place.get_capture_kind_span(self.infcx.tcx),
|
||||
captured_place.get_path_span(self.infcx.tcx),
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -345,10 +345,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let upvar = &self.upvars[upvar_field.unwrap().index()];
|
||||
// FIXME(project-rfc-2229#8): Improve borrow-check diagnostics in case of precise
|
||||
// capture.
|
||||
let upvar_hir_id = upvar.place.get_root_variable();
|
||||
let upvar_name = upvar.name;
|
||||
let upvar_name = upvar.place.to_string(self.infcx.tcx);
|
||||
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
|
||||
|
||||
let place_name = self.describe_any_place(move_place.as_ref());
|
||||
|
@ -478,8 +476,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
|
||||
|
||||
use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc));
|
||||
use_spans
|
||||
.var_span_label(err, format!("move occurs due to use{}", use_spans.describe()));
|
||||
use_spans.var_span_label(
|
||||
err,
|
||||
format!("move occurs due to use{}", use_spans.describe()),
|
||||
"moved",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
|
||||
reason = ", as it is not declared as mutable".to_string();
|
||||
} else {
|
||||
let name = self.upvars[upvar_index.index()].name;
|
||||
let name = self.upvars[upvar_index.index()].place.to_string(self.infcx.tcx);
|
||||
reason = format!(", as `{}` is not declared as mutable", name);
|
||||
}
|
||||
}
|
||||
|
@ -195,6 +195,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
"mutable borrow occurs due to use of {} in closure",
|
||||
self.describe_any_place(access_place.as_ref()),
|
||||
),
|
||||
"mutable",
|
||||
);
|
||||
borrow_span
|
||||
}
|
||||
|
|
|
@ -385,6 +385,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
|
||||
diag.span_label(*span, message);
|
||||
|
||||
// FIXME(project-rfc-2229#48): This should store a captured_place not a hir id
|
||||
if let ReturnConstraint::ClosureUpvar(upvar) = kind {
|
||||
let def_id = match self.regioncx.universal_regions().defining_ty {
|
||||
DefiningTy::Closure(def_id, _) => def_id,
|
||||
|
|
|
@ -74,9 +74,6 @@ crate use region_infer::RegionInferenceContext;
|
|||
// FIXME(eddyb) perhaps move this somewhere more centrally.
|
||||
#[derive(Debug)]
|
||||
crate struct Upvar<'tcx> {
|
||||
// FIXME(project-rfc_2229#36): print capture precisely here.
|
||||
name: Symbol,
|
||||
|
||||
place: CapturedPlace<'tcx>,
|
||||
|
||||
/// If true, the capture is behind a reference.
|
||||
|
@ -159,13 +156,12 @@ fn do_mir_borrowck<'a, 'tcx>(
|
|||
let upvars: Vec<_> = tables
|
||||
.closure_min_captures_flattened(def.did.to_def_id())
|
||||
.map(|captured_place| {
|
||||
let var_hir_id = captured_place.get_root_variable();
|
||||
let capture = captured_place.info.capture_kind;
|
||||
let by_ref = match capture {
|
||||
ty::UpvarCapture::ByValue(_) => false,
|
||||
ty::UpvarCapture::ByRef(..) => true,
|
||||
};
|
||||
Upvar { name: tcx.hir().name(var_hir_id), place: captured_place.clone(), by_ref }
|
||||
Upvar { place: captured_place.clone(), by_ref }
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ macro_rules! options {
|
|||
|
||||
pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool;
|
||||
pub const $stat: &[(&str, $setter_name, &str, &str)] =
|
||||
&[ $( (stringify!($opt), crate::options::parse::$opt, $crate::options::desc::$parse, $desc) ),* ];
|
||||
&[ $( (stringify!($opt), $crate::options::parse::$opt, $crate::options::desc::$parse, $desc) ),* ];
|
||||
|
||||
// Sometimes different options need to build a common structure.
|
||||
// That structure can kept in one of the options' fields, the others become dummy.
|
||||
|
|
|
@ -763,7 +763,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
PlaceBase::Local(*var_hir_id)
|
||||
};
|
||||
let place_with_id = PlaceWithHirId::new(
|
||||
capture_info.path_expr_id.unwrap_or(closure_expr.hir_id),
|
||||
capture_info.path_expr_id.unwrap_or(
|
||||
capture_info.capture_kind_expr_id.unwrap_or(closure_expr.hir_id),
|
||||
),
|
||||
place.base_ty,
|
||||
place_base,
|
||||
place.projections.clone(),
|
||||
|
|
|
@ -100,12 +100,13 @@ impl Clean<Item> for doctree::Module<'_> {
|
|||
// determine if we should display the inner contents or
|
||||
// the outer `mod` item for the source code.
|
||||
let span = Span::from_rustc_span({
|
||||
let where_outer = self.where_outer(cx.tcx);
|
||||
let sm = cx.sess().source_map();
|
||||
let outer = sm.lookup_char_pos(self.where_outer.lo());
|
||||
let outer = sm.lookup_char_pos(where_outer.lo());
|
||||
let inner = sm.lookup_char_pos(self.where_inner.lo());
|
||||
if outer.file.start_pos == inner.file.start_pos {
|
||||
// mod foo { ... }
|
||||
self.where_outer
|
||||
where_outer
|
||||
} else {
|
||||
// mod foo; (and a separate SourceFile for the contents)
|
||||
self.where_inner
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
//! This module is used to store stuff from Rust's AST in a more convenient
|
||||
//! manner (and with prettier names) before cleaning.
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{self, Span, Symbol};
|
||||
|
||||
use rustc_hir as hir;
|
||||
|
||||
crate struct Module<'hir> {
|
||||
crate name: Symbol,
|
||||
crate where_outer: Span,
|
||||
crate where_inner: Span,
|
||||
crate mods: Vec<Module<'hir>>,
|
||||
crate id: hir::HirId,
|
||||
|
@ -17,16 +17,19 @@ crate struct Module<'hir> {
|
|||
}
|
||||
|
||||
impl Module<'hir> {
|
||||
crate fn new(name: Symbol) -> Module<'hir> {
|
||||
crate fn new(name: Symbol, id: hir::HirId, where_inner: Span) -> Module<'hir> {
|
||||
Module {
|
||||
name,
|
||||
id: hir::CRATE_HIR_ID,
|
||||
where_outer: rustc_span::DUMMY_SP,
|
||||
where_inner: rustc_span::DUMMY_SP,
|
||||
id,
|
||||
where_inner,
|
||||
mods: Vec::new(),
|
||||
items: Vec::new(),
|
||||
foreigns: Vec::new(),
|
||||
macros: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn where_outer(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.hir().span(self.id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::Node;
|
||||
use rustc_middle::middle::privacy::AccessLevel;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{self, Span};
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
@ -73,7 +73,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
|
||||
let span = krate.item.inner;
|
||||
let mut top_level_module = self.visit_mod_contents(
|
||||
span,
|
||||
&Spanned { span, node: hir::VisibilityKind::Public },
|
||||
hir::CRATE_HIR_ID,
|
||||
&krate.item,
|
||||
|
@ -129,16 +128,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_mod_contents(
|
||||
&mut self,
|
||||
span: Span,
|
||||
vis: &hir::Visibility<'_>,
|
||||
id: hir::HirId,
|
||||
m: &'tcx hir::Mod<'tcx>,
|
||||
name: Symbol,
|
||||
) -> Module<'tcx> {
|
||||
let mut om = Module::new(name);
|
||||
om.where_outer = span;
|
||||
om.where_inner = m.inner;
|
||||
om.id = id;
|
||||
let mut om = Module::new(name, id, m.inner);
|
||||
// Keep track of if there were any private modules in the path.
|
||||
let orig_inside_public_path = self.inside_public_path;
|
||||
self.inside_public_path &= vis.node.is_pub();
|
||||
|
@ -312,7 +307,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
om.items.push((item, renamed))
|
||||
}
|
||||
hir::ItemKind::Mod(ref m) => {
|
||||
om.mods.push(self.visit_mod_contents(item.span, &item.vis, item.hir_id(), m, name));
|
||||
om.mods.push(self.visit_mod_contents(&item.vis, item.hir_id(), m, name));
|
||||
}
|
||||
hir::ItemKind::Fn(..)
|
||||
| hir::ItemKind::ExternCrate(..)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Verify debuginfo for generators:
|
||||
// - Each variant points to the file and line of its yield point
|
||||
// - The generator types and variants are marked artificial
|
||||
// - Captured vars from the source are not marked artificial
|
||||
// - The discriminants are marked artificial
|
||||
// - Other fields are not marked artificial
|
||||
//
|
||||
//
|
||||
// compile-flags: -C debuginfo=2 --edition=2018
|
||||
|
@ -17,26 +17,32 @@ async fn async_fn_test() {
|
|||
// FIXME: No way to reliably check the filename.
|
||||
|
||||
// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[ASYNC_FN]], {{.*}}flags: DIFlagArtificial
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[ASYNC_FN]]
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// For brevity, we only check the struct name and members of the last variant.
|
||||
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 15,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 15,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 12,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 14,
|
||||
// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[ASYNC_FN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENUM$DISR", scope: [[S1]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Verify debuginfo for async fn:
|
||||
// - Each variant points to the file and line of its yield point
|
||||
// - The generator types and variants are marked artificial
|
||||
// - Captured vars from the source are not marked artificial
|
||||
// - The discriminants are marked artificial
|
||||
// - Other fields are not marked artificial
|
||||
//
|
||||
//
|
||||
// compile-flags: -C debuginfo=2 --edition=2018
|
||||
|
@ -17,29 +17,36 @@ async fn async_fn_test() {
|
|||
// FIXME: No way to reliably check the filename.
|
||||
|
||||
// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]], {{.*}}flags: DIFlagArtificial
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]]
|
||||
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[ASYNC_FN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 15,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 15,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 12,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 14,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Verify debuginfo for generators:
|
||||
// - Each variant points to the file and line of its yield point
|
||||
// - The generator types and variants are marked artificial
|
||||
// - Captured vars from the source are not marked artificial
|
||||
// - The discriminants are marked artificial
|
||||
// - Other fields are not marked artificial
|
||||
//
|
||||
//
|
||||
// compile-flags: -C debuginfo=2
|
||||
|
@ -21,26 +21,32 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
|
|||
// FIXME: No way to reliably check the filename.
|
||||
|
||||
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[GEN_FN]], {{.*}}flags: DIFlagArtificial
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0", scope: [[GEN_FN]]
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// For brevity, we only check the struct name and members of the last variant.
|
||||
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 18,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 18,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 15,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, scope: [[GEN]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 17,
|
||||
// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN_FN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENUM$DISR", scope: [[S1]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Verify debuginfo for generators:
|
||||
// - Each variant points to the file and line of its yield point
|
||||
// - The generator types and variants are marked artificial
|
||||
// - Captured vars from the source are not marked artificial
|
||||
// - The discriminants are marked artificial
|
||||
// - Other fields are not marked artificial
|
||||
//
|
||||
//
|
||||
// compile-flags: -C debuginfo=2 --edition=2018
|
||||
|
@ -21,29 +21,36 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
|
|||
// FIXME: No way to reliably check the filename.
|
||||
|
||||
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]], {{.*}}flags: DIFlagArtificial
|
||||
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]]
|
||||
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN_FN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 18,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 18,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 15,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
|
||||
// CHECK-SAME: file: [[FILE]], line: 17,
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
|
||||
// CHECK-SAME: flags: DIFlagArtificial
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]]
|
||||
// CHECK-NOT: flags: DIFlagArtificial
|
||||
// CHECK-SAME: )
|
||||
|
|
|
@ -1,37 +1,41 @@
|
|||
// Require a gdb that can read DW_TAG_variant_part.
|
||||
// min-gdb-version: 8.2
|
||||
|
||||
// LLDB without native Rust support cannot read DW_TAG_variant_part,
|
||||
// so it prints nothing for generators. But those tests are kept to
|
||||
// ensure that LLDB won't crash at least (like #57822).
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
// === GDB TESTS ===================================================================================
|
||||
|
||||
// gdb-command:run
|
||||
// gdb-command:print b
|
||||
// gdb-check:$1 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
|
||||
// gdb-check:$1 = generator_objects::main::generator-0::Unresumed(0x[...])
|
||||
// gdb-command:continue
|
||||
// gdb-command:print b
|
||||
// gdb-check:$2 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 3, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
|
||||
// gdb-check:$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7, __0: 0x[...]}
|
||||
// gdb-command:continue
|
||||
// gdb-command:print b
|
||||
// gdb-check:$3 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 4, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {c: 7, d: 8}}}
|
||||
// gdb-check:$3 = generator_objects::main::generator-0::Suspend1{c: 7, d: 8, __0: 0x[...]}
|
||||
// gdb-command:continue
|
||||
// gdb-command:print b
|
||||
// gdb-check:$4 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 1, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
|
||||
// gdb-check:$4 = generator_objects::main::generator-0::Returned(0x[...])
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
|
||||
// lldb-command:run
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $0 = { 0 = 0x[...] }
|
||||
// lldbg-check:(generator_objects::main::generator-0) $0 =
|
||||
// lldb-command:continue
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $1 = { 0 = 0x[...] }
|
||||
// lldbg-check:(generator_objects::main::generator-0) $1 =
|
||||
// lldb-command:continue
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $2 = { 0 = 0x[...] }
|
||||
// lldbg-check:(generator_objects::main::generator-0) $2 =
|
||||
// lldb-command:continue
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $3 = { 0 = 0x[...] }
|
||||
// lldbg-check:(generator_objects::main::generator-0) $3 =
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
|
||||
#![omit_gdb_pretty_printer_section]
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
|
||||
|
||||
// gdb-command:print b
|
||||
// gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <<variant>>: {[...]}}, <<variant>>: {[...]}}
|
||||
// gdb-check:$2 = issue_57822::main::generator-3::Unresumed(issue_57822::main::generator-2::Unresumed(2))
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
|||
// lldbg-check:(issue_57822::main::closure-1) $0 = { 0 = { 0 = 1 } }
|
||||
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(issue_57822::main::generator-3) $1 = { 0 = { 0 = 2 } }
|
||||
// lldbg-check:(issue_57822::main::generator-3) $1 =
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
|
||||
#![omit_gdb_pretty_printer_section]
|
||||
|
|
|
@ -21,9 +21,9 @@ error[E0373]: async block may outlive the current function, but it borrows `x`,
|
|||
--> $DIR/async-borrowck-escaping-block-error.rs:11:11
|
||||
|
|
||||
LL | async { *x }
|
||||
| ^^^-^^
|
||||
| | |
|
||||
| | `x` is borrowed here
|
||||
| ^^--^^
|
||||
| | |
|
||||
| | `x` is borrowed here
|
||||
| may outlive borrowed value `x`
|
||||
|
|
||||
note: async block is returned here
|
||||
|
|
|
@ -73,7 +73,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
|
|||
--> $DIR/borrowck-closures-mut-and-imm.rs:57:5
|
||||
|
|
||||
LL | let c1 = || get(&*x);
|
||||
| -- - borrow occurs due to use in closure
|
||||
| -- -- borrow occurs due to use in closure
|
||||
| |
|
||||
| borrow of `*x` occurs here
|
||||
LL | *x = 5;
|
||||
|
@ -86,7 +86,7 @@ error[E0506]: cannot assign to `*x.f` because it is borrowed
|
|||
--> $DIR/borrowck-closures-mut-and-imm.rs:69:5
|
||||
|
|
||||
LL | let c1 = || get(&*x.f);
|
||||
| -- - borrow occurs due to use in closure
|
||||
| -- ---- borrow occurs due to use in closure
|
||||
| |
|
||||
| borrow of `*x.f` occurs here
|
||||
LL | *x.f = 5;
|
||||
|
@ -99,11 +99,11 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
|
|||
--> $DIR/borrowck-closures-mut-and-imm.rs:81:14
|
||||
|
|
||||
LL | let c1 = || get(&*x.f);
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- ---- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| immutable borrow occurs here
|
||||
LL | let c2 = || *x.f = 5;
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ ---- second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| mutable borrow occurs here
|
||||
LL |
|
||||
|
|
|
@ -14,12 +14,12 @@ error[E0524]: two closures require unique access to `x` at the same time
|
|||
--> $DIR/borrowck-closures-mut-of-imm.rs:11:18
|
||||
|
|
||||
LL | let mut c1 = || set(&mut *x);
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- -- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| first closure is constructed here
|
||||
LL |
|
||||
LL | let mut c2 = || set(&mut *x);
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ -- second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| second closure is constructed here
|
||||
...
|
||||
|
|
|
@ -2,11 +2,11 @@ error[E0524]: two closures require unique access to `x` at the same time
|
|||
--> $DIR/borrowck-closures-mut-of-mut.rs:14:18
|
||||
|
|
||||
LL | let mut c1 = || set(&mut *x);
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- -- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| first closure is constructed here
|
||||
LL | let mut c2 = || set(&mut *x);
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ -- second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| second closure is constructed here
|
||||
LL |
|
||||
|
|
|
@ -45,7 +45,7 @@ error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immut
|
|||
LL | let f = || {
|
||||
| -- immutable borrow occurs here
|
||||
LL | let [ref y, ref z @ ..] = *x;
|
||||
| - first borrow occurs due to use of `x` in closure
|
||||
| -- first borrow occurs due to use of `x` in closure
|
||||
LL | };
|
||||
LL | let r = &mut *x;
|
||||
| ^^^^^^^ mutable borrow occurs here
|
||||
|
@ -59,7 +59,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
|
|||
LL | let mut f = || {
|
||||
| -- closure construction occurs here
|
||||
LL | let [ref mut y, ref mut z @ ..] = *x;
|
||||
| - first borrow occurs due to use of `x` in closure
|
||||
| -- first borrow occurs due to use of `x` in closure
|
||||
LL | };
|
||||
LL | let r = &x;
|
||||
| ^^ second borrow occurs here
|
||||
|
@ -86,7 +86,7 @@ error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immut
|
|||
LL | let f = || {
|
||||
| -- immutable borrow occurs here
|
||||
LL | if let [ref y, ref z @ ..] = *x {}
|
||||
| - first borrow occurs due to use of `x` in closure
|
||||
| -- first borrow occurs due to use of `x` in closure
|
||||
LL | };
|
||||
LL | let r = &mut *x;
|
||||
| ^^^^^^^ mutable borrow occurs here
|
||||
|
@ -100,7 +100,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
|
|||
LL | let mut f = || {
|
||||
| -- closure construction occurs here
|
||||
LL | if let [ref mut y, ref mut z @ ..] = *x {}
|
||||
| - first borrow occurs due to use of `x` in closure
|
||||
| -- first borrow occurs due to use of `x` in closure
|
||||
LL | };
|
||||
LL | let r = &x;
|
||||
| ^^ second borrow occurs here
|
||||
|
|
|
@ -59,11 +59,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
|
|||
--> $DIR/borrowck-closures-two-mut-fail.rs:53:24
|
||||
|
|
||||
LL | let c1 = to_fn_mut(|| set(&mut *x.f));
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- ---- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| first mutable borrow occurs here
|
||||
LL | let c2 = to_fn_mut(|| set(&mut *x.f));
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ ---- second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| second mutable borrow occurs here
|
||||
LL |
|
||||
|
|
|
@ -59,11 +59,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
|
|||
--> $DIR/borrowck-closures-two-mut.rs:49:24
|
||||
|
|
||||
LL | let c1 = to_fn_mut(|| set(&mut *x.f));
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- ---- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| first mutable borrow occurs here
|
||||
LL | let c2 = to_fn_mut(|| set(&mut *x.f));
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ ---- second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| second mutable borrow occurs here
|
||||
LL |
|
||||
|
|
|
@ -20,7 +20,7 @@ LL | let c1 = || get(x);
|
|||
| |
|
||||
| borrow occurs here
|
||||
LL | let c2 = || { get(x); set(x); };
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| closure construction occurs here
|
||||
LL | c1;
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0502]: cannot borrow `*ptr` as immutable because it is also borrowed as m
|
|||
LL | let mut test = |foo: &Foo| {
|
||||
| ----------- mutable borrow occurs here
|
||||
LL | ptr = box Foo { x: ptr.x + 1 };
|
||||
| --- first borrow occurs due to use of `ptr` in closure
|
||||
| --- first borrow occurs due to use of `ptr` in closure
|
||||
LL | };
|
||||
LL | test(&*ptr);
|
||||
| ---- ^^^^^ immutable borrow occurs here
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | |
|
|||
LL | | |a| {
|
||||
| | --- closure construction occurs here
|
||||
LL | | f.n.insert(*a);
|
||||
| | - first borrow occurs due to use of `f` in closure
|
||||
| | --- first borrow occurs due to use of `f` in closure
|
||||
LL | | })
|
||||
| |__________^ second borrow occurs here
|
||||
|
||||
|
@ -24,7 +24,7 @@ LL |
|
|||
LL | |a| {
|
||||
| ^^^ closure construction occurs here
|
||||
LL | f.n.insert(*a);
|
||||
| - second borrow occurs due to use of `f` in closure
|
||||
| --- second borrow occurs due to use of `f` in closure
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | thread::spawn(move|| {
|
|||
| ^^^^^^ move out of `v` occurs here
|
||||
LL |
|
||||
LL | println!("v={}", *v);
|
||||
| - move occurs due to use in closure
|
||||
| -- move occurs due to use in closure
|
||||
LL | });
|
||||
LL | w.use_ref();
|
||||
| - borrow later used here
|
||||
|
@ -21,7 +21,7 @@ LL | thread::spawn(move|| {
|
|||
| ^^^^^^ move out of `v` occurs here
|
||||
LL |
|
||||
LL | println!("v={}", *v);
|
||||
| - move occurs due to use in closure
|
||||
| -- move occurs due to use in closure
|
||||
LL | });
|
||||
LL | w.use_ref();
|
||||
| - borrow later used here
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | p.blockm(|| {
|
|||
| | immutable borrow later used by call
|
||||
| immutable borrow occurs here
|
||||
LL | p.x = 10;
|
||||
| - second borrow occurs due to use of `p` in closure
|
||||
| --- second borrow occurs due to use of `p` in closure
|
||||
|
||||
error[E0502]: cannot borrow `p` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-loan-rcvr.rs:34:5
|
||||
|
|
|
@ -5,10 +5,10 @@ LL | let bar: Box<_> = box 3;
|
|||
| --- captured outer variable
|
||||
LL | let _g = to_fn_mut(|| {
|
||||
LL | let _h = to_fn_once(move || -> isize { *bar });
|
||||
| ^^^^^^^^^^^^^^^^ ---
|
||||
| | |
|
||||
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
|
||||
| | move occurs due to use in closure
|
||||
| ^^^^^^^^^^^^^^^^ ----
|
||||
| | |
|
||||
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
|
||||
| | move occurs due to use in closure
|
||||
| move out of `bar` occurs here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
@ -5,11 +5,11 @@ LL | let t: Box<_> = box 3;
|
|||
| - move occurs because `t` has type `Box<isize>`, which does not implement the `Copy` trait
|
||||
LL |
|
||||
LL | call_f(move|| { *t + 1 });
|
||||
| ------ - variable moved due to use in closure
|
||||
| ------ -- variable moved due to use in closure
|
||||
| |
|
||||
| value moved into closure here
|
||||
LL | call_f(move|| { *t + 1 });
|
||||
| ^^^^^^ - use occurs due to use in closure
|
||||
| ^^^^^^ -- use occurs due to use in closure
|
||||
| |
|
||||
| value used here after move
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | match x {
|
|||
| - value is immutable in match guard
|
||||
...
|
||||
LL | (|| { *x = None; drop(force_fn_once); })();
|
||||
| ^^ - borrow occurs due to use of `x` in closure
|
||||
| ^^ -- borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| cannot mutably borrow
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern g
|
|||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25
|
||||
|
|
||||
LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
|
||||
| ^^ - mutable borrow occurs due to use of `r` in closure
|
||||
| ^^ -- mutable borrow occurs due to use of `r` in closure
|
||||
| |
|
||||
| cannot borrow as mutable
|
||||
|
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
fn main() {
|
||||
let mut p = Point {x: 1, y: 2 };
|
||||
|
||||
let y = &mut p.y;
|
||||
let mut c = || {
|
||||
//~^ ERROR cannot borrow `p` as mutable more than once at a time
|
||||
let x = &mut p.x;
|
||||
println!("{:?}", p);
|
||||
};
|
||||
c();
|
||||
*y+=1;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/borrowck-1.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0499]: cannot borrow `p` as mutable more than once at a time
|
||||
--> $DIR/borrowck-1.rs:13:17
|
||||
|
|
||||
LL | let y = &mut p.y;
|
||||
| -------- first mutable borrow occurs here
|
||||
LL | let mut c = || {
|
||||
| ^^ second mutable borrow occurs here
|
||||
LL |
|
||||
LL | let x = &mut p.x;
|
||||
| --- capture is mutable because of use here
|
||||
LL | println!("{:?}", p);
|
||||
| - second borrow occurs due to use of `p` in closure
|
||||
...
|
||||
LL | *y+=1;
|
||||
| ----- first borrow later used here
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0499`.
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
fn main() {
|
||||
let mut p = Point {x: 1, y: 2 };
|
||||
|
||||
let y = &p.y;
|
||||
let mut c = || {
|
||||
//~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable
|
||||
println!("{:?}", p);
|
||||
let x = &mut p.x;
|
||||
};
|
||||
c();
|
||||
println!("{}", y);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/borrowck-2.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-2.rs:13:17
|
||||
|
|
||||
LL | let y = &p.y;
|
||||
| ---- immutable borrow occurs here
|
||||
LL | let mut c = || {
|
||||
| ^^ mutable borrow occurs here
|
||||
LL |
|
||||
LL | println!("{:?}", p);
|
||||
| - second borrow occurs due to use of `p` in closure
|
||||
LL | let x = &mut p.x;
|
||||
| --- capture is mutable because of use here
|
||||
...
|
||||
LL | println!("{}", y);
|
||||
| - immutable borrow later used here
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
|
@ -0,0 +1,19 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: String,
|
||||
y: String,
|
||||
}
|
||||
fn main() {
|
||||
let mut c = {
|
||||
let mut p = Point {x: "1".to_string(), y: "2".to_string() };
|
||||
|| {
|
||||
let x = &mut p.x;
|
||||
println!("{:?}", p);
|
||||
//~^ ERROR `p` does not live long enough
|
||||
}
|
||||
};
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/borrowck-3.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0597]: `p` does not live long enough
|
||||
--> $DIR/borrowck-3.rs:14:29
|
||||
|
|
||||
LL | let mut c = {
|
||||
| ----- borrow later stored here
|
||||
LL | let mut p = Point {x: "1".to_string(), y: "2".to_string() };
|
||||
LL | || {
|
||||
| -- value captured here
|
||||
LL | let x = &mut p.x;
|
||||
LL | println!("{:?}", p);
|
||||
| ^ borrowed value does not live long enough
|
||||
...
|
||||
LL | };
|
||||
| - `p` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
|
@ -0,0 +1,21 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
fn foo () -> impl FnMut()->() {
|
||||
let mut p = Point {x: 1, y: 2 };
|
||||
let mut c = || {
|
||||
//~^ ERROR closure may outlive the current function, but it borrows `p`
|
||||
p.x+=5;
|
||||
println!("{:?}", p);
|
||||
};
|
||||
c
|
||||
}
|
||||
fn main() {
|
||||
let c = foo();
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/borrowck-4.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0373]: closure may outlive the current function, but it borrows `p`, which is owned by the current function
|
||||
--> $DIR/borrowck-4.rs:11:17
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| ^^ may outlive borrowed value `p`
|
||||
...
|
||||
LL | println!("{:?}", p);
|
||||
| - `p` is borrowed here
|
||||
|
|
||||
note: closure is returned here
|
||||
--> $DIR/borrowck-4.rs:9:14
|
||||
|
|
||||
LL | fn foo () -> impl FnMut()->() {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword
|
||||
|
|
||||
LL | let mut c = move || {
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0373`.
|
|
@ -0,0 +1,26 @@
|
|||
// Tests that two closures cannot simultaneously have mutable
|
||||
// and immutable access to the variable. Issue #6801.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(box_syntax)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn a() {
|
||||
let mut p = Point {x: 3, y:4};
|
||||
let c2 = || p.y * 5;
|
||||
let c1 = || {
|
||||
//~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable
|
||||
dbg!(&p);
|
||||
p.x = 4;
|
||||
};
|
||||
drop(c2);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/borrowck-closures-mut-and-imm.rs:4:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/borrowck-closures-mut-and-imm.rs:17:14
|
||||
|
|
||||
LL | let c2 = || p.y * 5;
|
||||
| -- --- first borrow occurs due to use of `p.y` in closure
|
||||
| |
|
||||
| immutable borrow occurs here
|
||||
LL | let c1 = || {
|
||||
| ^^ mutable borrow occurs here
|
||||
LL |
|
||||
LL | dbg!(&p);
|
||||
| - second borrow occurs due to use of `p` in closure
|
||||
LL | p.x = 4;
|
||||
| --- capture is mutable because of use here
|
||||
LL | };
|
||||
LL | drop(c2);
|
||||
| -- immutable borrow later used here
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
|
@ -13,7 +13,7 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
|
|||
LL | let mut c = || {
|
||||
| -- borrow of `e.0.0.m.x` occurs here
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| - borrow occurs due to use in closure
|
||||
| --------- borrow occurs due to use in closure
|
||||
...
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
|
||||
|
@ -27,7 +27,7 @@ error[E0502]: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed
|
|||
LL | let mut c = || {
|
||||
| -- mutable borrow occurs here
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| - first borrow occurs due to use of `e.0.0.m.x` in closure
|
||||
| --------- first borrow occurs due to use of `e.0.0.m.x` in closure
|
||||
...
|
||||
LL | println!("{}", e.0.0.m.x);
|
||||
| ^^^^^^^^^ immutable borrow occurs here
|
||||
|
@ -41,7 +41,7 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
|
|||
LL | let c = || {
|
||||
| -- borrow of `e.0.0.m.x` occurs here
|
||||
LL | println!("{}", e.0.0.m.x);
|
||||
| - borrow occurs due to use in closure
|
||||
| --------- borrow occurs due to use in closure
|
||||
...
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
|
||||
|
|
|
@ -14,7 +14,7 @@ LL | let mut c = || {
|
|||
| ^^ cannot borrow as mutable
|
||||
LL |
|
||||
LL | z.0.0.0 = format!("X1");
|
||||
| - mutable borrow occurs due to use of `z.0.0.0` in closure
|
||||
| ------- mutable borrow occurs due to use of `z.0.0.0` in closure
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ fn mut_error_struct() {
|
|||
|
||||
let mut c = || {
|
||||
z.0.0.0 = 20;
|
||||
//~^ ERROR: cannot assign to `z`, as it is not declared as mutable
|
||||
//~^ ERROR: cannot assign to `z.0.0.0`, as it is not declared as mutable
|
||||
};
|
||||
|
||||
c();
|
||||
|
@ -23,7 +23,7 @@ fn mut_error_box() {
|
|||
|
||||
let mut c = || {
|
||||
bx.0 = 20;
|
||||
//~^ ERROR: cannot assign to `bx`, as it is not declared as mutable
|
||||
//~^ ERROR: cannot assign to `*bx.0`, as it is not declared as mutable
|
||||
};
|
||||
|
||||
c();
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | #![feature(capture_disjoint_fields)]
|
|||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0594]: cannot assign to `z`, as it is not declared as mutable
|
||||
error[E0594]: cannot assign to `z.0.0.0`, as it is not declared as mutable
|
||||
--> $DIR/cant-mutate-imm.rs:13:9
|
||||
|
|
||||
LL | let z = (y, 10);
|
||||
|
@ -16,7 +16,7 @@ LL | let z = (y, 10);
|
|||
LL | z.0.0.0 = 20;
|
||||
| ^^^^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0594]: cannot assign to `bx`, as it is not declared as mutable
|
||||
error[E0594]: cannot assign to `*bx.0`, as it is not declared as mutable
|
||||
--> $DIR/cant-mutate-imm.rs:25:9
|
||||
|
|
||||
LL | let bx = Box::new(x);
|
||||
|
|
|
@ -13,7 +13,7 @@ error[E0499]: cannot borrow `w.p.x` as mutable more than once at a time
|
|||
LL | let mut c = || {
|
||||
| -- first mutable borrow occurs here
|
||||
LL | w.p.x += 20;
|
||||
| - first borrow occurs due to use of `w.p.x` in closure
|
||||
| ----- first borrow occurs due to use of `w.p.x` in closure
|
||||
...
|
||||
LL | let py = &mut w.p.x;
|
||||
| ^^^^^^^^^^ second mutable borrow occurs here
|
||||
|
|
|
@ -17,7 +17,7 @@ LL | let c = || {
|
|||
| ^^ `ref_mref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||
LL |
|
||||
LL | **ref_mref_x = y;
|
||||
| ---------- mutable borrow occurs due to use of `**ref_mref_x` in closure
|
||||
| ------------ mutable borrow occurs due to use of `**ref_mref_x` in closure
|
||||
|
||||
error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
|
||||
--> $DIR/mut_ref.rs:27:13
|
||||
|
@ -26,7 +26,7 @@ LL | let c = || {
|
|||
| ^^ cannot borrow as mutable
|
||||
LL |
|
||||
LL | **mref_ref_x = y;
|
||||
| ---------- mutable borrow occurs due to use of `**mref_ref_x` in closure
|
||||
| ------------ mutable borrow occurs due to use of `**mref_ref_x` in closure
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
|
|
|
@ -13,7 +13,9 @@ error[E0502]: cannot borrow `p` as immutable because it is also borrowed as muta
|
|||
LL | let mut c = || {
|
||||
| -- mutable borrow occurs here
|
||||
LL | p.x += 10;
|
||||
| - first borrow occurs due to use of `p` in closure
|
||||
| --- capture is mutable because of use here
|
||||
LL | println!("{:?}", p);
|
||||
| - first borrow occurs due to use of `p` in closure
|
||||
...
|
||||
LL | println!("{:?}", p);
|
||||
| ^ immutable borrow occurs here
|
||||
|
|
|
@ -7,7 +7,7 @@ LL |
|
|||
LL | let x = move || {
|
||||
| ^^^^^^^ move out of `fancy_num` occurs here
|
||||
LL | println!("child function: {}", fancy_num.num);
|
||||
| --------- move occurs due to use in closure
|
||||
| ------------- move occurs due to use in closure
|
||||
...
|
||||
LL | println!("main function: {}", fancy_ref.num);
|
||||
| ------------- borrow later used here
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
|
|||
LL | let mut b = || {
|
||||
| -- generator construction occurs here
|
||||
LL | let a = &mut *x;
|
||||
| - first borrow occurs due to use of `x` in generator
|
||||
| -- first borrow occurs due to use of `x` in generator
|
||||
...
|
||||
LL | println!("{}", x);
|
||||
| ^ second borrow occurs here
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | let mut test = |foo: &Foo| {
|
|||
| ----------- mutable borrow occurs here
|
||||
LL | println!("access {}", foo.x);
|
||||
LL | ptr = box Foo { x: ptr.x + 1 };
|
||||
| --- first borrow occurs due to use of `ptr` in closure
|
||||
| --- first borrow occurs due to use of `ptr` in closure
|
||||
...
|
||||
LL | test(&*ptr);
|
||||
| ---- ^^^^^ immutable borrow occurs here
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | match x {
|
|||
| - value is immutable in match guard
|
||||
...
|
||||
LL | (|| { *x = None; drop(force_fn_once); })();
|
||||
| ^^ - borrow occurs due to use of `x` in closure
|
||||
| ^^ -- borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| cannot mutably borrow
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | match **x {
|
|||
| --- value is immutable in match guard
|
||||
...
|
||||
LL | (|| { *x = &None; drop(force_fn_once); })();
|
||||
| ^^ - borrow occurs due to use of `x` in closure
|
||||
| ^^ -- borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| cannot mutably borrow
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ error[E0502]: cannot borrow `*x.1` as mutable because it is also borrowed as imm
|
|||
--> $DIR/issue-61623.rs:6:19
|
||||
|
|
||||
LL | f2(|| x.0, f1(x.1))
|
||||
| -- -- - ^^^ mutable borrow occurs here
|
||||
| -- -- --- ^^^ mutable borrow occurs here
|
||||
| | | |
|
||||
| | | first borrow occurs due to use of `x` in closure
|
||||
| | immutable borrow occurs here
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0505]: cannot move out of `x` because it is borrowed
|
|||
--> $DIR/issue-6801.rs:19:13
|
||||
|
|
||||
LL | let sq = || { *x * *x };
|
||||
| -- - borrow occurs due to use in closure
|
||||
| -- -- borrow occurs due to use in closure
|
||||
| |
|
||||
| borrow of `x` occurs here
|
||||
LL |
|
||||
|
|
|
@ -28,7 +28,7 @@ error[E0500]: closure requires unique access to `x` but it is already borrowed
|
|||
LL | let r = &mut x;
|
||||
| ------ borrow occurs here
|
||||
LL | || *x = 2;
|
||||
| ^^ - second borrow occurs due to use of `x` in closure
|
||||
| ^^ -- second borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| closure construction occurs here
|
||||
LL | r.use_mut();
|
||||
|
@ -88,7 +88,7 @@ LL | fn closure_unique_capture_moved(x: &mut String) {
|
|||
LL | let r = x;
|
||||
| - value moved here
|
||||
LL | || *x = String::new();
|
||||
| ^^ - borrow occurs due to use in closure
|
||||
| ^^ -- borrow occurs due to use in closure
|
||||
| |
|
||||
| value borrowed here after move
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ error[E0505]: cannot move out of `x` because it is borrowed
|
|||
--> $DIR/closure-borrow-spans.rs:65:13
|
||||
|
|
||||
LL | let f = || *x = 0;
|
||||
| -- - borrow occurs due to use in closure
|
||||
| -- -- borrow occurs due to use in closure
|
||||
| |
|
||||
| borrow of `x` occurs here
|
||||
LL | let y = x;
|
||||
|
@ -122,7 +122,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
|
|||
--> $DIR/closure-borrow-spans.rs:71:13
|
||||
|
|
||||
LL | let f = || *x = 0;
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- -- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| closure construction occurs here
|
||||
LL | let y = &x;
|
||||
|
@ -134,7 +134,7 @@ error[E0501]: cannot borrow `x` as mutable because previous closure requires uni
|
|||
--> $DIR/closure-borrow-spans.rs:77:13
|
||||
|
|
||||
LL | let f = || *x = 0;
|
||||
| -- - first borrow occurs due to use of `x` in closure
|
||||
| -- -- first borrow occurs due to use of `x` in closure
|
||||
| |
|
||||
| closure construction occurs here
|
||||
LL | let y = &mut x;
|
||||
|
@ -143,10 +143,10 @@ LL | f.use_ref();
|
|||
| - first borrow later used here
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/closure-borrow-spans.rs:86:17
|
||||
--> $DIR/closure-borrow-spans.rs:86:16
|
||||
|
|
||||
LL | f = || *x = 0;
|
||||
| -- ^ borrowed value does not live long enough
|
||||
| -- ^^ borrowed value does not live long enough
|
||||
| |
|
||||
| value captured here
|
||||
LL | }
|
||||
|
@ -158,7 +158,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
|
|||
--> $DIR/closure-borrow-spans.rs:93:5
|
||||
|
|
||||
LL | let f = || *x = 0;
|
||||
| -- - borrow occurs due to use in closure
|
||||
| -- -- borrow occurs due to use in closure
|
||||
| |
|
||||
| borrow of `*x` occurs here
|
||||
LL | *x = 1;
|
||||
|
|
|
@ -133,9 +133,9 @@ LL | fn_ref(|| {
|
|||
LL | | ||
|
||||
| | ^^ cannot borrow as mutable
|
||||
LL | | *x = 1;});
|
||||
| |__________-_____- in this closure
|
||||
| |
|
||||
| mutable borrow occurs due to use of `x` in closure
|
||||
| |_________--_____- in this closure
|
||||
| |
|
||||
| mutable borrow occurs due to use of `x` in closure
|
||||
|
||||
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
|
||||
--> $DIR/closure-captures.rs:51:9
|
||||
|
@ -150,9 +150,9 @@ LL | fn_ref(move || {
|
|||
LL | | ||
|
||||
| | ^^ cannot borrow as mutable
|
||||
LL | | *x = 1;});
|
||||
| |__________-_____- in this closure
|
||||
| |
|
||||
| mutable borrow occurs due to use of `x` in closure
|
||||
| |_________--_____- in this closure
|
||||
| |
|
||||
| mutable borrow occurs due to use of `x` in closure
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | let y = &x;
|
|||
LL | x = 0;
|
||||
| ^^^^^ assignment to borrowed `x` occurs here
|
||||
LL | || *y;
|
||||
| - borrow later captured here by closure
|
||||
| -- borrow later captured here by closure
|
||||
|
||||
error[E0506]: cannot assign to `x` because it is borrowed
|
||||
--> $DIR/closure-use-spans.rs:11:5
|
||||
|
@ -16,7 +16,7 @@ LL | let y = &mut x;
|
|||
LL | x = 0;
|
||||
| ^^^^^ assignment to borrowed `x` occurs here
|
||||
LL | || *y = 1;
|
||||
| - borrow later captured here by closure
|
||||
| -- borrow later captured here by closure
|
||||
|
||||
error[E0506]: cannot assign to `x` because it is borrowed
|
||||
--> $DIR/closure-use-spans.rs:17:5
|
||||
|
|
|
@ -21,7 +21,7 @@ error[E0524]: two closures require unique access to `x` at the same time
|
|||
--> $DIR/closures-in-loops.rs:20:16
|
||||
|
|
||||
LL | v.push(|| *x = String::new());
|
||||
| ^^ - borrows occur due to use of `x` in closure
|
||||
| ^^ -- borrows occur due to use of `x` in closure
|
||||
| |
|
||||
| closures are constructed here in different iterations of loop
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | self.thing.bar(|| {
|
|||
| |
|
||||
LL | |
|
||||
LL | | &self.number;
|
||||
| | ---- first borrow occurs due to use of `self` in closure
|
||||
| | ----------- first borrow occurs due to use of `self` in closure
|
||||
LL | | });
|
||||
| |__________^ mutable borrow occurs here
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ error[E0597]: `self` does not live long enough
|
|||
LL | let _f = || {
|
||||
| -- value captured here
|
||||
LL | let p: &'static mut usize = &mut self.food;
|
||||
| ------------------ ^^^^ borrowed value does not live long enough
|
||||
| ------------------ ^^^^^^^^^ borrowed value does not live long enough
|
||||
| |
|
||||
| type annotation requires that `self` is borrowed for `'static`
|
||||
...
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue