Skip to content

Commit b91c376

Browse files
authored
Rollup merge of #70725 - Centril:nix-unwraps, r=estebank
Avoid `.unwrap()`s on `.span_to_snippet(...)`s First commit fixes #70724 and the others fix similar issues found by grepping. r? @estebank
2 parents 5082fe2 + 5cb5dde commit b91c376

File tree

7 files changed

+116
-75
lines changed

7 files changed

+116
-75
lines changed

src/librustc_parse/parser/stmt.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ impl<'a> Parser<'a> {
165165
// Rewind to before attempting to parse the type and continue parsing.
166166
let parser_snapshot_after_type = self.clone();
167167
mem::replace(self, parser_snapshot_before_type);
168-
169-
let snippet = self.span_to_snippet(pat.span).unwrap();
170-
err.span_label(pat.span, format!("while parsing the type for `{}`", snippet));
168+
if let Ok(snip) = self.span_to_snippet(pat.span) {
169+
err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
170+
}
171171
(Some((parser_snapshot_after_type, colon_sp, err)), None)
172172
}
173173
}

src/librustc_trait_selection/traits/error_reporting/mod.rs

+24-33
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub trait InferCtxtExt<'tcx> {
6565
/// returns a span and `ArgKind` information that describes the
6666
/// arguments it expects. This can be supplied to
6767
/// `report_arg_count_mismatch`.
68-
fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>);
68+
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)>;
6969

7070
/// Reports an error when the number of arguments needed by a
7171
/// trait match doesn't match the number that the expression
@@ -611,10 +611,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
611611
)
612612
} else {
613613
let (closure_span, found) = found_did
614-
.and_then(|did| self.tcx.hir().get_if_local(did))
615-
.map(|node| {
616-
let (found_span, found) = self.get_fn_like_arguments(node);
617-
(Some(found_span), found)
614+
.and_then(|did| {
615+
let node = self.tcx.hir().get_if_local(did)?;
616+
let (found_span, found) = self.get_fn_like_arguments(node)?;
617+
Some((Some(found_span), found))
618618
})
619619
.unwrap_or((found_span, found));
620620

@@ -672,43 +672,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
672672
/// returns a span and `ArgKind` information that describes the
673673
/// arguments it expects. This can be supplied to
674674
/// `report_arg_count_mismatch`.
675-
fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>) {
676-
match node {
675+
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)> {
676+
let sm = self.tcx.sess.source_map();
677+
let hir = self.tcx.hir();
678+
Some(match node {
677679
Node::Expr(&hir::Expr {
678680
kind: hir::ExprKind::Closure(_, ref _decl, id, span, _),
679681
..
680682
}) => (
681-
self.tcx.sess.source_map().guess_head_span(span),
682-
self.tcx
683-
.hir()
684-
.body(id)
683+
sm.guess_head_span(span),
684+
hir.body(id)
685685
.params
686686
.iter()
687687
.map(|arg| {
688688
if let hir::Pat { kind: hir::PatKind::Tuple(ref args, _), span, .. } =
689689
*arg.pat
690690
{
691-
ArgKind::Tuple(
691+
Some(ArgKind::Tuple(
692692
Some(span),
693693
args.iter()
694694
.map(|pat| {
695-
let snippet = self
696-
.tcx
697-
.sess
698-
.source_map()
699-
.span_to_snippet(pat.span)
700-
.unwrap();
701-
(snippet, "_".to_owned())
695+
sm.span_to_snippet(pat.span)
696+
.ok()
697+
.map(|snippet| (snippet, "_".to_owned()))
702698
})
703-
.collect::<Vec<_>>(),
704-
)
699+
.collect::<Option<Vec<_>>>()?,
700+
))
705701
} else {
706-
let name =
707-
self.tcx.sess.source_map().span_to_snippet(arg.pat.span).unwrap();
708-
ArgKind::Arg(name, "_".to_owned())
702+
let name = sm.span_to_snippet(arg.pat.span).ok()?;
703+
Some(ArgKind::Arg(name, "_".to_owned()))
709704
}
710705
})
711-
.collect::<Vec<ArgKind>>(),
706+
.collect::<Option<Vec<ArgKind>>>()?,
712707
),
713708
Node::Item(&hir::Item { span, kind: hir::ItemKind::Fn(ref sig, ..), .. })
714709
| Node::ImplItem(&hir::ImplItem {
@@ -721,7 +716,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
721716
kind: hir::TraitItemKind::Fn(ref sig, _),
722717
..
723718
}) => (
724-
self.tcx.sess.source_map().guess_head_span(span),
719+
sm.guess_head_span(span),
725720
sig.decl
726721
.inputs
727722
.iter()
@@ -735,16 +730,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
735730
.collect::<Vec<ArgKind>>(),
736731
),
737732
Node::Ctor(ref variant_data) => {
738-
let span = variant_data
739-
.ctor_hir_id()
740-
.map(|hir_id| self.tcx.hir().span(hir_id))
741-
.unwrap_or(DUMMY_SP);
742-
let span = self.tcx.sess.source_map().guess_head_span(span);
743-
733+
let span = variant_data.ctor_hir_id().map(|id| hir.span(id)).unwrap_or(DUMMY_SP);
734+
let span = sm.guess_head_span(span);
744735
(span, vec![ArgKind::empty(); variant_data.fields().len()])
745736
}
746737
_ => panic!("non-FnLike node found: {:?}", node),
747-
}
738+
})
748739
}
749740

750741
/// Reports an error when the number of arguments needed by a

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+15-17
Original file line numberDiff line numberDiff line change
@@ -732,12 +732,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
732732
true
733733
};
734734

735+
let sm = self.tcx.sess.source_map();
735736
let (snippet, last_ty) =
736737
if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = (
737738
// Verify that we're dealing with a return `dyn Trait`
738739
ret_ty.span.overlaps(span),
739740
&ret_ty.kind,
740-
self.tcx.sess.source_map().span_to_snippet(ret_ty.span),
741+
sm.span_to_snippet(ret_ty.span),
741742
// If any of the return types does not conform to the trait, then we can't
742743
// suggest `impl Trait` nor trait objects, it is a type mismatch error.
743744
all_returns_conform_to_trait,
@@ -775,26 +776,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
775776
if is_object_safe {
776777
// Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
777778
// Get all the return values and collect their span and suggestion.
778-
let mut suggestions = visitor
779+
if let Some(mut suggestions) = visitor
779780
.returns
780781
.iter()
781782
.map(|expr| {
782-
(
783-
expr.span,
784-
format!(
785-
"Box::new({})",
786-
self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap()
787-
),
788-
)
783+
let snip = sm.span_to_snippet(expr.span).ok()?;
784+
Some((expr.span, format!("Box::new({})", snip)))
789785
})
790-
.collect::<Vec<_>>();
791-
// Add the suggestion for the return type.
792-
suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
793-
err.multipart_suggestion(
794-
"return a boxed trait object instead",
795-
suggestions,
796-
Applicability::MaybeIncorrect,
797-
);
786+
.collect::<Option<Vec<_>>>()
787+
{
788+
// Add the suggestion for the return type.
789+
suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
790+
err.multipart_suggestion(
791+
"return a boxed trait object instead",
792+
suggestions,
793+
Applicability::MaybeIncorrect,
794+
);
795+
}
798796
} else {
799797
// This is currently not possible to trigger because E0038 takes precedence, but
800798
// leave it in for completeness in case anything changes in an earlier stage.

src/librustc_typeck/check/closure.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -432,18 +432,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
432432
body: &hir::Body<'_>,
433433
expected_sig: ExpectedSig<'tcx>,
434434
) -> ClosureSignatures<'tcx> {
435-
let expr_map_node = self.tcx.hir().get_if_local(expr_def_id).unwrap();
435+
let hir = self.tcx.hir();
436+
let expr_map_node = hir.get_if_local(expr_def_id).unwrap();
436437
let expected_args: Vec<_> = expected_sig
437438
.sig
438439
.inputs()
439440
.iter()
440441
.map(|ty| ArgKind::from_expected_ty(ty, None))
441442
.collect();
442-
let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node);
443-
let expected_span = expected_sig.cause_span.unwrap_or(closure_span);
443+
let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
444+
Some((sp, args)) => (Some(sp), args),
445+
None => (None, Vec::new()),
446+
};
447+
let expected_span =
448+
expected_sig.cause_span.unwrap_or_else(|| hir.span_if_local(expr_def_id).unwrap());
444449
self.report_arg_count_mismatch(
445450
expected_span,
446-
Some(closure_span),
451+
closure_span,
447452
expected_args,
448453
found_args,
449454
true,

src/librustc_typeck/check/op.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
481481
}
482482

483483
/// If one of the types is an uncalled function and calling it would yield the other type,
484-
/// suggest calling the function. Returns whether a suggestion was given.
484+
/// suggest calling the function. Returns `true` if suggestion would apply (even if not given).
485485
fn add_type_neq_err_label(
486486
&self,
487487
err: &mut rustc_errors::DiagnosticBuilder<'_>,
@@ -514,24 +514,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
514514
.lookup_op_method(fn_sig.output(), &[other_ty], Op::Binary(op, is_assign))
515515
.is_ok()
516516
{
517-
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
518-
(
519-
format!("{}( /* arguments */ )", source_map.span_to_snippet(span).unwrap()),
520-
Applicability::HasPlaceholders,
521-
)
522-
} else {
523-
(
524-
format!("{}()", source_map.span_to_snippet(span).unwrap()),
525-
Applicability::MaybeIncorrect,
526-
)
527-
};
517+
if let Ok(snippet) = source_map.span_to_snippet(span) {
518+
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
519+
(format!("{}( /* arguments */ )", snippet), Applicability::HasPlaceholders)
520+
} else {
521+
(format!("{}()", snippet), Applicability::MaybeIncorrect)
522+
};
528523

529-
err.span_suggestion(
530-
span,
531-
"you might have forgotten to call this function",
532-
variable_snippet,
533-
applicability,
534-
);
524+
err.span_suggestion(
525+
span,
526+
"you might have forgotten to call this function",
527+
variable_snippet,
528+
applicability,
529+
);
530+
}
535531
return true;
536532
}
537533
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn a() -> i32 {
2+
3
3+
}
4+
5+
pub fn main() {
6+
assert_eq!(a, 0);
7+
//~^ ERROR binary operation `==` cannot
8+
//~| ERROR mismatched types
9+
//~| ERROR doesn't implement
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0369]: binary operation `==` cannot be applied to type `fn() -> i32 {a}`
2+
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
3+
|
4+
LL | assert_eq!(a, 0);
5+
| ^^^^^^^^^^^^^^^^^
6+
| |
7+
| fn() -> i32 {a}
8+
| {integer}
9+
| help: you might have forgotten to call this function: `*left_val()`
10+
|
11+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
15+
|
16+
LL | assert_eq!(a, 0);
17+
| ^^^^^^^^^^^^^^^^^ expected fn item, found integer
18+
|
19+
= note: expected fn item `fn() -> i32 {a}`
20+
found type `i32`
21+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
22+
23+
error[E0277]: `fn() -> i32 {a}` doesn't implement `std::fmt::Debug`
24+
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
25+
|
26+
LL | fn a() -> i32 {
27+
| - consider calling this function
28+
...
29+
LL | assert_eq!(a, 0);
30+
| ^^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
31+
|
32+
= help: the trait `std::fmt::Debug` is not implemented for `fn() -> i32 {a}`
33+
= help: use parentheses to call the function: `a()`
34+
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn() -> i32 {a}`
35+
= note: required by `std::fmt::Debug::fmt`
36+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
37+
38+
error: aborting due to 3 previous errors
39+
40+
Some errors have detailed explanations: E0277, E0308, E0369.
41+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)