Auto merge of #114481 - matthiaskrgr:rollup-58pczpl, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #113945 (Fix wrong span for trait selection failure error reporting) - #114351 ([rustc_span][perf] Remove unnecessary string joins and allocs.) - #114418 (bump parking_lot to 0.12) - #114434 (Improve spans for indexing expressions) - #114450 (Fix ICE failed to get layout for ReferencesError) - #114461 (Fix unwrap on None) - #114462 (interpret: add mplace_to_ref helper method) - #114472 (Reword `confusable_idents` lint) - #114477 (Account for `Rc` and `Arc` when suggesting to clone) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e4c1446846
111 changed files with 466 additions and 202 deletions
|
@ -3469,7 +3469,7 @@ dependencies = [
|
|||
"libc",
|
||||
"measureme",
|
||||
"memmap2",
|
||||
"parking_lot 0.11.2",
|
||||
"parking_lot 0.12.1",
|
||||
"rustc-hash",
|
||||
"rustc-rayon",
|
||||
"rustc-rayon-core",
|
||||
|
@ -4190,7 +4190,7 @@ dependencies = [
|
|||
name = "rustc_query_system"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"parking_lot 0.11.2",
|
||||
"parking_lot 0.12.1",
|
||||
"rustc-rayon-core",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
|
|
|
@ -1462,7 +1462,8 @@ pub enum ExprKind {
|
|||
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
|
||||
Field(P<Expr>, Ident),
|
||||
/// An indexing operation (e.g., `foo[2]`).
|
||||
Index(P<Expr>, P<Expr>),
|
||||
/// The span represents the span of the `[2]`, including brackets.
|
||||
Index(P<Expr>, P<Expr>, Span),
|
||||
/// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
|
||||
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
|
||||
/// An underscore, used in destructuring assignment to ignore a value.
|
||||
|
|
|
@ -1400,7 +1400,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
fn_arg_span: _,
|
||||
fn_arg_span,
|
||||
}) => {
|
||||
vis.visit_closure_binder(binder);
|
||||
visit_constness(constness, vis);
|
||||
|
@ -1408,6 +1408,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
vis.visit_fn_decl(fn_decl);
|
||||
vis.visit_expr(body);
|
||||
vis.visit_span(fn_decl_span);
|
||||
vis.visit_span(fn_arg_span);
|
||||
}
|
||||
ExprKind::Block(blk, label) => {
|
||||
vis.visit_block(blk);
|
||||
|
@ -1420,9 +1421,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
vis.visit_expr(expr);
|
||||
vis.visit_span(await_kw_span);
|
||||
}
|
||||
ExprKind::Assign(el, er, _) => {
|
||||
ExprKind::Assign(el, er, span) => {
|
||||
vis.visit_expr(el);
|
||||
vis.visit_expr(er);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
ExprKind::AssignOp(_op, el, er) => {
|
||||
vis.visit_expr(el);
|
||||
|
@ -1432,9 +1434,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
vis.visit_expr(el);
|
||||
vis.visit_ident(ident);
|
||||
}
|
||||
ExprKind::Index(el, er) => {
|
||||
ExprKind::Index(el, er, brackets_span) => {
|
||||
vis.visit_expr(el);
|
||||
vis.visit_expr(er);
|
||||
vis.visit_span(brackets_span);
|
||||
}
|
||||
ExprKind::Range(e1, e2, _lim) => {
|
||||
visit_opt(e1, |e1| vis.visit_expr(e1));
|
||||
|
|
|
@ -390,7 +390,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
|
|||
| ast::ExprKind::Cast(x, _)
|
||||
| ast::ExprKind::Type(x, _)
|
||||
| ast::ExprKind::Field(x, _)
|
||||
| ast::ExprKind::Index(x, _) => {
|
||||
| ast::ExprKind::Index(x, _, _) => {
|
||||
// &X { y: 1 }, X { y: 1 }.y
|
||||
contains_exterior_struct_lit(x)
|
||||
}
|
||||
|
|
|
@ -885,7 +885,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
|||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_ident(*ident);
|
||||
}
|
||||
ExprKind::Index(main_expression, index_expression) => {
|
||||
ExprKind::Index(main_expression, index_expression, _) => {
|
||||
visitor.visit_expr(main_expression);
|
||||
visitor.visit_expr(index_expression)
|
||||
}
|
||||
|
|
|
@ -240,8 +240,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ExprKind::Field(el, ident) => {
|
||||
hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident))
|
||||
}
|
||||
ExprKind::Index(el, er) => {
|
||||
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er))
|
||||
ExprKind::Index(el, er, brackets_span) => {
|
||||
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span)
|
||||
}
|
||||
ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
|
||||
self.lower_expr_range_closed(e.span, e1, e2)
|
||||
|
|
|
@ -477,7 +477,7 @@ impl<'a> State<'a> {
|
|||
self.word(".");
|
||||
self.print_ident(*ident);
|
||||
}
|
||||
ast::ExprKind::Index(expr, index) => {
|
||||
ast::ExprKind::Index(expr, index, _) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word("[");
|
||||
self.print_expr(index);
|
||||
|
|
|
@ -751,9 +751,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
let msg = if let ty::Adt(def, _) = ty.kind()
|
||||
&& [
|
||||
tcx.get_diagnostic_item(sym::Arc),
|
||||
tcx.get_diagnostic_item(sym::Rc),
|
||||
].contains(&Some(def.did()))
|
||||
{
|
||||
"clone the value to increment its reference count"
|
||||
} else {
|
||||
"consider cloning the value if the performance cost is acceptable"
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
"consider cloning the value if the performance cost is acceptable",
|
||||
msg,
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
|
@ -79,7 +79,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
| hir::ExprKind::Unary(hir::UnOp::Deref, inner)
|
||||
| hir::ExprKind::Field(inner, _)
|
||||
| hir::ExprKind::MethodCall(_, inner, _, _)
|
||||
| hir::ExprKind::Index(inner, _) = &expr.kind
|
||||
| hir::ExprKind::Index(inner, _, _) = &expr.kind
|
||||
{
|
||||
expr = inner;
|
||||
}
|
||||
|
|
|
@ -567,7 +567,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
};
|
||||
if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
|
||||
&& let hir::ExprKind::Index(val, index) = place.kind
|
||||
&& let hir::ExprKind::Index(val, index, _) = place.kind
|
||||
&& (expr.span == self.assign_span || place.span == self.assign_span)
|
||||
{
|
||||
// val[index] = rv;
|
||||
|
@ -620,7 +620,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
);
|
||||
self.suggested = true;
|
||||
} else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
|
||||
&& let hir::ExprKind::Index(val, index) = receiver.kind
|
||||
&& let hir::ExprKind::Index(val, index, _) = receiver.kind
|
||||
&& expr.span == self.assign_span
|
||||
{
|
||||
// val[index].path(args..);
|
||||
|
|
|
@ -237,7 +237,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||
ExprKind::If(local_expr, _, _) => {
|
||||
self.manage_cond_expr(local_expr);
|
||||
}
|
||||
ExprKind::Index(prefix, suffix) => {
|
||||
ExprKind::Index(prefix, suffix, _) => {
|
||||
self.manage_cond_expr(prefix);
|
||||
self.manage_cond_expr(suffix);
|
||||
}
|
||||
|
|
|
@ -477,7 +477,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
|||
|
||||
#[inline]
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
||||
if let layout::LayoutError::SizeOverflow(_) = err {
|
||||
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||
self.0.sess.span_fatal(span, err.to_string())
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
||||
|
|
|
@ -476,7 +476,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
|
||||
#[inline]
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
||||
if let LayoutError::SizeOverflow(_) = err {
|
||||
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||
self.sess().emit_fatal(respan(span, err.into_diagnostic()))
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
||||
|
|
|
@ -985,7 +985,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
|
|||
|
||||
#[inline]
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
||||
if let LayoutError::SizeOverflow(_) = err {
|
||||
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||
self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() })
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{ty}`: {err:?}")
|
||||
|
|
|
@ -157,7 +157,6 @@ impl<Prov: Provenance> MemPlace<Prov> {
|
|||
}
|
||||
|
||||
/// Turn a mplace into a (thin or wide) pointer, as a reference, pointing to the same space.
|
||||
/// This is the inverse of `ref_to_mplace`.
|
||||
#[inline(always)]
|
||||
pub fn to_ref(self, cx: &impl HasDataLayout) -> Immediate<Prov> {
|
||||
match self.meta {
|
||||
|
@ -415,7 +414,7 @@ where
|
|||
}
|
||||
|
||||
/// Take a value, which represents a (thin or wide) reference, and make it a place.
|
||||
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
||||
/// Alignment is just based on the type. This is the inverse of `mplace_to_ref()`.
|
||||
///
|
||||
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
|
||||
/// want to ever use the place for memory access!
|
||||
|
@ -438,6 +437,18 @@ where
|
|||
Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.to_pointer(self)?, layout, meta))
|
||||
}
|
||||
|
||||
/// Turn a mplace into a (thin or wide) mutable raw pointer, pointing to the same space.
|
||||
/// `align` information is lost!
|
||||
/// This is the inverse of `ref_to_mplace`.
|
||||
pub fn mplace_to_ref(
|
||||
&self,
|
||||
mplace: &MPlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
||||
let imm = mplace.to_ref(self);
|
||||
let layout = self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, mplace.layout.ty))?;
|
||||
Ok(ImmTy::from_immediate(imm, layout))
|
||||
}
|
||||
|
||||
/// Take an operand, representing a pointer, and dereference it to a place.
|
||||
/// Corresponds to the `*` operator in Rust.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
|
|
@ -852,10 +852,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let instance = ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
|
||||
|
||||
let arg = ImmTy::from_immediate(
|
||||
place.to_ref(self),
|
||||
self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, place.layout.ty))?,
|
||||
);
|
||||
let arg = self.mplace_to_ref(&place)?;
|
||||
let ret = MPlaceTy::fake_alloc_zst(self.layout_of(self.tcx.types.unit)?);
|
||||
|
||||
self.eval_fn_call(
|
||||
|
|
|
@ -35,7 +35,7 @@ elsa = "=1.7.1"
|
|||
itertools = "0.10.1"
|
||||
|
||||
[dependencies.parking_lot]
|
||||
version = "0.11"
|
||||
version = "0.12"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows]
|
||||
version = "0.48.0"
|
||||
|
|
|
@ -1754,7 +1754,7 @@ impl Expr<'_> {
|
|||
|
||||
ExprKind::Unary(UnOp::Deref, _) => true,
|
||||
|
||||
ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _) => {
|
||||
ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
|
||||
allow_projections_from(base) || base.is_place_expr(allow_projections_from)
|
||||
}
|
||||
|
||||
|
@ -1831,7 +1831,7 @@ impl Expr<'_> {
|
|||
ExprKind::Type(base, _)
|
||||
| ExprKind::Unary(_, base)
|
||||
| ExprKind::Field(base, _)
|
||||
| ExprKind::Index(base, _)
|
||||
| ExprKind::Index(base, _, _)
|
||||
| ExprKind::AddrOf(.., base)
|
||||
| ExprKind::Cast(base, _) => {
|
||||
// This isn't exactly true for `Index` and all `Unary`, but we are using this
|
||||
|
@ -2015,7 +2015,9 @@ pub enum ExprKind<'hir> {
|
|||
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
|
||||
Field(&'hir Expr<'hir>, Ident),
|
||||
/// An indexing operation (`foo[2]`).
|
||||
Index(&'hir Expr<'hir>, &'hir Expr<'hir>),
|
||||
/// Similar to [`ExprKind::MethodCall`], the final `Span` represents the span of the brackets
|
||||
/// and index.
|
||||
Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
|
||||
|
||||
/// Path to a definition, possibly containing lifetime or type parameters.
|
||||
Path(QPath<'hir>),
|
||||
|
|
|
@ -780,7 +780,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
|
|||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_ident(ident);
|
||||
}
|
||||
ExprKind::Index(ref main_expression, ref index_expression) => {
|
||||
ExprKind::Index(ref main_expression, ref index_expression, _) => {
|
||||
visitor.visit_expr(main_expression);
|
||||
visitor.visit_expr(index_expression)
|
||||
}
|
||||
|
|
|
@ -1526,7 +1526,7 @@ impl<'a> State<'a> {
|
|||
self.word(".");
|
||||
self.print_ident(ident);
|
||||
}
|
||||
hir::ExprKind::Index(expr, index) => {
|
||||
hir::ExprKind::Index(expr, index, _) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word("[");
|
||||
self.print_expr(index);
|
||||
|
@ -2419,7 +2419,7 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
|
|||
| hir::ExprKind::Cast(x, _)
|
||||
| hir::ExprKind::Type(x, _)
|
||||
| hir::ExprKind::Field(x, _)
|
||||
| hir::ExprKind::Index(x, _) => {
|
||||
| hir::ExprKind::Index(x, _, _) => {
|
||||
// `&X { y: 1 }, X { y: 1 }.y`
|
||||
contains_exterior_struct_lit(x)
|
||||
}
|
||||
|
|
|
@ -345,7 +345,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.check_expr_struct(expr, expected, qpath, fields, base_expr)
|
||||
}
|
||||
ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected),
|
||||
ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr),
|
||||
ExprKind::Index(base, idx, brackets_span) => {
|
||||
self.check_expr_index(base, idx, expr, brackets_span)
|
||||
}
|
||||
ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src),
|
||||
hir::ExprKind::Err(guar) => Ty::new_error(tcx, guar),
|
||||
}
|
||||
|
@ -2840,6 +2842,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
base: &'tcx hir::Expr<'tcx>,
|
||||
idx: &'tcx hir::Expr<'tcx>,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
brackets_span: Span,
|
||||
) -> Ty<'tcx> {
|
||||
let base_t = self.check_expr(&base);
|
||||
let idx_t = self.check_expr(&idx);
|
||||
|
@ -2873,7 +2876,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
let mut err = type_error_struct!(
|
||||
self.tcx.sess,
|
||||
expr.span,
|
||||
brackets_span,
|
||||
base_t,
|
||||
E0608,
|
||||
"cannot index into a value of type `{base_t}`",
|
||||
|
@ -2887,16 +2890,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&& let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
|
||||
&& i < types.len().try_into().expect("expected tuple index to be < usize length")
|
||||
{
|
||||
let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
|
||||
if let Ok(snip) = snip {
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
"to access tuple elements, use",
|
||||
format!("{snip}.{i}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
needs_note = false;
|
||||
}
|
||||
|
||||
err.span_suggestion(
|
||||
brackets_span,
|
||||
"to access tuple elements, use",
|
||||
format!(".{i}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
needs_note = false;
|
||||
} else if let ExprKind::Path(..) = idx.peel_borrows().kind {
|
||||
err.span_label(idx.span, "cannot access tuple elements at a variable index");
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
self.select_from_expr(base);
|
||||
}
|
||||
|
||||
hir::ExprKind::Index(lhs, rhs) => {
|
||||
hir::ExprKind::Index(lhs, rhs, _) => {
|
||||
// lhs[rhs]
|
||||
self.select_from_expr(lhs);
|
||||
self.consume_expr(rhs);
|
||||
|
|
|
@ -1620,8 +1620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.filter(|x| x.1.hir_id == *hir_id)
|
||||
.map(|(i, _)| init_tup.get(i).unwrap())
|
||||
.next()
|
||||
.find_map(|(i, _)| init_tup.get(i))
|
||||
{
|
||||
self.note_type_is_not_clone_inner_expr(init)
|
||||
} else {
|
||||
|
|
|
@ -332,7 +332,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
))
|
||||
}
|
||||
|
||||
hir::ExprKind::Index(ref base, _) => {
|
||||
hir::ExprKind::Index(ref base, _, _) => {
|
||||
if self.typeck_results.is_method_call(expr) {
|
||||
// If this is an index implemented by a method call, then it
|
||||
// will include an implicit deref of the result.
|
||||
|
|
|
@ -284,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let mut exprs = vec![expr];
|
||||
|
||||
while let hir::ExprKind::Field(ref expr, _)
|
||||
| hir::ExprKind::Index(ref expr, _)
|
||||
| hir::ExprKind::Index(ref expr, _, _)
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, ref expr) = exprs.last().unwrap().kind
|
||||
{
|
||||
exprs.push(expr);
|
||||
|
|
|
@ -40,7 +40,7 @@ fn record_rvalue_scope_rec(
|
|||
hir::ExprKind::AddrOf(_, _, subexpr)
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, subexpr)
|
||||
| hir::ExprKind::Field(subexpr, _)
|
||||
| hir::ExprKind::Index(subexpr, _) => {
|
||||
| hir::ExprKind::Index(subexpr, _, _) => {
|
||||
expr = subexpr;
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -210,7 +210,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
// to use builtin indexing because the index type is known to be
|
||||
// usize-ish
|
||||
fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
|
||||
if let hir::ExprKind::Index(ref base, ref index) = e.kind {
|
||||
if let hir::ExprKind::Index(ref base, ref index, _) = e.kind {
|
||||
// All valid indexing looks like this; might encounter non-valid indexes at this point.
|
||||
let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
|
||||
if base_ty.is_none() {
|
||||
|
|
|
@ -167,8 +167,9 @@ lint_check_name_warning = {$msg}
|
|||
|
||||
lint_command_line_source = `forbid` lint level was set on command line
|
||||
|
||||
lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
|
||||
.label = this is where the previous identifier occurred
|
||||
lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike
|
||||
.current_use = this identifier can be confused with `{$existing_sym}`
|
||||
.other_use = other identifier used here
|
||||
|
||||
lint_cstring_ptr = getting the inner pointer of a temporary `CString`
|
||||
.as_ptr_label = this pointer will be invalid
|
||||
|
|
|
@ -1083,8 +1083,10 @@ pub struct IdentifierUncommonCodepoints;
|
|||
pub struct ConfusableIdentifierPair {
|
||||
pub existing_sym: Symbol,
|
||||
pub sym: Symbol,
|
||||
#[label]
|
||||
#[label(lint_other_use)]
|
||||
pub label: Span,
|
||||
#[label(lint_current_use)]
|
||||
pub main_label: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
|
|
@ -222,6 +222,7 @@ impl EarlyLintPass for NonAsciiIdents {
|
|||
existing_sym: *existing_symbol,
|
||||
sym: symbol,
|
||||
label: *existing_span,
|
||||
main_label: sp,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -653,7 +653,7 @@ trait UnusedDelimLint {
|
|||
ExprKind::Call(fn_, _params) => fn_,
|
||||
ExprKind::Cast(expr, _ty) => expr,
|
||||
ExprKind::Type(expr, _ty) => expr,
|
||||
ExprKind::Index(base, _subscript) => base,
|
||||
ExprKind::Index(base, _subscript, _) => base,
|
||||
_ => break,
|
||||
};
|
||||
if !classify::expr_requires_semi_to_be_stmt(innermost) {
|
||||
|
@ -830,7 +830,7 @@ trait UnusedDelimLint {
|
|||
(value, UnusedDelimsCtx::ReturnValue, false, Some(left), None, true)
|
||||
}
|
||||
|
||||
Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
|
||||
Index(_, ref value, _) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
|
||||
|
||||
Assign(_, ref value, _) | AssignOp(.., ref value) => {
|
||||
(value, UnusedDelimsCtx::AssignedValue, false, None, None, false)
|
||||
|
|
|
@ -469,11 +469,17 @@ impl<'tcx> Cx<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
hir::ExprKind::Index(ref lhs, ref index) => {
|
||||
hir::ExprKind::Index(ref lhs, ref index, brackets_span) => {
|
||||
if self.typeck_results().is_method_call(expr) {
|
||||
let lhs = self.mirror_expr(lhs);
|
||||
let index = self.mirror_expr(index);
|
||||
self.overloaded_place(expr, expr_ty, None, Box::new([lhs, index]), expr.span)
|
||||
self.overloaded_place(
|
||||
expr,
|
||||
expr_ty,
|
||||
None,
|
||||
Box::new([lhs, index]),
|
||||
brackets_span,
|
||||
)
|
||||
} else {
|
||||
ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
|
||||
}
|
||||
|
|
|
@ -857,7 +857,7 @@ impl<'a> Parser<'a> {
|
|||
let msg = format!(
|
||||
"cast cannot be followed by {}",
|
||||
match with_postfix.kind {
|
||||
ExprKind::Index(_, _) => "indexing",
|
||||
ExprKind::Index(..) => "indexing",
|
||||
ExprKind::Try(_) => "`?`",
|
||||
ExprKind::Field(_, _) => "a field access",
|
||||
ExprKind::MethodCall(_) => "a method call",
|
||||
|
@ -1304,7 +1304,10 @@ impl<'a> Parser<'a> {
|
|||
let index = self.parse_expr()?;
|
||||
self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
|
||||
self.expect(&token::CloseDelim(Delimiter::Bracket))?;
|
||||
Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index)))
|
||||
Ok(self.mk_expr(
|
||||
lo.to(self.prev_token.span),
|
||||
self.mk_index(base, index, open_delim_span.to(self.prev_token.span)),
|
||||
))
|
||||
}
|
||||
|
||||
/// Assuming we have just parsed `.`, continue parsing into an expression.
|
||||
|
@ -3366,8 +3369,8 @@ impl<'a> Parser<'a> {
|
|||
ExprKind::Binary(binop, lhs, rhs)
|
||||
}
|
||||
|
||||
fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ExprKind {
|
||||
ExprKind::Index(expr, idx)
|
||||
fn mk_index(&self, expr: P<Expr>, idx: P<Expr>, brackets_span: Span) -> ExprKind {
|
||||
ExprKind::Index(expr, idx, brackets_span)
|
||||
}
|
||||
|
||||
fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind {
|
||||
|
|
|
@ -1061,7 +1061,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
self.propagate_through_expr(&l, ln)
|
||||
}
|
||||
|
||||
hir::ExprKind::Index(ref l, ref r) | hir::ExprKind::Binary(_, ref l, ref r) => {
|
||||
hir::ExprKind::Index(ref l, ref r, _) | hir::ExprKind::Binary(_, ref l, ref r) => {
|
||||
let r_succ = self.propagate_through_expr(&r, succ);
|
||||
self.propagate_through_expr(&l, r_succ)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||
[lib]
|
||||
|
||||
[dependencies]
|
||||
parking_lot = "0.11"
|
||||
parking_lot = "0.12"
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use parking_lot::Mutex;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::profiling::{EventId, QueryInvocationId, SelfProfilerRef};
|
||||
|
@ -88,7 +87,7 @@ pub struct DepGraphData<K: DepKind> {
|
|||
|
||||
colors: DepNodeColorMap,
|
||||
|
||||
processed_side_effects: Mutex<FxHashSet<DepNodeIndex>>,
|
||||
processed_side_effects: Lock<FxHashSet<DepNodeIndex>>,
|
||||
|
||||
/// When we load, there may be `.o` files, cached MIR, or other such
|
||||
/// things available to us. If we find that they are not dirty, we
|
||||
|
|
|
@ -21,12 +21,11 @@ use {
|
|||
parking_lot::{Condvar, Mutex},
|
||||
rayon_core,
|
||||
rustc_data_structures::fx::FxHashSet,
|
||||
rustc_data_structures::sync::Lock,
|
||||
rustc_data_structures::sync::Lrc,
|
||||
rustc_data_structures::{defer, jobserver},
|
||||
rustc_span::DUMMY_SP,
|
||||
std::iter,
|
||||
std::process,
|
||||
std::sync::Arc,
|
||||
};
|
||||
|
||||
/// Represents a span and a query key.
|
||||
|
@ -191,7 +190,7 @@ struct QueryWaiter<D: DepKind> {
|
|||
query: Option<QueryJobId>,
|
||||
condvar: Condvar,
|
||||
span: Span,
|
||||
cycle: Lock<Option<CycleError<D>>>,
|
||||
cycle: Mutex<Option<CycleError<D>>>,
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
|
@ -205,20 +204,20 @@ impl<D: DepKind> QueryWaiter<D> {
|
|||
#[cfg(parallel_compiler)]
|
||||
struct QueryLatchInfo<D: DepKind> {
|
||||
complete: bool,
|
||||
waiters: Vec<Lrc<QueryWaiter<D>>>,
|
||||
waiters: Vec<Arc<QueryWaiter<D>>>,
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
#[derive(Clone)]
|
||||
pub(super) struct QueryLatch<D: DepKind> {
|
||||
info: Lrc<Mutex<QueryLatchInfo<D>>>,
|
||||
info: Arc<Mutex<QueryLatchInfo<D>>>,
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
impl<D: DepKind> QueryLatch<D> {
|
||||
fn new() -> Self {
|
||||
QueryLatch {
|
||||
info: Lrc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })),
|
||||
info: Arc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,11 +228,11 @@ impl<D: DepKind> QueryLatch<D> {
|
|||
span: Span,
|
||||
) -> Result<(), CycleError<D>> {
|
||||
let waiter =
|
||||
Lrc::new(QueryWaiter { query, span, cycle: Lock::new(None), condvar: Condvar::new() });
|
||||
Arc::new(QueryWaiter { query, span, cycle: Mutex::new(None), condvar: Condvar::new() });
|
||||
self.wait_on_inner(&waiter);
|
||||
// FIXME: Get rid of this lock. We have ownership of the QueryWaiter
|
||||
// although another thread may still have a Lrc reference so we cannot
|
||||
// use Lrc::get_mut
|
||||
// although another thread may still have a Arc reference so we cannot
|
||||
// use Arc::get_mut
|
||||
let mut cycle = waiter.cycle.lock();
|
||||
match cycle.take() {
|
||||
None => Ok(()),
|
||||
|
@ -242,7 +241,7 @@ impl<D: DepKind> QueryLatch<D> {
|
|||
}
|
||||
|
||||
/// Awaits the caller on this latch by blocking the current thread.
|
||||
fn wait_on_inner(&self, waiter: &Lrc<QueryWaiter<D>>) {
|
||||
fn wait_on_inner(&self, waiter: &Arc<QueryWaiter<D>>) {
|
||||
let mut info = self.info.lock();
|
||||
if !info.complete {
|
||||
// We push the waiter on to the `waiters` list. It can be accessed inside
|
||||
|
@ -276,7 +275,7 @@ impl<D: DepKind> QueryLatch<D> {
|
|||
|
||||
/// Removes a single waiter from the list of waiters.
|
||||
/// This is used to break query cycles.
|
||||
fn extract_waiter(&self, waiter: usize) -> Lrc<QueryWaiter<D>> {
|
||||
fn extract_waiter(&self, waiter: usize) -> Arc<QueryWaiter<D>> {
|
||||
let mut info = self.info.lock();
|
||||
debug_assert!(!info.complete);
|
||||
// Remove the waiter from the list of waiters
|
||||
|
@ -428,7 +427,7 @@ where
|
|||
fn remove_cycle<D: DepKind>(
|
||||
query_map: &QueryMap<D>,
|
||||
jobs: &mut Vec<QueryJobId>,
|
||||
wakelist: &mut Vec<Lrc<QueryWaiter<D>>>,
|
||||
wakelist: &mut Vec<Arc<QueryWaiter<D>>>,
|
||||
) -> bool {
|
||||
let mut visited = FxHashSet::default();
|
||||
let mut stack = Vec::new();
|
||||
|
|
|
@ -4269,7 +4269,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
ExprKind::ConstBlock(ref ct) => {
|
||||
self.resolve_anon_const(ct, AnonConstKind::InlineConst);
|
||||
}
|
||||
ExprKind::Index(ref elem, ref idx) => {
|
||||
ExprKind::Index(ref elem, ref idx, _) => {
|
||||
self.resolve_expr(elem, Some(expr));
|
||||
self.visit_expr(idx);
|
||||
}
|
||||
|
|
|
@ -248,9 +248,9 @@ fn find_match_by_sorted_words(iter_names: &[Symbol], lookup: &str) -> Option<Sym
|
|||
})
|
||||
}
|
||||
|
||||
fn sort_by_words(name: &str) -> String {
|
||||
fn sort_by_words(name: &str) -> Vec<&str> {
|
||||
let mut split_words: Vec<&str> = name.split('_').collect();
|
||||
// We are sorting primitive &strs and can use unstable sort here.
|
||||
split_words.sort_unstable();
|
||||
split_words.join("_")
|
||||
split_words
|
||||
}
|
||||
|
|
|
@ -2987,6 +2987,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
unsatisfied_const: bool,
|
||||
) {
|
||||
let body_def_id = obligation.cause.body_id;
|
||||
let span = if let ObligationCauseCode::BinOp { rhs_span: Some(rhs_span), .. } =
|
||||
obligation.cause.code()
|
||||
{
|
||||
*rhs_span
|
||||
} else {
|
||||
span
|
||||
};
|
||||
|
||||
// Try to report a help message
|
||||
if is_fn_trait
|
||||
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
|
||||
|
|
|
@ -2854,7 +2854,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.note("all local variables must have a statically known size");
|
||||
}
|
||||
Some(Node::Local(hir::Local {
|
||||
init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }),
|
||||
init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
|
||||
..
|
||||
})) => {
|
||||
// When encountering an assignment of an unsized trait, like
|
||||
|
@ -3953,9 +3953,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
candidate_impls: &[ImplCandidate<'tcx>],
|
||||
span: Span,
|
||||
) {
|
||||
// We can only suggest the slice coersion for function arguments since the suggestion
|
||||
// would make no sense in turbofish or call
|
||||
let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
|
||||
// We can only suggest the slice coersion for function and binary operation arguments,
|
||||
// since the suggestion would make no sense in turbofish or call
|
||||
let (ObligationCauseCode::BinOp { .. }
|
||||
| ObligationCauseCode::FunctionArgumentObligation { .. }) = obligation.cause.code()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
@ -800,7 +800,7 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
|
|||
&& parent.span.ctxt() == e.span.ctxt()
|
||||
{
|
||||
match parent.kind {
|
||||
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _)
|
||||
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
|
||||
if child.hir_id == e.hir_id => true,
|
||||
ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true,
|
||||
_ => false,
|
||||
|
|
|
@ -221,7 +221,7 @@ fn is_mutated_static(e: &hir::Expr<'_>) -> bool {
|
|||
match e.kind {
|
||||
Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)),
|
||||
Path(_) => true,
|
||||
Field(inner, _) | Index(inner, _) => is_mutated_static(inner),
|
||||
Field(inner, _) | Index(inner, _, _) => is_mutated_static(inner),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
|
|||
// Checking for slice indexing
|
||||
let parent_id = map.parent_id(expr.hir_id);
|
||||
if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id);
|
||||
if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind;
|
||||
if let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind;
|
||||
if let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr);
|
||||
if let Ok(index_value) = index_value.try_into();
|
||||
if index_value < max_suggested_slice;
|
||||
|
|
|
@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
|
|||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Index(array, index) = &expr.kind {
|
||||
if let ExprKind::Index(array, index, _) = &expr.kind {
|
||||
let note = "the suggestion might not be applicable in constant blocks";
|
||||
let ty = cx.typeck_results().expr_ty(array).peel_refs();
|
||||
if let Some(range) = higher::Range::hir(index) {
|
||||
|
|
|
@ -60,8 +60,8 @@ pub(super) fn check<'tcx>(
|
|||
o.and_then(|(lhs, rhs)| {
|
||||
let rhs = fetch_cloned_expr(rhs);
|
||||
if_chain! {
|
||||
if let ExprKind::Index(base_left, idx_left) = lhs.kind;
|
||||
if let ExprKind::Index(base_right, idx_right) = rhs.kind;
|
||||
if let ExprKind::Index(base_left, idx_left, _) = lhs.kind;
|
||||
if let ExprKind::Index(base_right, idx_right, _) = rhs.kind;
|
||||
if let Some(ty) = get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_left));
|
||||
if get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some();
|
||||
if let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts);
|
||||
|
|
|
@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
|
||||
if_chain! {
|
||||
// an index op
|
||||
if let ExprKind::Index(seqexpr, idx) = expr.kind;
|
||||
if let ExprKind::Index(seqexpr, idx, _) = expr.kind;
|
||||
if !self.check(idx, seqexpr, expr);
|
||||
then {
|
||||
return;
|
||||
|
|
|
@ -162,7 +162,7 @@ fn never_loop_expr<'tcx>(
|
|||
ExprKind::Binary(_, e1, e2)
|
||||
| ExprKind::Assign(e1, e2, _)
|
||||
| ExprKind::AssignOp(_, e1, e2)
|
||||
| ExprKind::Index(e1, e2) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
|
||||
| ExprKind::Index(e1, e2, _) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
|
||||
ExprKind::Loop(b, _, _, _) => {
|
||||
// Break can come from the inner loop so remove them.
|
||||
absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id))
|
||||
|
|
|
@ -113,7 +113,7 @@ fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExp
|
|||
|
||||
// Shouldn't have side effects, but there's no way to trace which field is used. So forget which fields have
|
||||
// already been seen.
|
||||
ExprKind::Index(base, idx) if !idx.can_have_side_effects() => {
|
||||
ExprKind::Index(base, idx, _) if !idx.can_have_side_effects() => {
|
||||
can_move = false;
|
||||
fields.clear();
|
||||
e = base;
|
||||
|
|
|
@ -204,7 +204,7 @@ fn find_stripping<'tcx>(
|
|||
if_chain! {
|
||||
if is_ref_str(self.cx, ex);
|
||||
let unref = peel_ref(ex);
|
||||
if let ExprKind::Index(indexed, index) = &unref.kind;
|
||||
if let ExprKind::Index(indexed, index, _) = &unref.kind;
|
||||
if let Some(higher::Range { start, end, .. }) = higher::Range::hir(index);
|
||||
if let ExprKind::Path(path) = &indexed.kind;
|
||||
if self.cx.qpath_res(path, ex.hir_id) == self.target;
|
||||
|
|
|
@ -12,7 +12,7 @@ use super::MATCH_ON_VEC_ITEMS;
|
|||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
|
||||
if_chain! {
|
||||
if let Some(idx_expr) = is_vec_indexing(cx, scrutinee);
|
||||
if let ExprKind::Index(vec, idx) = idx_expr.kind;
|
||||
if let ExprKind::Index(vec, idx, _) = idx_expr.kind;
|
||||
|
||||
then {
|
||||
// FIXME: could be improved to suggest surrounding every pattern with Some(_),
|
||||
|
@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
|
|||
|
||||
fn is_vec_indexing<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
|
||||
if_chain! {
|
||||
if let ExprKind::Index(array, index) = expr.kind;
|
||||
if let ExprKind::Index(array, index, _) = expr.kind;
|
||||
if is_vector(cx, array);
|
||||
if !is_full_range(cx, index);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use super::FILTER_NEXT;
|
|||
fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> {
|
||||
match expr.kind {
|
||||
hir::ExprKind::Field(f, _) => path_to_local(f),
|
||||
hir::ExprKind::Index(recv, _) => path_to_local(recv),
|
||||
hir::ExprKind::Index(recv, _, _) => path_to_local(recv),
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
_,
|
||||
hir::Path {
|
||||
|
|
|
@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, cal
|
|||
if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {
|
||||
// caller is a Slice
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Index(caller_var, index_expr) = &caller_expr.kind;
|
||||
if let hir::ExprKind::Index(caller_var, index_expr, _) = &caller_expr.kind;
|
||||
if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
|
||||
= higher::Range::hir(index_expr);
|
||||
if let hir::ExprKind::Lit(start_lit) = &start_expr.kind;
|
||||
|
|
|
@ -239,7 +239,7 @@ fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> St
|
|||
| ExprKind::MethodCall(..)
|
||||
| ExprKind::Call(_, _)
|
||||
| ExprKind::Assign(..)
|
||||
| ExprKind::Index(_, _)
|
||||
| ExprKind::Index(..)
|
||||
| ExprKind::Repeat(_, _)
|
||||
| ExprKind::Struct(_, _, _) => {
|
||||
walk_expr(vis, expr);
|
||||
|
|
|
@ -119,7 +119,7 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool {
|
|||
| ExprKind::Call(i, _)
|
||||
| ExprKind::Cast(i, _)
|
||||
| ExprKind::Type(i, _)
|
||||
| ExprKind::Index(i, _) = inner.kind
|
||||
| ExprKind::Index(i, _, _) = inner.kind
|
||||
{
|
||||
if matches!(
|
||||
i.kind,
|
||||
|
|
|
@ -160,7 +160,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
match peel_blocks(expr).kind {
|
||||
ExprKind::Lit(..) | ExprKind::Closure { .. } => true,
|
||||
ExprKind::Path(..) => !has_drop(cx, cx.typeck_results().expr_ty(expr)),
|
||||
ExprKind::Index(a, b) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
|
||||
ExprKind::Index(a, b, _) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
|
||||
ExprKind::Array(v) | ExprKind::Tup(v) => v.iter().all(|val| has_no_effect(cx, val)),
|
||||
ExprKind::Repeat(inner, _)
|
||||
| ExprKind::Cast(inner, _)
|
||||
|
@ -263,7 +263,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
|
|||
return None;
|
||||
}
|
||||
match expr.kind {
|
||||
ExprKind::Index(a, b) => Some(vec![a, b]),
|
||||
ExprKind::Index(a, b, _) => Some(vec![a, b]),
|
||||
ExprKind::Binary(ref binop, a, b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => {
|
||||
Some(vec![a, b])
|
||||
},
|
||||
|
|
|
@ -438,7 +438,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
|||
|
||||
dereferenced_expr = parent_expr;
|
||||
},
|
||||
ExprKind::Index(e, _) if ptr::eq(&**e, cur_expr) => {
|
||||
ExprKind::Index(e, _, _) if ptr::eq(&**e, cur_expr) => {
|
||||
// `e[i]` => desugared to `*Index::index(&e, i)`,
|
||||
// meaning `e` must be referenced.
|
||||
// no need to go further up since a method call is involved now.
|
||||
|
|
|
@ -695,7 +695,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
|
|||
}
|
||||
},
|
||||
// Indexing is fine for currently supported types.
|
||||
ExprKind::Index(e, _) if e.hir_id == child_id => (),
|
||||
ExprKind::Index(e, _, _) if e.hir_id == child_id => (),
|
||||
_ => set_skip_flag(),
|
||||
},
|
||||
_ => set_skip_flag(),
|
||||
|
|
|
@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
|||
if_chain! {
|
||||
if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind;
|
||||
if addressee.span.ctxt() == ctxt;
|
||||
if let ExprKind::Index(indexed, range) = addressee.kind;
|
||||
if let ExprKind::Index(indexed, range, _) = addressee.kind;
|
||||
if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
|
||||
then {
|
||||
let (expr_ty, expr_ref_count) = peel_mid_ty_refs(cx.typeck_results().expr_ty(expr));
|
||||
|
|
|
@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
|
|||
);
|
||||
}
|
||||
},
|
||||
ExprKind::Index(target, _idx) => {
|
||||
ExprKind::Index(target, _idx, _) => {
|
||||
let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
|
||||
if e_ty.is_str() || is_type_lang_item(cx, e_ty, LangItem::String) {
|
||||
span_lint(
|
||||
|
@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
|
|||
|
||||
// Find string::as_bytes
|
||||
if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args[0].kind;
|
||||
if let ExprKind::Index(left, right) = args.kind;
|
||||
if let ExprKind::Index(left, right, _) = args.kind;
|
||||
let (method_names, expressions, _) = method_calls(left, 1);
|
||||
if method_names.len() == 1;
|
||||
if expressions.len() == 1;
|
||||
|
|
|
@ -572,7 +572,7 @@ fn ident_difference_expr_with_base_location(
|
|||
| (AddrOf(_, _, _), AddrOf(_, _, _))
|
||||
| (Path(_, _), Path(_, _))
|
||||
| (Range(_, _, _), Range(_, _, _))
|
||||
| (Index(_, _), Index(_, _))
|
||||
| (Index(_, _, _), Index(_, _, _))
|
||||
| (Field(_, _), Field(_, _))
|
||||
| (AssignOp(_, _, _), AssignOp(_, _, _))
|
||||
| (Assign(_, _, _), Assign(_, _, _))
|
||||
|
|
|
@ -86,8 +86,8 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
|
|||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
if !can_mut_borrow_both(cx, e1, e2) {
|
||||
if let ExprKind::Index(lhs1, idx1) = e1.kind
|
||||
&& let ExprKind::Index(lhs2, idx2) = e2.kind
|
||||
if let ExprKind::Index(lhs1, idx1, _) = e1.kind
|
||||
&& let ExprKind::Index(lhs2, idx2, _) = e2.kind
|
||||
&& eq_expr_value(cx, lhs1, lhs2)
|
||||
&& e1.span.ctxt() == ctxt
|
||||
&& e2.span.ctxt() == ctxt
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment {
|
|||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Assign(target, ..) = &expr.kind {
|
||||
let mut base = target;
|
||||
while let ExprKind::Field(f, _) | ExprKind::Index(f, _) = &base.kind {
|
||||
while let ExprKind::Field(f, _) | ExprKind::Index(f, _, _) = &base.kind {
|
||||
base = f;
|
||||
}
|
||||
if is_temporary(base) && !is_adjusted(cx, base) {
|
||||
|
|
|
@ -103,11 +103,11 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &
|
|||
// Fix #11100
|
||||
&& tys.iter().all_equal()
|
||||
&& let Some(locals) = (match first.kind {
|
||||
ExprKind::Index(_, _) => elements
|
||||
ExprKind::Index(..) => elements
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, i_expr)| -> Option<&'tcx Expr<'tcx>> {
|
||||
if let ExprKind::Index(lhs, index) = i_expr.kind
|
||||
if let ExprKind::Index(lhs, index, _) = i_expr.kind
|
||||
&& let ExprKind::Lit(lit) = index.kind
|
||||
&& let LitKind::Int(val, _) = lit.node
|
||||
{
|
||||
|
|
|
@ -526,7 +526,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
self.ident(field_name);
|
||||
self.expr(object);
|
||||
},
|
||||
ExprKind::Index(object, index) => {
|
||||
ExprKind::Index(object, index, _) => {
|
||||
bind!(self, object, index);
|
||||
kind!("Index({object}, {index})");
|
||||
self.expr(object);
|
||||
|
|
|
@ -88,7 +88,7 @@ impl VecPushSearcher {
|
|||
let mut last_place = parent;
|
||||
while let Some(parent) = get_parent_expr(cx, last_place) {
|
||||
if matches!(parent.kind, ExprKind::Unary(UnOp::Deref, _) | ExprKind::Field(..))
|
||||
|| matches!(parent.kind, ExprKind::Index(e, _) if e.hir_id == last_place.hir_id)
|
||||
|| matches!(parent.kind, ExprKind::Index(e, _, _) if e.hir_id == last_place.hir_id)
|
||||
{
|
||||
last_place = parent;
|
||||
} else {
|
||||
|
|
|
@ -178,7 +178,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
|||
(Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
|
||||
(Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
|
||||
(Continue(ll), Continue(rl)) => eq_label(ll, rl),
|
||||
(Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2), Index(r1, r2)) => eq_expr(l1, r1) && eq_expr(l2, r2),
|
||||
(Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => eq_expr(l1, r1) && eq_expr(l2, r2),
|
||||
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
|
||||
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
|
||||
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
|
||||
|
|
|
@ -163,7 +163,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
|
|||
) => (Pat::Str("unsafe"), Pat::Str("}")),
|
||||
ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
|
||||
ExprKind::Field(e, name) => (expr_search_pat(tcx, e).0, Pat::Sym(name.name)),
|
||||
ExprKind::Index(e, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
|
||||
ExprKind::Index(e, _, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
|
||||
ExprKind::Path(ref path) => qpath_search_pat(path),
|
||||
ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1),
|
||||
ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),
|
||||
|
|
|
@ -394,7 +394,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
},
|
||||
ExprKind::Index(arr, index) => self.index(arr, index),
|
||||
ExprKind::Index(arr, index, _) => self.index(arr, index),
|
||||
ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))),
|
||||
ExprKind::Field(local_expr, ref field) => {
|
||||
let result = self.expr(local_expr);
|
||||
|
|
|
@ -185,7 +185,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
|||
.type_dependent_def_id(e.hir_id)
|
||||
.map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true));
|
||||
},
|
||||
ExprKind::Index(_, e) => {
|
||||
ExprKind::Index(_, e, _) => {
|
||||
let ty = self.cx.typeck_results().expr_ty_adjusted(e);
|
||||
if is_copy(self.cx, ty) && !ty.is_ref() {
|
||||
self.eagerness |= NoChange;
|
||||
|
|
|
@ -299,7 +299,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
(&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => {
|
||||
l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp)
|
||||
},
|
||||
(&ExprKind::Index(la, li), &ExprKind::Index(ra, ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
||||
(&ExprKind::Index(la, li, _), &ExprKind::Index(ra, ri, _)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
||||
(&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
|
||||
self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||
},
|
||||
|
@ -730,7 +730,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(e);
|
||||
self.hash_name(f.name);
|
||||
},
|
||||
ExprKind::Index(a, i) => {
|
||||
ExprKind::Index(a, i, _) => {
|
||||
self.hash_expr(a);
|
||||
self.hash_expr(i);
|
||||
},
|
||||
|
|
|
@ -735,7 +735,7 @@ fn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'
|
|||
let mut result = vec![];
|
||||
let root = loop {
|
||||
match e.kind {
|
||||
ExprKind::Index(ep, _) | ExprKind::Field(ep, _) => {
|
||||
ExprKind::Index(ep, _, _) | ExprKind::Field(ep, _) => {
|
||||
result.push(e);
|
||||
e = ep;
|
||||
},
|
||||
|
@ -782,7 +782,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
|
|||
return true;
|
||||
}
|
||||
},
|
||||
(ExprKind::Index(_, i1), ExprKind::Index(_, i2)) => {
|
||||
(ExprKind::Index(_, i1, _), ExprKind::Index(_, i2, _)) => {
|
||||
if !eq_expr_value(cx, i1, i2) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
|
|||
let certainty = match &expr.kind {
|
||||
ExprKind::Unary(_, expr)
|
||||
| ExprKind::Field(expr, _)
|
||||
| ExprKind::Index(expr, _)
|
||||
| ExprKind::Index(expr, _, _)
|
||||
| ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr),
|
||||
|
||||
ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr))),
|
||||
|
|
|
@ -329,7 +329,7 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
|
|||
&& self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
|
||||
ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_ref() => (),
|
||||
ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (),
|
||||
ExprKind::Index(base, _)
|
||||
ExprKind::Index(base, _, _)
|
||||
if matches!(
|
||||
self.cx.typeck_results().expr_ty(base).peel_refs().kind(),
|
||||
ty::Slice(_) | ty::Array(..)
|
||||
|
@ -629,7 +629,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
helper(typeck, true, arg, f)?;
|
||||
}
|
||||
},
|
||||
ExprKind::Index(borrowed, consumed)
|
||||
ExprKind::Index(borrowed, consumed, _)
|
||||
| ExprKind::Assign(borrowed, consumed, _)
|
||||
| ExprKind::AssignOp(_, borrowed, consumed) => {
|
||||
helper(typeck, false, borrowed, f)?;
|
||||
|
|
|
@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_middle::mir::{Mutability, RetagKind};
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
layout::{HasParamEnv, LayoutOf},
|
||||
layout::HasParamEnv,
|
||||
Ty,
|
||||
};
|
||||
use rustc_target::abi::{Abi, Align, Size};
|
||||
|
@ -993,8 +993,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
// We have to turn the place into a pointer to use the usual retagging logic.
|
||||
// (The pointer type does not matter, so we use a raw pointer.)
|
||||
let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?;
|
||||
let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout);
|
||||
let ptr = this.mplace_to_ref(place)?;
|
||||
// Reborrow it. With protection! That is the entire point.
|
||||
let new_perm = NewPermission::Uniform {
|
||||
perm: Permission::Unique,
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc_middle::{
|
|||
mir::{Mutability, RetagKind},
|
||||
ty::{
|
||||
self,
|
||||
layout::{HasParamEnv, LayoutOf},
|
||||
layout::HasParamEnv,
|
||||
Ty,
|
||||
},
|
||||
};
|
||||
|
@ -488,8 +488,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
// We have to turn the place into a pointer to use the usual retagging logic.
|
||||
// (The pointer type does not matter, so we use a raw pointer.)
|
||||
let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?;
|
||||
let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout);
|
||||
let ptr = this.mplace_to_ref(place)?;
|
||||
// Reborrow it. With protection! That is the entire point.
|
||||
let new_perm = NewPermission {
|
||||
initial_state: Permission::new_active(),
|
||||
|
|
|
@ -256,7 +256,7 @@ pub(crate) fn format_expr(
|
|||
shape,
|
||||
SeparatorPlace::Back,
|
||||
),
|
||||
ast::ExprKind::Index(ref expr, ref index) => {
|
||||
ast::ExprKind::Index(ref expr, ref index, _) => {
|
||||
rewrite_index(&**expr, &**index, context, shape)
|
||||
}
|
||||
ast::ExprKind::Repeat(ref expr, ref repeats) => rewrite_pair(
|
||||
|
@ -1342,7 +1342,7 @@ pub(crate) fn is_simple_expr(expr: &ast::Expr) -> bool {
|
|||
| ast::ExprKind::Field(ref expr, _)
|
||||
| ast::ExprKind::Try(ref expr)
|
||||
| ast::ExprKind::Unary(_, ref expr) => is_simple_expr(expr),
|
||||
ast::ExprKind::Index(ref lhs, ref rhs) => is_simple_expr(lhs) && is_simple_expr(rhs),
|
||||
ast::ExprKind::Index(ref lhs, ref rhs, _) => is_simple_expr(lhs) && is_simple_expr(rhs),
|
||||
ast::ExprKind::Repeat(ref lhs, ref rhs) => {
|
||||
is_simple_expr(lhs) && is_simple_expr(&*rhs.value)
|
||||
}
|
||||
|
|
|
@ -594,7 +594,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool {
|
|||
ast::ExprKind::AddrOf(_, _, ref expr)
|
||||
| ast::ExprKind::Try(ref expr)
|
||||
| ast::ExprKind::Unary(_, ref expr)
|
||||
| ast::ExprKind::Index(ref expr, _)
|
||||
| ast::ExprKind::Index(ref expr, _, _)
|
||||
| ast::ExprKind::Cast(ref expr, _) => can_flatten_block_around_this(expr),
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -441,7 +441,7 @@ pub(crate) fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
|
|||
| ast::ExprKind::Assign(ref e, _, _)
|
||||
| ast::ExprKind::AssignOp(_, ref e, _)
|
||||
| ast::ExprKind::Field(ref e, _)
|
||||
| ast::ExprKind::Index(ref e, _)
|
||||
| ast::ExprKind::Index(ref e, _, _)
|
||||
| ast::ExprKind::Range(Some(ref e), _, _)
|
||||
| ast::ExprKind::Try(ref e) => left_most_sub_expr(e),
|
||||
_ => e,
|
||||
|
@ -479,7 +479,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
|
|||
| ast::ExprKind::Match(..) => repr.contains('\n'),
|
||||
ast::ExprKind::Paren(ref expr)
|
||||
| ast::ExprKind::Binary(_, _, ref expr)
|
||||
| ast::ExprKind::Index(_, ref expr)
|
||||
| ast::ExprKind::Index(_, ref expr, _)
|
||||
| ast::ExprKind::Unary(_, ref expr)
|
||||
| ast::ExprKind::Try(ref expr)
|
||||
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
|
|||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1893;
|
||||
const ROOT_ENTRY_LIMIT: usize = 873;
|
||||
const ROOT_ENTRY_LIMIT: usize = 866;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
error[E0608]: cannot index into a value of type `Foo`
|
||||
--> $DIR/slice-2.rs:7:6
|
||||
--> $DIR/slice-2.rs:7:7
|
||||
|
|
||||
LL | &x[..];
|
||||
| ^^^^^
|
||||
| ^^^^
|
||||
|
||||
error[E0608]: cannot index into a value of type `Foo`
|
||||
--> $DIR/slice-2.rs:8:6
|
||||
--> $DIR/slice-2.rs:8:7
|
||||
|
|
||||
LL | &x[Foo..];
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0608]: cannot index into a value of type `Foo`
|
||||
--> $DIR/slice-2.rs:9:6
|
||||
--> $DIR/slice-2.rs:9:7
|
||||
|
|
||||
LL | &x[..Foo];
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0608]: cannot index into a value of type `Foo`
|
||||
--> $DIR/slice-2.rs:10:6
|
||||
--> $DIR/slice-2.rs:10:7
|
||||
|
|
||||
LL | &x[Foo..Foo];
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
|
|||
|
|
||||
LL | vec[vec.len() - 1] = 123;
|
||||
| ----^^^-----------
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| | ||
|
||||
| | |immutable borrow occurs here
|
||||
| | mutable borrow later used here
|
||||
| mutable borrow occurs here
|
||||
| mutable borrow later used here
|
||||
|
|
||||
help: try adding a local storing this...
|
||||
--> $DIR/suggest-local-var-for-vector.rs:3:9
|
||||
|
@ -14,10 +14,10 @@ help: try adding a local storing this...
|
|||
LL | vec[vec.len() - 1] = 123;
|
||||
| ^^^^^^^^^
|
||||
help: ...and then using that local here
|
||||
--> $DIR/suggest-local-var-for-vector.rs:3:5
|
||||
--> $DIR/suggest-local-var-for-vector.rs:3:8
|
||||
|
|
||||
LL | vec[vec.len() - 1] = 123;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
|
|||
|
|
||||
LL | vec[vec.len() - 1] = 123;
|
||||
| ----^^^-----------
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| | ||
|
||||
| | |immutable borrow occurs here
|
||||
| | mutable borrow later used here
|
||||
| mutable borrow occurs here
|
||||
| mutable borrow later used here
|
||||
|
|
||||
help: try adding a local storing this...
|
||||
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
|
||||
|
@ -14,10 +14,10 @@ help: try adding a local storing this...
|
|||
LL | vec[vec.len() - 1] = 123;
|
||||
| ^^^^^^^^^
|
||||
help: ...and then using that local here
|
||||
--> $DIR/suggest-storing-local-var-for-vector.rs:3:5
|
||||
--> $DIR/suggest-storing-local-var-for-vector.rs:3:8
|
||||
|
|
||||
LL | vec[vec.len() - 1] = 123;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -50,42 +50,42 @@ error[E0502]: cannot borrow `i` as immutable because it is also borrowed as muta
|
|||
|
|
||||
LL | i[i[3]] = 4;
|
||||
| --^----
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| |||
|
||||
| ||immutable borrow occurs here
|
||||
| |mutable borrow later used here
|
||||
| mutable borrow occurs here
|
||||
| mutable borrow later used here
|
||||
|
|
||||
help: try adding a local storing this...
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:132:7
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:132:8
|
||||
|
|
||||
LL | i[i[3]] = 4;
|
||||
| ^^^^
|
||||
| ^^^
|
||||
help: ...and then using that local here
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:132:5
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:132:6
|
||||
|
|
||||
LL | i[i[3]] = 4;
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:138:7
|
||||
|
|
||||
LL | i[i[3]] = i[4];
|
||||
| --^----
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| |||
|
||||
| ||immutable borrow occurs here
|
||||
| |mutable borrow later used here
|
||||
| mutable borrow occurs here
|
||||
| mutable borrow later used here
|
||||
|
|
||||
help: try adding a local storing this...
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:138:7
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:138:8
|
||||
|
|
||||
LL | i[i[3]] = i[4];
|
||||
| ^^^^
|
||||
| ^^^
|
||||
help: ...and then using that local here
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:138:5
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:138:6
|
||||
|
|
||||
LL | i[i[3]] = i[4];
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ LL | self.bar[0] = baz.len();
|
|||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const operator in constant functions
|
||||
--> $DIR/issue-94675.rs:11:9
|
||||
--> $DIR/issue-94675.rs:11:17
|
||||
|
|
||||
LL | self.bar[0] = baz.len();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^
|
||||
|
|
||||
note: impl defined here, but it is not `const`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
|
25
tests/ui/dst/issue-113447.fixed
Normal file
25
tests/ui/dst/issue-113447.fixed
Normal file
|
@ -0,0 +1,25 @@
|
|||
// run-rustfix
|
||||
|
||||
pub struct Bytes;
|
||||
|
||||
impl Bytes {
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<[u8]> for Bytes {
|
||||
fn eq(&self, other: &[u8]) -> bool {
|
||||
self.as_slice() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Bytes> for &[u8] {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == **self
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = &[0u8] == &[0xAA][..]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]`
|
||||
}
|
25
tests/ui/dst/issue-113447.rs
Normal file
25
tests/ui/dst/issue-113447.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
// run-rustfix
|
||||
|
||||
pub struct Bytes;
|
||||
|
||||
impl Bytes {
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<[u8]> for Bytes {
|
||||
fn eq(&self, other: &[u8]) -> bool {
|
||||
self.as_slice() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Bytes> for &[u8] {
|
||||
fn eq(&self, other: &Bytes) -> bool {
|
||||
*other == **self
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = &[0u8] == [0xAA]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]`
|
||||
}
|
25
tests/ui/dst/issue-113447.stderr
Normal file
25
tests/ui/dst/issue-113447.stderr
Normal file
|
@ -0,0 +1,25 @@
|
|||
error[E0277]: can't compare `&[u8; 1]` with `[{integer}; 1]`
|
||||
--> $DIR/issue-113447.rs:24:20
|
||||
|
|
||||
LL | let _ = &[0u8] == [0xAA];
|
||||
| ^^ no implementation for `&[u8; 1] == [{integer}; 1]`
|
||||
|
|
||||
= help: the trait `PartialEq<[{integer}; 1]>` is not implemented for `&[u8; 1]`
|
||||
= help: the following other types implement trait `PartialEq<Rhs>`:
|
||||
<[A; N] as PartialEq<[B; N]>>
|
||||
<[A; N] as PartialEq<[B]>>
|
||||
<[A; N] as PartialEq<&[B]>>
|
||||
<[A; N] as PartialEq<&mut [B]>>
|
||||
<[T] as PartialEq<Vec<U, A>>>
|
||||
<[A] as PartialEq<[B]>>
|
||||
<[B] as PartialEq<[A; N]>>
|
||||
<&[u8] as PartialEq<Bytes>>
|
||||
and 4 others
|
||||
help: convert the array to a `&[u8]` slice instead
|
||||
|
|
||||
LL | let _ = &[0u8] == &[0xAA][..];
|
||||
| + ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,8 +1,8 @@
|
|||
error[E0608]: cannot index into a value of type `u8`
|
||||
--> $DIR/E0608.rs:2:5
|
||||
--> $DIR/E0608.rs:2:8
|
||||
|
|
||||
LL | 0u8[2];
|
||||
| ^^^^^^
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0608]: cannot index into a value of type `!`
|
||||
--> $DIR/index-bot.rs:2:5
|
||||
--> $DIR/index-bot.rs:2:13
|
||||
|
|
||||
LL | (return)[0];
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0608]: cannot index into a value of type `({integer},)`
|
||||
--> $DIR/index_message.rs:3:13
|
||||
--> $DIR/index_message.rs:3:14
|
||||
|
|
||||
LL | let _ = z[0];
|
||||
| ^^^^ help: to access tuple elements, use: `z.0`
|
||||
| ^^^ help: to access tuple elements, use: `.0`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
27
tests/ui/indexing/indexing-spans-caller-location.rs
Normal file
27
tests/ui/indexing/indexing-spans-caller-location.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
// run-pass
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/114388
|
||||
|
||||
#[track_caller]
|
||||
fn caller_line() -> u32 {
|
||||
std::panic::Location::caller().line()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let prev_line = caller_line(); // first line
|
||||
(A { prev_line }) // second line
|
||||
[0]; // third line
|
||||
}
|
||||
|
||||
struct A {
|
||||
prev_line: u32,
|
||||
}
|
||||
impl std::ops::Index<usize> for A {
|
||||
type Output = ();
|
||||
|
||||
fn index(&self, _idx: usize) -> &() {
|
||||
// Use the relative number to make it resistent to header changes.
|
||||
assert_eq!(caller_line(), self.prev_line + 2);
|
||||
&()
|
||||
}
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:6:
|
||||
thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:8:
|
||||
byte index 1 is out of bounds of ``
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
|
44
tests/ui/invalid/issue-114435-layout-type-err.rs
Normal file
44
tests/ui/invalid/issue-114435-layout-type-err.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
// build-fail
|
||||
// compile-flags: --crate-type lib -Cdebuginfo=2
|
||||
// error-pattern: the type has an unknown layout
|
||||
|
||||
#![recursion_limit = "10"]
|
||||
macro_rules! link {
|
||||
($outer:ident, $inner:ident) => {
|
||||
struct $outer($inner);
|
||||
impl $outer {
|
||||
fn new() -> $outer {
|
||||
$outer($inner::new())
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for $outer {
|
||||
type Target = $inner;
|
||||
fn deref(&self) -> &$inner {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct Bottom;
|
||||
|
||||
impl Bottom {
|
||||
fn new() -> Bottom {
|
||||
Bottom
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
link!(A, B);
|
||||
link!(B, C);
|
||||
link!(C, D);
|
||||
link!(D, E);
|
||||
link!(E, F);
|
||||
link!(F, G);
|
||||
link!(G, H);
|
||||
link!(H, I);
|
||||
link!(I, J);
|
||||
link!(J, K);
|
||||
link!(K, Bottom);
|
||||
|
||||
fn main() { }
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue