Skip to content

Commit e19d82f

Browse files
committed
review comments
1 parent 5c70f25 commit e19d82f

File tree

2 files changed

+41
-37
lines changed

2 files changed

+41
-37
lines changed

compiler/rustc_typeck/src/check/place_op.rs

+38-34
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4949
expr: &hir::Expr<'_>,
5050
base_expr: &'tcx hir::Expr<'tcx>,
5151
base_ty: Ty<'tcx>,
52-
idx_expr: &'tcx hir::Expr<'tcx>,
52+
index_expr: &'tcx hir::Expr<'tcx>,
5353
idx_ty: Ty<'tcx>,
5454
) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
5555
// FIXME(#18741) -- this is almost but not quite the same as the
@@ -59,12 +59,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5959
let mut autoderef = self.autoderef(base_expr.span, base_ty);
6060
let mut result = None;
6161
while result.is_none() && autoderef.next().is_some() {
62-
result = self.try_index_step(expr, base_expr, &autoderef, idx_ty, idx_expr);
62+
result = self.try_index_step(expr, base_expr, &autoderef, idx_ty, index_expr);
6363
}
6464
self.register_predicates(autoderef.into_obligations());
6565
result
6666
}
6767

68+
fn negative_index(
69+
&self,
70+
ty: Ty<'tcx>,
71+
span: Span,
72+
base_expr: &hir::Expr<'_>,
73+
) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
74+
let ty = self.resolve_vars_if_possible(ty);
75+
let mut err = self.tcx.sess.struct_span_err(
76+
span,
77+
&format!("negative integers cannot be used to index on a `{}`", ty),
78+
);
79+
err.span_label(span, &format!("cannot use a negative integer for indexing on `{}`", ty));
80+
if let (hir::ExprKind::Path(..), Ok(snippet)) =
81+
(&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
82+
{
83+
// `foo[-1]` to `foo[foo.len() - 1]`
84+
err.span_suggestion_verbose(
85+
span.shrink_to_lo(),
86+
&format!(
87+
"to access an element starting from the end of the `{}`, compute the index",
88+
ty,
89+
),
90+
format!("{}.len() ", snippet),
91+
Applicability::MachineApplicable,
92+
);
93+
}
94+
err.emit();
95+
Some((self.tcx.ty_error(), self.tcx.ty_error()))
96+
}
97+
6898
/// To type-check `base_expr[index_expr]`, we progressively autoderef
6999
/// (and otherwise adjust) `base_expr`, looking for a type which either
70100
/// supports builtin indexing or overloaded indexing.
@@ -76,7 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
76106
base_expr: &hir::Expr<'_>,
77107
autoderef: &Autoderef<'a, 'tcx>,
78108
index_ty: Ty<'tcx>,
79-
idx_expr: &hir::Expr<'_>,
109+
index_expr: &hir::Expr<'_>,
80110
) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
81111
let adjusted_ty =
82112
self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
@@ -86,49 +116,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
86116
expr, base_expr, adjusted_ty, index_ty
87117
);
88118

89-
let negative_index = || {
90-
let ty = self.resolve_vars_if_possible(adjusted_ty);
91-
let mut err = self.tcx.sess.struct_span_err(
92-
idx_expr.span,
93-
&format!("negative integers cannot be used to index on a `{}`", ty),
94-
);
95-
err.span_label(
96-
idx_expr.span,
97-
&format!("cannot use a negative integer for indexing on `{}`", ty),
98-
);
99-
if let (hir::ExprKind::Path(..), Ok(snippet)) =
100-
(&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
101-
{
102-
// `foo[-1]` to `foo[foo.len() - 1]`
103-
err.span_suggestion_verbose(
104-
idx_expr.span.shrink_to_lo(),
105-
&format!(
106-
"if you wanted to access an element starting from the end of the `{}`, you \
107-
must compute it",
108-
ty,
109-
),
110-
format!("{}.len() ", snippet),
111-
Applicability::MachineApplicable,
112-
);
113-
}
114-
err.emit();
115-
Some((self.tcx.ty_error(), self.tcx.ty_error()))
116-
};
117119
if let hir::ExprKind::Unary(
118120
hir::UnOp::Neg,
119121
hir::Expr {
120122
kind: hir::ExprKind::Lit(hir::Lit { node: ast::LitKind::Int(..), .. }),
121123
..
122124
},
123-
) = idx_expr.kind
125+
) = index_expr.kind
124126
{
125127
match adjusted_ty.kind() {
126128
ty::Adt(ty::AdtDef { did, .. }, _)
127129
if self.tcx.is_diagnostic_item(sym::vec_type, *did) =>
128130
{
129-
return negative_index();
131+
return self.negative_index(adjusted_ty, index_expr.span, base_expr);
132+
}
133+
ty::Slice(_) | ty::Array(_, _) => {
134+
return self.negative_index(adjusted_ty, index_expr.span, base_expr);
130135
}
131-
ty::Slice(_) | ty::Array(_, _) => return negative_index(),
132136
_ => {}
133137
}
134138
}

src/test/ui/suggestions/negative-literal-index.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: negative integers cannot be used to index on a `Vec<{integer}>`
44
LL | x[-1];
55
| ^^ cannot use a negative integer for indexing on `Vec<{integer}>`
66
|
7-
help: if you wanted to access an element starting from the end of the `Vec<{integer}>`, you must compute it
7+
help: to access an element starting from the end of the `Vec<{integer}>`, compute the index
88
|
99
LL | x[x.len() -1];
1010
| +++++++
@@ -15,7 +15,7 @@ error: negative integers cannot be used to index on a `[{integer}; 3]`
1515
LL | x[-1];
1616
| ^^ cannot use a negative integer for indexing on `[{integer}; 3]`
1717
|
18-
help: if you wanted to access an element starting from the end of the `[{integer}; 3]`, you must compute it
18+
help: to access an element starting from the end of the `[{integer}; 3]`, compute the index
1919
|
2020
LL | x[x.len() -1];
2121
| +++++++
@@ -26,7 +26,7 @@ error: negative integers cannot be used to index on a `[{integer}; 3]`
2626
LL | x[-1];
2727
| ^^ cannot use a negative integer for indexing on `[{integer}; 3]`
2828
|
29-
help: if you wanted to access an element starting from the end of the `[{integer}; 3]`, you must compute it
29+
help: to access an element starting from the end of the `[{integer}; 3]`, compute the index
3030
|
3131
LL | x[x.len() -1];
3232
| +++++++

0 commit comments

Comments
 (0)