Detect negative literal inferred to unsigned integer
```
error[E0277]: the trait bound `usize: Neg` is not satisfied
--> $DIR/negative-literal-infered-to-unsigned.rs:2:14
|
LL | for x in -5..5 {
| ^^ the trait `Neg` is not implemented for `usize`
|
help: consider specifying an integer type that can be negative
|
LL | for x in -5isize..5 {
| +++++
```
This commit is contained in:
parent
fe55364329
commit
18a36bccf5
3 changed files with 78 additions and 1 deletions
|
|
@ -3,7 +3,8 @@ use std::borrow::Cow;
|
|||
use std::path::PathBuf;
|
||||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::TraitObjectSyntax;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_ast::{LitIntType, TraitObjectSyntax};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::codes::*;
|
||||
|
|
@ -280,6 +281,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
(suggested, noted_missing_impl) = self.try_conversion_context(&obligation, main_trait_predicate, &mut err);
|
||||
}
|
||||
|
||||
suggested |= self.detect_negative_literal(
|
||||
&obligation,
|
||||
main_trait_predicate,
|
||||
&mut err,
|
||||
);
|
||||
|
||||
if let Some(ret_span) = self.return_type_span(&obligation) {
|
||||
if is_try_conversion {
|
||||
let ty = self.tcx.short_string(
|
||||
|
|
@ -950,6 +957,38 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn detect_negative_literal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
) -> bool {
|
||||
if let ObligationCauseCode::BinOp { lhs_hir_id, .. } = obligation.cause.code()
|
||||
&& let hir::Node::Expr(expr) = self.tcx.hir_node(*lhs_hir_id)
|
||||
&& let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = expr.kind
|
||||
&& let hir::ExprKind::Lit(lit) = inner.kind
|
||||
&& let LitKind::Int(_, LitIntType::Unsuffixed) = lit.node
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
lit.span.shrink_to_hi(),
|
||||
"consider specifying an integer type that can be negative",
|
||||
match trait_pred.skip_binder().self_ty().kind() {
|
||||
ty::Uint(ty::UintTy::Usize) => "isize",
|
||||
ty::Uint(ty::UintTy::U8) => "i8",
|
||||
ty::Uint(ty::UintTy::U16) => "i16",
|
||||
ty::Uint(ty::UintTy::U32) => "i32",
|
||||
ty::Uint(ty::UintTy::U64) => "i64",
|
||||
ty::Uint(ty::UintTy::U128) => "i128",
|
||||
_ => "i64",
|
||||
}
|
||||
.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// When the `E` of the resulting `Result<T, E>` in an expression `foo().bar().baz()?`,
|
||||
/// identify those method chain sub-expressions that could or could not have been annotated
|
||||
/// with `?`.
|
||||
|
|
|
|||
13
tests/ui/suggestions/negative-literal-infered-to-unsigned.rs
Normal file
13
tests/ui/suggestions/negative-literal-infered-to-unsigned.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
fn main() {
|
||||
for x in -5..5 {
|
||||
//~^ ERROR: the trait bound `usize: Neg` is not satisfied
|
||||
//~| HELP: consider specifying an integer type that can be negative
|
||||
do_something(x);
|
||||
}
|
||||
let x = -5;
|
||||
//~^ ERROR: the trait bound `usize: Neg` is not satisfied
|
||||
//~| HELP: consider specifying an integer type that can be negative
|
||||
do_something(x);
|
||||
}
|
||||
|
||||
fn do_something(_val: usize) {}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
error[E0277]: the trait bound `usize: Neg` is not satisfied
|
||||
--> $DIR/negative-literal-infered-to-unsigned.rs:2:14
|
||||
|
|
||||
LL | for x in -5..5 {
|
||||
| ^^ the trait `Neg` is not implemented for `usize`
|
||||
|
|
||||
help: consider specifying an integer type that can be negative
|
||||
|
|
||||
LL | for x in -5isize..5 {
|
||||
| +++++
|
||||
|
||||
error[E0277]: the trait bound `usize: Neg` is not satisfied
|
||||
--> $DIR/negative-literal-infered-to-unsigned.rs:7:13
|
||||
|
|
||||
LL | let x = -5;
|
||||
| ^^ the trait `Neg` is not implemented for `usize`
|
||||
|
|
||||
help: consider specifying an integer type that can be negative
|
||||
|
|
||||
LL | let x = -5isize;
|
||||
| +++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue