mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Auto merge of #47420 - davidtwco:issue-46885, r=estebank
Fix off-by-one spans in MIR borrowck errors Fixes #46885. r? @nikomatsakis
This commit is contained in:
commit
7d6e5b9da0
@ -958,7 +958,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// `sp` only covers `T`, change it so that it covers
|
// `sp` only covers `T`, change it so that it covers
|
||||||
// `T:` when appropriate
|
// `T:` when appropriate
|
||||||
let sp = if has_lifetimes {
|
let sp = if has_lifetimes {
|
||||||
sp.to(sp.next_point().next_point())
|
sp.to(self.tcx.sess.codemap().next_point(
|
||||||
|
self.tcx.sess.codemap().next_point(sp)))
|
||||||
} else {
|
} else {
|
||||||
sp
|
sp
|
||||||
};
|
};
|
||||||
|
@ -591,8 +591,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||||||
// 3. Where does old loan expire.
|
// 3. Where does old loan expire.
|
||||||
|
|
||||||
let previous_end_span =
|
let previous_end_span =
|
||||||
Some(old_loan.kill_scope.span(self.tcx(), &self.bccx.region_scope_tree)
|
Some(self.tcx().sess.codemap().end_point(
|
||||||
.end_point());
|
old_loan.kill_scope.span(self.tcx(), &self.bccx.region_scope_tree)));
|
||||||
|
|
||||||
let mut err = match (new_loan.kind, old_loan.kind) {
|
let mut err = match (new_loan.kind, old_loan.kind) {
|
||||||
(ty::MutBorrow, ty::MutBorrow) =>
|
(ty::MutBorrow, ty::MutBorrow) =>
|
||||||
|
@ -1276,7 +1276,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
|||||||
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
|
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReScope(scope) => {
|
ty::ReScope(scope) => {
|
||||||
Some(scope.span(self.tcx, &self.region_scope_tree).end_point())
|
Some(self.tcx.sess.codemap().end_point(
|
||||||
|
scope.span(self.tcx, &self.region_scope_tree)))
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
|
@ -1112,10 +1112,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||||||
debug!("check_for_invalidation_at_exit({:?}): INVALID", place);
|
debug!("check_for_invalidation_at_exit({:?}): INVALID", place);
|
||||||
// FIXME: should be talking about the region lifetime instead
|
// FIXME: should be talking about the region lifetime instead
|
||||||
// of just a span here.
|
// of just a span here.
|
||||||
|
let span = self.tcx.sess.codemap().end_point(span);
|
||||||
self.report_borrowed_value_does_not_live_long_enough(
|
self.report_borrowed_value_does_not_live_long_enough(
|
||||||
context,
|
context,
|
||||||
borrow,
|
borrow,
|
||||||
span.end_point(),
|
span,
|
||||||
flow_state.borrows.operator(),
|
flow_state.borrows.operator(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -695,10 +695,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
if let DropKind::Value { .. } = drop_kind {
|
if let DropKind::Value { .. } = drop_kind {
|
||||||
scope.needs_cleanup = true;
|
scope.needs_cleanup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let region_scope_span = region_scope.span(self.hir.tcx(),
|
let region_scope_span = region_scope.span(self.hir.tcx(),
|
||||||
&self.hir.region_scope_tree);
|
&self.hir.region_scope_tree);
|
||||||
// Attribute scope exit drops to scope's closing brace
|
// Attribute scope exit drops to scope's closing brace.
|
||||||
let scope_end = region_scope_span.with_lo(region_scope_span.hi());
|
let scope_end = self.hir.tcx().sess.codemap().end_point(region_scope_span);
|
||||||
|
|
||||||
scope.drops.push(DropData {
|
scope.drops.push(DropData {
|
||||||
span: scope_end,
|
span: scope_end,
|
||||||
location: place.clone(),
|
location: place.clone(),
|
||||||
|
@ -537,8 +537,8 @@ impl<'a, 'gcx, 'tcx> ActiveBorrows<'a, 'gcx, 'tcx> {
|
|||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => {
|
None => {
|
||||||
match self.0.region_span_map.get(region) {
|
match self.0.region_span_map.get(region) {
|
||||||
Some(span) => Some(span.end_point()),
|
Some(span) => Some(self.0.tcx.sess.codemap().end_point(*span)),
|
||||||
None => Some(self.0.mir.span.end_point())
|
None => Some(self.0.tcx.sess.codemap().end_point(self.0.mir.span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2871,8 +2871,8 @@ impl<'a> Resolver<'a> {
|
|||||||
if let Some(sp) = self.current_type_ascription.last() {
|
if let Some(sp) = self.current_type_ascription.last() {
|
||||||
let mut sp = *sp;
|
let mut sp = *sp;
|
||||||
loop { // try to find the `:`, bail on first non-':'/non-whitespace
|
loop { // try to find the `:`, bail on first non-':'/non-whitespace
|
||||||
sp = sp.next_point();
|
sp = cm.next_point(sp);
|
||||||
if let Ok(snippet) = cm.span_to_snippet(sp.to(sp.next_point())) {
|
if let Ok(snippet) = cm.span_to_snippet(sp.to(cm.next_point(sp))) {
|
||||||
debug!("snippet {:?}", snippet);
|
debug!("snippet {:?}", snippet);
|
||||||
let line_sp = cm.lookup_char_pos(sp.hi()).line;
|
let line_sp = cm.lookup_char_pos(sp.hi()).line;
|
||||||
let line_base_sp = cm.lookup_char_pos(base_span.lo()).line;
|
let line_base_sp = cm.lookup_char_pos(base_span.lo()).line;
|
||||||
|
@ -2457,7 +2457,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
err.span_label(def_s, "defined here");
|
err.span_label(def_s, "defined here");
|
||||||
}
|
}
|
||||||
if sugg_unit {
|
if sugg_unit {
|
||||||
let sugg_span = expr_sp.end_point();
|
let sugg_span = sess.codemap().end_point(expr_sp);
|
||||||
// remove closing `)` from the span
|
// remove closing `)` from the span
|
||||||
let sugg_span = sugg_span.with_hi(sugg_span.lo());
|
let sugg_span = sugg_span.with_hi(sugg_span.lo());
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
@ -4446,10 +4446,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// statement and the return type has been left as default or has been specified as `()`. If so,
|
/// statement and the return type has been left as default or has been specified as `()`. If so,
|
||||||
/// it suggests adding a semicolon.
|
/// it suggests adding a semicolon.
|
||||||
fn suggest_missing_semicolon(&self,
|
fn suggest_missing_semicolon(&self,
|
||||||
err: &mut DiagnosticBuilder<'tcx>,
|
err: &mut DiagnosticBuilder<'tcx>,
|
||||||
expression: &'gcx hir::Expr,
|
expression: &'gcx hir::Expr,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
cause_span: Span) {
|
cause_span: Span) {
|
||||||
if expected.is_nil() {
|
if expected.is_nil() {
|
||||||
// `BlockTailExpression` only relevant if the tail expr would be
|
// `BlockTailExpression` only relevant if the tail expr would be
|
||||||
// useful on its own.
|
// useful on its own.
|
||||||
@ -4461,7 +4461,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
hir::ExprLoop(..) |
|
hir::ExprLoop(..) |
|
||||||
hir::ExprMatch(..) |
|
hir::ExprMatch(..) |
|
||||||
hir::ExprBlock(..) => {
|
hir::ExprBlock(..) => {
|
||||||
let sp = cause_span.next_point();
|
let sp = self.tcx.sess.codemap().next_point(cause_span);
|
||||||
err.span_suggestion(sp,
|
err.span_suggestion(sp,
|
||||||
"try adding a semicolon",
|
"try adding a semicolon",
|
||||||
";".to_string());
|
";".to_string());
|
||||||
|
@ -25,6 +25,7 @@ pub use self::ExpnFormat::*;
|
|||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
use rustc_data_structures::stable_hasher::StableHasher;
|
||||||
use std::cell::{RefCell, Ref};
|
use std::cell::{RefCell, Ref};
|
||||||
|
use std::cmp;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -607,6 +608,101 @@ impl CodeMap {
|
|||||||
self.span_until_char(sp, '{')
|
self.span_until_char(sp, '{')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a new span representing just the end-point of this span
|
||||||
|
pub fn end_point(&self, sp: Span) -> Span {
|
||||||
|
let pos = sp.hi().0;
|
||||||
|
|
||||||
|
let width = self.find_width_of_character_at_span(sp, false);
|
||||||
|
let corrected_end_position = pos.checked_sub(width).unwrap_or(pos);
|
||||||
|
|
||||||
|
let end_point = BytePos(cmp::max(corrected_end_position, sp.lo().0));
|
||||||
|
sp.with_lo(end_point)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new span representing the next character after the end-point of this span
|
||||||
|
pub fn next_point(&self, sp: Span) -> Span {
|
||||||
|
let start_of_next_point = sp.hi().0;
|
||||||
|
|
||||||
|
let width = self.find_width_of_character_at_span(sp, true);
|
||||||
|
// If the width is 1, then the next span should point to the same `lo` and `hi`. However,
|
||||||
|
// in the case of a multibyte character, where the width != 1, the next span should
|
||||||
|
// span multiple bytes to include the whole character.
|
||||||
|
let end_of_next_point = start_of_next_point.checked_add(
|
||||||
|
width - 1).unwrap_or(start_of_next_point);
|
||||||
|
|
||||||
|
let end_of_next_point = BytePos(cmp::max(sp.lo().0 + 1, end_of_next_point));
|
||||||
|
Span::new(BytePos(start_of_next_point), end_of_next_point, sp.ctxt())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds the width of a character, either before or after the provided span.
|
||||||
|
fn find_width_of_character_at_span(&self, sp: Span, forwards: bool) -> u32 {
|
||||||
|
// Disregard malformed spans and assume a one-byte wide character.
|
||||||
|
if sp.lo() >= sp.hi() {
|
||||||
|
debug!("find_width_of_character_at_span: early return malformed span");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let local_begin = self.lookup_byte_offset(sp.lo());
|
||||||
|
let local_end = self.lookup_byte_offset(sp.hi());
|
||||||
|
debug!("find_width_of_character_at_span: local_begin=`{:?}`, local_end=`{:?}`",
|
||||||
|
local_begin, local_end);
|
||||||
|
|
||||||
|
let start_index = local_begin.pos.to_usize();
|
||||||
|
let end_index = local_end.pos.to_usize();
|
||||||
|
debug!("find_width_of_character_at_span: start_index=`{:?}`, end_index=`{:?}`",
|
||||||
|
start_index, end_index);
|
||||||
|
|
||||||
|
// Disregard indexes that are at the start or end of their spans, they can't fit bigger
|
||||||
|
// characters.
|
||||||
|
if (!forwards && end_index == usize::min_value()) ||
|
||||||
|
(forwards && start_index == usize::max_value()) {
|
||||||
|
debug!("find_width_of_character_at_span: start or end of span, cannot be multibyte");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let source_len = (local_begin.fm.end_pos - local_begin.fm.start_pos).to_usize();
|
||||||
|
debug!("find_width_of_character_at_span: source_len=`{:?}`", source_len);
|
||||||
|
// Ensure indexes are also not malformed.
|
||||||
|
if start_index > end_index || end_index > source_len {
|
||||||
|
debug!("find_width_of_character_at_span: source indexes are malformed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to extend the snippet to the end of the src rather than to end_index so when
|
||||||
|
// searching forwards for boundaries we've got somewhere to search.
|
||||||
|
let snippet = if let Some(ref src) = local_begin.fm.src {
|
||||||
|
let len = src.len();
|
||||||
|
(&src[start_index..len]).to_string()
|
||||||
|
} else if let Some(src) = local_begin.fm.external_src.borrow().get_source() {
|
||||||
|
let len = src.len();
|
||||||
|
(&src[start_index..len]).to_string()
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
debug!("find_width_of_character_at_span: snippet=`{:?}`", snippet);
|
||||||
|
|
||||||
|
let file_start_pos = local_begin.fm.start_pos.to_usize();
|
||||||
|
let file_end_pos = local_begin.fm.end_pos.to_usize();
|
||||||
|
debug!("find_width_of_character_at_span: file_start_pos=`{:?}` file_end_pos=`{:?}`",
|
||||||
|
file_start_pos, file_end_pos);
|
||||||
|
|
||||||
|
let mut target = if forwards { end_index + 1 } else { end_index - 1 };
|
||||||
|
debug!("find_width_of_character_at_span: initial target=`{:?}`", target);
|
||||||
|
|
||||||
|
while !snippet.is_char_boundary(target - start_index)
|
||||||
|
&& target >= file_start_pos && target <= file_end_pos {
|
||||||
|
target = if forwards { target + 1 } else { target - 1 };
|
||||||
|
debug!("find_width_of_character_at_span: target=`{:?}`", target);
|
||||||
|
}
|
||||||
|
debug!("find_width_of_character_at_span: final target=`{:?}`", target);
|
||||||
|
|
||||||
|
if forwards {
|
||||||
|
(target - end_index) as u32
|
||||||
|
} else {
|
||||||
|
(end_index - target) as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_filemap(&self, filename: &FileName) -> Option<Rc<FileMap>> {
|
pub fn get_filemap(&self, filename: &FileName) -> Option<Rc<FileMap>> {
|
||||||
for fm in self.files.borrow().iter() {
|
for fm in self.files.borrow().iter() {
|
||||||
if *filename == fm.name {
|
if *filename == fm.name {
|
||||||
|
@ -704,13 +704,15 @@ impl<'a> Parser<'a> {
|
|||||||
expect.clone()
|
expect.clone()
|
||||||
};
|
};
|
||||||
(format!("expected one of {}, found `{}`", expect, actual),
|
(format!("expected one of {}, found `{}`", expect, actual),
|
||||||
(self.prev_span.next_point(), format!("expected one of {} here", short_expect)))
|
(self.sess.codemap().next_point(self.prev_span),
|
||||||
|
format!("expected one of {} here", short_expect)))
|
||||||
} else if expected.is_empty() {
|
} else if expected.is_empty() {
|
||||||
(format!("unexpected token: `{}`", actual),
|
(format!("unexpected token: `{}`", actual),
|
||||||
(self.prev_span, "unexpected token after this".to_string()))
|
(self.prev_span, "unexpected token after this".to_string()))
|
||||||
} else {
|
} else {
|
||||||
(format!("expected {}, found `{}`", expect, actual),
|
(format!("expected {}, found `{}`", expect, actual),
|
||||||
(self.prev_span.next_point(), format!("expected {} here", expect)))
|
(self.sess.codemap().next_point(self.prev_span),
|
||||||
|
format!("expected {} here", expect)))
|
||||||
};
|
};
|
||||||
let mut err = self.fatal(&msg_exp);
|
let mut err = self.fatal(&msg_exp);
|
||||||
let sp = if self.token == token::Token::Eof {
|
let sp = if self.token == token::Token::Eof {
|
||||||
@ -3190,7 +3192,7 @@ impl<'a> Parser<'a> {
|
|||||||
// return. This won't catch blocks with an explicit `return`, but that would be caught by
|
// return. This won't catch blocks with an explicit `return`, but that would be caught by
|
||||||
// the dead code lint.
|
// the dead code lint.
|
||||||
if self.eat_keyword(keywords::Else) || !cond.returns() {
|
if self.eat_keyword(keywords::Else) || !cond.returns() {
|
||||||
let sp = lo.next_point();
|
let sp = self.sess.codemap().next_point(lo);
|
||||||
let mut err = self.diagnostic()
|
let mut err = self.diagnostic()
|
||||||
.struct_span_err(sp, "missing condition for `if` statemement");
|
.struct_span_err(sp, "missing condition for `if` statemement");
|
||||||
err.span_label(sp, "expected if condition here");
|
err.span_label(sp, "expected if condition here");
|
||||||
|
@ -216,20 +216,6 @@ impl Span {
|
|||||||
self.data().with_ctxt(ctxt)
|
self.data().with_ctxt(ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new span representing just the end-point of this span
|
|
||||||
pub fn end_point(self) -> Span {
|
|
||||||
let span = self.data();
|
|
||||||
let lo = cmp::max(span.hi.0 - 1, span.lo.0);
|
|
||||||
span.with_lo(BytePos(lo))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new span representing the next character after the end-point of this span
|
|
||||||
pub fn next_point(self) -> Span {
|
|
||||||
let span = self.data();
|
|
||||||
let lo = cmp::max(span.hi.0, span.lo.0 + 1);
|
|
||||||
Span::new(BytePos(lo), BytePos(lo), span.ctxt)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `self` if `self` is not the dummy span, and `other` otherwise.
|
/// Returns `self` if `self` is not the dummy span, and `other` otherwise.
|
||||||
pub fn substitute_dummy(self, other: Span) -> Span {
|
pub fn substitute_dummy(self, other: Span) -> Span {
|
||||||
if self.source_equal(&DUMMY_SP) { other } else { self }
|
if self.source_equal(&DUMMY_SP) { other } else { self }
|
||||||
|
@ -15,7 +15,7 @@ error[E0597]: `z` does not live long enough (Mir)
|
|||||||
16 | &mut z
|
16 | &mut z
|
||||||
| ^^^^^^ borrowed value does not live long enough
|
| ^^^^^^ borrowed value does not live long enough
|
||||||
17 | };
|
17 | };
|
||||||
| - `z` dropped here while still borrowed
|
| - `z` dropped here while still borrowed
|
||||||
...
|
...
|
||||||
21 | }
|
21 | }
|
||||||
| - borrowed value needs to live until here
|
| - borrowed value needs to live until here
|
||||||
|
@ -16,7 +16,7 @@ error[E0597]: `x` does not live long enough (Mir)
|
|||||||
| ^^ borrowed value does not live long enough
|
| ^^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
18 | }
|
18 | }
|
||||||
| - borrowed value only lives until here
|
| - borrowed value only lives until here
|
||||||
|
|
|
|
||||||
= note: borrowed value must be valid for the static lifetime...
|
= note: borrowed value must be valid for the static lifetime...
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ error[E0597]: borrowed value does not live long enough (Mir)
|
|||||||
| ^ temporary value does not live long enough
|
| ^ temporary value does not live long enough
|
||||||
...
|
...
|
||||||
17 | }
|
17 | }
|
||||||
| - temporary value only lives until here
|
| - temporary value only lives until here
|
||||||
|
|
|
|
||||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
|
||||||
--> $DIR/issue-46472.rs:13:1
|
--> $DIR/issue-46472.rs:13:1
|
||||||
|
@ -5,7 +5,7 @@ error[E0597]: `y` does not live long enough
|
|||||||
| ^^ borrowed value does not live long enough
|
| ^^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
38 | }
|
38 | }
|
||||||
| - borrowed value only lives until here
|
| - borrowed value only lives until here
|
||||||
39 |
|
39 |
|
||||||
40 | deref(p);
|
40 | deref(p);
|
||||||
| - borrow later used here
|
| - borrow later used here
|
||||||
|
@ -30,7 +30,7 @@ error[E0597]: `y` does not live long enough
|
|||||||
| ^^ borrowed value does not live long enough
|
| ^^ borrowed value does not live long enough
|
||||||
38 | //~^ ERROR `y` does not live long enough [E0597]
|
38 | //~^ ERROR `y` does not live long enough [E0597]
|
||||||
39 | }
|
39 | }
|
||||||
| - borrowed value only lives until here
|
| - borrowed value only lives until here
|
||||||
40 |
|
40 |
|
||||||
41 | deref(p);
|
41 | deref(p);
|
||||||
| - borrow later used here
|
| - borrow later used here
|
||||||
|
@ -57,7 +57,7 @@ error[E0597]: `y` does not live long enough
|
|||||||
| |_________^ borrowed value does not live long enough
|
| |_________^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
36 | }
|
36 | }
|
||||||
| - borrowed value only lives until here
|
| - borrowed value only lives until here
|
||||||
37 |
|
37 |
|
||||||
38 | deref(p);
|
38 | deref(p);
|
||||||
| - borrow later used here
|
| - borrow later used here
|
||||||
|
@ -34,7 +34,7 @@ error[E0597]: `y` does not live long enough
|
|||||||
| ^^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
36 | }
|
36 | }
|
||||||
| - borrowed value only lives until here
|
| - borrowed value only lives until here
|
||||||
37 |
|
37 |
|
||||||
38 | deref(p);
|
38 | deref(p);
|
||||||
| - borrow later used here
|
| - borrow later used here
|
||||||
|
@ -8,7 +8,7 @@ error[E0506]: cannot assign to `v[..]` because it is borrowed
|
|||||||
| ^^^^^^^^^ assignment to borrowed `v[..]` occurs here
|
| ^^^^^^^^^ assignment to borrowed `v[..]` occurs here
|
||||||
...
|
...
|
||||||
35 | }
|
35 | }
|
||||||
| - borrow later used here, when `p` is dropped
|
| - borrow later used here, when `p` is dropped
|
||||||
|
|
||||||
error[E0506]: cannot assign to `v[..]` because it is borrowed
|
error[E0506]: cannot assign to `v[..]` because it is borrowed
|
||||||
--> $DIR/drop-no-may-dangle.rs:34:5
|
--> $DIR/drop-no-may-dangle.rs:34:5
|
||||||
@ -19,7 +19,7 @@ error[E0506]: cannot assign to `v[..]` because it is borrowed
|
|||||||
34 | v[0] += 1; //~ ERROR cannot assign to `v[..]` because it is borrowed
|
34 | v[0] += 1; //~ ERROR cannot assign to `v[..]` because it is borrowed
|
||||||
| ^^^^^^^^^ assignment to borrowed `v[..]` occurs here
|
| ^^^^^^^^^ assignment to borrowed `v[..]` occurs here
|
||||||
35 | }
|
35 | }
|
||||||
| - borrow later used here, when `p` is dropped
|
| - borrow later used here, when `p` is dropped
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ error[E0506]: cannot assign to `x` because it is borrowed
|
|||||||
| ^^^^^ assignment to borrowed `x` occurs here
|
| ^^^^^ assignment to borrowed `x` occurs here
|
||||||
33 | // FIXME ^ Should not error in the future with implicit dtors, only manually implemented ones
|
33 | // FIXME ^ Should not error in the future with implicit dtors, only manually implemented ones
|
||||||
34 | }
|
34 | }
|
||||||
| - borrow later used here, when `foo` is dropped
|
| - borrow later used here, when `foo` is dropped
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ error[E0506]: cannot assign to `x` because it is borrowed
|
|||||||
31 | x = 1; //~ ERROR cannot assign to `x` because it is borrowed [E0506]
|
31 | x = 1; //~ ERROR cannot assign to `x` because it is borrowed [E0506]
|
||||||
| ^^^^^ assignment to borrowed `x` occurs here
|
| ^^^^^ assignment to borrowed `x` occurs here
|
||||||
32 | }
|
32 | }
|
||||||
| - borrow later used here, when `foo` is dropped
|
| - borrow later used here, when `foo` is dropped
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ error[E0506]: cannot assign to `x` because it is borrowed
|
|||||||
| ^^^^^ assignment to borrowed `x` occurs here
|
| ^^^^^ assignment to borrowed `x` occurs here
|
||||||
33 | // FIXME ^ This currently errors and it should not.
|
33 | // FIXME ^ This currently errors and it should not.
|
||||||
34 | }
|
34 | }
|
||||||
| - borrow later used here, when `foo` is dropped
|
| - borrow later used here, when `foo` is dropped
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ error[E0506]: cannot assign to `x` because it is borrowed
|
|||||||
26 | x = 1; //~ ERROR cannot assign to `x` because it is borrowed [E0506]
|
26 | x = 1; //~ ERROR cannot assign to `x` because it is borrowed [E0506]
|
||||||
| ^^^^^ assignment to borrowed `x` occurs here
|
| ^^^^^ assignment to borrowed `x` occurs here
|
||||||
27 | }
|
27 | }
|
||||||
| - borrow later used here, when `wrap` is dropped
|
| - borrow later used here, when `wrap` is dropped
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ error[E0597]: borrowed value does not live long enough
|
|||||||
| ^^^^^^^ temporary value does not live long enough
|
| ^^^^^^^ temporary value does not live long enough
|
||||||
18 | x
|
18 | x
|
||||||
19 | }
|
19 | }
|
||||||
| - temporary value only lives until here
|
| - temporary value only lives until here
|
||||||
|
|
|
|
||||||
= note: borrowed value must be valid for lifetime '_#2r...
|
= note: borrowed value must be valid for lifetime '_#2r...
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user