Don't unwrap the result of span_to_snippet
It can return `Err` due to macros being expanded across crates or files.
This commit is contained in:
parent
478464570e
commit
365ff62fca
5 changed files with 90 additions and 43 deletions
|
@ -415,20 +415,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
"{:?}",
|
||||
move_place.ty(self.body, self.infcx.tcx).ty,
|
||||
);
|
||||
let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
|
||||
let is_option = move_ty.starts_with("std::option::Option");
|
||||
let is_result = move_ty.starts_with("std::result::Result");
|
||||
if is_option || is_result {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("consider borrowing the `{}`'s content", if is_option {
|
||||
"Option"
|
||||
} else {
|
||||
"Result"
|
||||
}),
|
||||
format!("{}.as_ref()", snippet),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
|
||||
let is_option = move_ty.starts_with("std::option::Option");
|
||||
let is_result = move_ty.starts_with("std::result::Result");
|
||||
if is_option || is_result {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("consider borrowing the `{}`'s content", if is_option {
|
||||
"Option"
|
||||
} else {
|
||||
"Result"
|
||||
}),
|
||||
format!("{}.as_ref()", snippet),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
err
|
||||
}
|
||||
|
@ -439,19 +440,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
err: &mut DiagnosticBuilder<'a>,
|
||||
span: Span,
|
||||
) {
|
||||
let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
|
||||
match error {
|
||||
GroupedMoveError::MovesFromPlace {
|
||||
mut binds_to,
|
||||
move_from,
|
||||
..
|
||||
} => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider borrowing here",
|
||||
format!("&{}", snippet),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider borrowing here",
|
||||
format!("&{}", snippet),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
}
|
||||
|
||||
if binds_to.is_empty() {
|
||||
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
|
||||
|
@ -517,27 +519,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
..
|
||||
}))
|
||||
) = bind_to.is_user_variable {
|
||||
let pat_snippet = self.infcx.tcx.sess.source_map()
|
||||
.span_to_snippet(pat_span)
|
||||
.unwrap();
|
||||
if pat_snippet.starts_with('&') {
|
||||
let pat_snippet = pat_snippet[1..].trim_start();
|
||||
let suggestion;
|
||||
let to_remove;
|
||||
if pat_snippet.starts_with("mut")
|
||||
&& pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
|
||||
{
|
||||
suggestion = pat_snippet["mut".len()..].trim_start();
|
||||
to_remove = "&mut";
|
||||
} else {
|
||||
suggestion = pat_snippet;
|
||||
to_remove = "&";
|
||||
if let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
|
||||
{
|
||||
if pat_snippet.starts_with('&') {
|
||||
let pat_snippet = pat_snippet[1..].trim_start();
|
||||
let suggestion;
|
||||
let to_remove;
|
||||
if pat_snippet.starts_with("mut")
|
||||
&& pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
|
||||
{
|
||||
suggestion = pat_snippet["mut".len()..].trim_start();
|
||||
to_remove = "&mut";
|
||||
} else {
|
||||
suggestion = pat_snippet;
|
||||
to_remove = "&";
|
||||
}
|
||||
suggestions.push((
|
||||
pat_span,
|
||||
to_remove,
|
||||
suggestion.to_owned(),
|
||||
));
|
||||
}
|
||||
suggestions.push((
|
||||
pat_span,
|
||||
to_remove,
|
||||
suggestion.to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -711,8 +711,8 @@ fn annotate_struct_field(
|
|||
}
|
||||
|
||||
/// If possible, suggest replacing `ref` with `ref mut`.
|
||||
fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<(String)> {
|
||||
let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).unwrap();
|
||||
fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
|
||||
let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
|
||||
if hi_src.starts_with("ref")
|
||||
&& hi_src["ref".len()..].starts_with(Pattern_White_Space)
|
||||
{
|
||||
|
|
7
src/test/ui/borrowck/move-error-snippets-ext.rs
Normal file
7
src/test/ui/borrowck/move-error-snippets-ext.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
// ignore-test
|
||||
|
||||
macro_rules! aaa {
|
||||
($c:ident) => {{
|
||||
let a = $c;
|
||||
}}
|
||||
}
|
23
src/test/ui/borrowck/move-error-snippets.rs
Normal file
23
src/test/ui/borrowck/move-error-snippets.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Test that we don't ICE after trying to construct a cross-file snippet #63800.
|
||||
|
||||
// compile-flags: --test
|
||||
|
||||
#[macro_use]
|
||||
#[path = "move-error-snippets-ext.rs"]
|
||||
mod move_error_snippets_ext;
|
||||
|
||||
struct A;
|
||||
|
||||
macro_rules! sss {
|
||||
() => {
|
||||
#[test]
|
||||
fn fff() {
|
||||
static D: A = A;
|
||||
aaa!(D); //~ ERROR cannot move
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
sss!();
|
||||
|
||||
fn main() {}
|
15
src/test/ui/borrowck/move-error-snippets.stderr
Normal file
15
src/test/ui/borrowck/move-error-snippets.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error[E0507]: cannot move out of static item `D`
|
||||
--> $DIR/move-error-snippets.rs:16:18
|
||||
|
|
||||
LL | | #[macro_use]
|
||||
| |__________________^ move occurs because `D` has type `A`, which does not implement the `Copy` trait
|
||||
...
|
||||
LL | aaa!(D);
|
||||
| __________________^
|
||||
...
|
||||
LL | sss!();
|
||||
| ------- in this macro invocation
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
Loading…
Add table
Add a link
Reference in a new issue