Auto merge of #12246 - flip1995:rustup, r=flip1995
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
60cb29c5e4
24 changed files with 112 additions and 123 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy"
|
||||
version = "0.1.77"
|
||||
version = "0.1.78"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_config"
|
||||
version = "0.1.77"
|
||||
version = "0.1.78"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -927,7 +927,7 @@ fn remove_line_splices(s: &str) -> String {
|
|||
.and_then(|s| s.strip_suffix('"'))
|
||||
.unwrap_or_else(|| panic!("expected quoted string, found `{s}`"));
|
||||
let mut res = String::with_capacity(s.len());
|
||||
unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, ch| {
|
||||
unescape::unescape_unicode(s, unescape::Mode::Str, &mut |range, ch| {
|
||||
if ch.is_ok() {
|
||||
res.push_str(&s[range]);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.77"
|
||||
version = "0.1.78"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -881,6 +881,7 @@ impl TyCoercionStability {
|
|||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::Alias(ty::Projection, _) => Self::Deref,
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_span::sym;
|
|||
use super::ITER_NTH_ZERO;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
|
||||
if let OwnerNode::Item(item) = cx.tcx.hir().owner(cx.tcx.hir().get_parent_item(expr.hir_id))
|
||||
if let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id))
|
||||
&& let def_id = item.owner_id.to_def_id()
|
||||
&& is_trait_method(cx, expr, sym::Iterator)
|
||||
&& let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), arg)
|
||||
|
|
|
@ -93,9 +93,7 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
|
|||
// reimplement it even if we wanted to
|
||||
cx.tcx.opt_hir_node(hir_id)
|
||||
} else {
|
||||
let Some(owner) = cx.tcx.hir_owner_nodes(hir_id.owner).as_owner() else {
|
||||
return;
|
||||
};
|
||||
let owner = cx.tcx.hir_owner_nodes(hir_id.owner);
|
||||
owner.nodes.get(hir_id.local_id).copied().flatten().map(|p| p.node)
|
||||
};
|
||||
let Some(node) = node else {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use super::ARITHMETIC_SIDE_EFFECTS;
|
||||
use clippy_utils::consts::{constant, constant_simple, Constant};
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::type_diagnostic_name;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -88,37 +88,44 @@ impl ArithmeticSideEffects {
|
|||
}
|
||||
|
||||
/// Verifies built-in types that have specific allowed operations
|
||||
fn has_specific_allowed_type_and_operation(
|
||||
cx: &LateContext<'_>,
|
||||
lhs_ty: Ty<'_>,
|
||||
fn has_specific_allowed_type_and_operation<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
op: &Spanned<hir::BinOpKind>,
|
||||
rhs_ty: Ty<'_>,
|
||||
rhs_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
|
||||
let is_non_zero_u = |symbol: Option<Symbol>| {
|
||||
matches!(
|
||||
symbol,
|
||||
Some(
|
||||
sym::NonZeroU128
|
||||
| sym::NonZeroU16
|
||||
| sym::NonZeroU32
|
||||
| sym::NonZeroU64
|
||||
| sym::NonZeroU8
|
||||
| sym::NonZeroUsize
|
||||
)
|
||||
)
|
||||
let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| {
|
||||
let tcx = cx.tcx;
|
||||
|
||||
let ty::Adt(adt, substs) = ty.kind() else { return false };
|
||||
|
||||
if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
|
||||
return false;
|
||||
};
|
||||
|
||||
let int_type = substs.type_at(0);
|
||||
let unsigned_int_types = [
|
||||
tcx.types.u8,
|
||||
tcx.types.u16,
|
||||
tcx.types.u32,
|
||||
tcx.types.u64,
|
||||
tcx.types.u128,
|
||||
tcx.types.usize,
|
||||
];
|
||||
|
||||
unsigned_int_types.contains(&int_type)
|
||||
};
|
||||
let is_sat_or_wrap = |ty: Ty<'_>| {
|
||||
let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating);
|
||||
let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping);
|
||||
is_sat || is_wrap
|
||||
is_type_diagnostic_item(cx, ty, sym::Saturating) || is_type_diagnostic_item(cx, ty, sym::Wrapping)
|
||||
};
|
||||
|
||||
// If the RHS is NonZeroU*, then division or module by zero will never occur
|
||||
if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem {
|
||||
// If the RHS is `NonZero<u*>`, then division or module by zero will never occur.
|
||||
if is_non_zero_u(cx, rhs_ty) && is_div_or_rem {
|
||||
return true;
|
||||
}
|
||||
// `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module
|
||||
|
||||
// `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module.
|
||||
if is_sat_or_wrap(lhs_ty) {
|
||||
return !is_div_or_rem;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
|||
&& is_res_lang_ctor(cx, path_res(cx, maybe_constr), ResultErr)
|
||||
|
||||
// Ensure this is not the final stmt, otherwise removing it would cause a compile error
|
||||
&& let OwnerNode::Item(item) = cx.tcx.hir().owner(cx.tcx.hir().get_parent_item(expr.hir_id))
|
||||
&& let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id))
|
||||
&& let ItemKind::Fn(_, _, body) = item.kind
|
||||
&& let block = cx.tcx.hir().body(body).value
|
||||
&& let ExprKind::Block(block, _) = block.kind
|
||||
|
|
|
@ -16,40 +16,55 @@ pub(super) fn check<'tcx>(
|
|||
to_ty: Ty<'tcx>,
|
||||
arg: &'tcx Expr<'_>,
|
||||
) -> bool {
|
||||
let (ty::Int(_) | ty::Uint(_), Some(to_ty_adt)) = (&from_ty.kind(), to_ty.ty_adt_def()) else {
|
||||
return false;
|
||||
};
|
||||
let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_adt.did()) else {
|
||||
let tcx = cx.tcx;
|
||||
|
||||
let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if !matches!(
|
||||
to_type_sym,
|
||||
sym::NonZeroU8
|
||||
| sym::NonZeroU16
|
||||
| sym::NonZeroU32
|
||||
| sym::NonZeroU64
|
||||
| sym::NonZeroU128
|
||||
| sym::NonZeroI8
|
||||
| sym::NonZeroI16
|
||||
| sym::NonZeroI32
|
||||
| sym::NonZeroI64
|
||||
| sym::NonZeroI128
|
||||
) {
|
||||
if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: This can be simplified once `NonZero<T>` is stable.
|
||||
let coercable_types = [
|
||||
("NonZeroU8", tcx.types.u8),
|
||||
("NonZeroU16", tcx.types.u16),
|
||||
("NonZeroU32", tcx.types.u32),
|
||||
("NonZeroU64", tcx.types.u64),
|
||||
("NonZeroU128", tcx.types.u128),
|
||||
("NonZeroUsize", tcx.types.usize),
|
||||
("NonZeroI8", tcx.types.i8),
|
||||
("NonZeroI16", tcx.types.i16),
|
||||
("NonZeroI32", tcx.types.i32),
|
||||
("NonZeroI64", tcx.types.i64),
|
||||
("NonZeroI128", tcx.types.i128),
|
||||
("NonZeroIsize", tcx.types.isize),
|
||||
];
|
||||
|
||||
let int_type = substs.type_at(0);
|
||||
|
||||
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
|
||||
if *t == int_type && *t == from_ty {
|
||||
Some(nonzero_alias)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
TRANSMUTE_INT_TO_NON_ZERO,
|
||||
e.span,
|
||||
&format!("transmute from a `{from_ty}` to a `{to_type_sym}`"),
|
||||
&format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
|
||||
|diag| {
|
||||
let arg = sugg::Sugg::hir(cx, arg, "..");
|
||||
diag.span_suggestion(
|
||||
e.span,
|
||||
"consider using",
|
||||
format!("{to_type_sym}::{}({arg})", sym::new_unchecked),
|
||||
format!("{nonzero_alias}::{}({arg})", sym::new_unchecked),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
},
|
||||
|
|
|
@ -37,12 +37,6 @@ pub(super) fn check_cast<'tcx>(
|
|||
let inherited = Inherited::new(cx.tcx, local_def_id);
|
||||
let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, local_def_id);
|
||||
|
||||
// If we already have errors, we can't be sure we can pointer cast.
|
||||
assert!(
|
||||
!fn_ctxt.errors_reported_since_creation(),
|
||||
"Newly created FnCtxt contained errors"
|
||||
);
|
||||
|
||||
if let Ok(check) = cast::CastCheck::new(
|
||||
&fn_ctxt,
|
||||
e,
|
||||
|
@ -53,17 +47,7 @@ pub(super) fn check_cast<'tcx>(
|
|||
DUMMY_SP,
|
||||
hir::Constness::NotConst,
|
||||
) {
|
||||
let res = check.do_check(&fn_ctxt);
|
||||
|
||||
// do_check's documentation says that it might return Ok and create
|
||||
// errors in the fcx instead of returning Err in some cases. Those cases
|
||||
// should be filtered out before getting here.
|
||||
assert!(
|
||||
!fn_ctxt.errors_reported_since_creation(),
|
||||
"`fn_ctxt` contained errors after cast check!"
|
||||
);
|
||||
|
||||
res.ok()
|
||||
check.do_check(&fn_ctxt).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -490,6 +490,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
|
||||
},
|
||||
},
|
||||
ClosureKind::CoroutineClosure(desugaring) => {
|
||||
format!("ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})")
|
||||
},
|
||||
};
|
||||
|
||||
let ret_ty = match fn_decl.output {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.77"
|
||||
version = "0.1.78"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "declare_clippy_lint"
|
||||
version = "0.1.77"
|
||||
version = "0.1.78"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2024-01-25"
|
||||
channel = "nightly-2024-02-08"
|
||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
|
|
|
@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind
|
|||
{
|
||||
// report your lint here
|
||||
}
|
||||
if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = expr.kind
|
||||
if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind
|
||||
&& let FnRetTy::DefaultReturn(_) = fn_decl.output
|
||||
&& expr1 = &cx.tcx.hir().body(body_id).value
|
||||
&& let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
|
||||
&& let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
|
||||
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output
|
||||
&& expr2 = &cx.tcx.hir().body(body_id1).value
|
||||
&& let ExprKind::Block(block, None) = expr2.kind
|
||||
|
|
|
@ -11,8 +11,6 @@ fn main() {
|
|||
// This used to cause an ICE (https://github.com/rust-lang/rust/issues/78071)
|
||||
match FOO_REF_REF {
|
||||
FOO_REF_REF => {},
|
||||
//~^ ERROR: to use a constant of type `Foo` in a pattern, `Foo` must be annotated
|
||||
//~| NOTE: for more information, see issue #62411 <https://github.com/rust-lang/ru
|
||||
Foo(_) => {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/ice-6254.rs:13:9
|
||||
|
|
||||
LL | FOO_REF_REF => {},
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
= note: `-D indirect-structural-match` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(indirect_structural_match)]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
@ -20,12 +20,8 @@ mod rustc_ok {
|
|||
pub fn rustc_lints() {
|
||||
let x = 42.0;
|
||||
|
||||
#[expect(illegal_floating_point_literal_pattern)]
|
||||
match x {
|
||||
5.0 => {},
|
||||
6.0 => {},
|
||||
_ => {},
|
||||
}
|
||||
#[expect(invalid_nan_comparisons)]
|
||||
let _b = x == f32::NAN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,13 +34,9 @@ mod rustc_warn {
|
|||
pub fn rustc_lints() {
|
||||
let x = 42;
|
||||
|
||||
#[expect(illegal_floating_point_literal_pattern)]
|
||||
#[expect(invalid_nan_comparisons)]
|
||||
//~^ ERROR: this lint expectation is unfulfilled
|
||||
match x {
|
||||
5 => {},
|
||||
6 => {},
|
||||
_ => {},
|
||||
}
|
||||
let _b = x == 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this lint expectation is unfulfilled
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:35:14
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:31:14
|
||||
|
|
||||
LL | #[expect(dead_code)]
|
||||
| ^^^^^^^^^
|
||||
|
@ -8,31 +8,31 @@ LL | #[expect(dead_code)]
|
|||
= help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`
|
||||
|
||||
error: this lint expectation is unfulfilled
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:41:18
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:37:18
|
||||
|
|
||||
LL | #[expect(illegal_floating_point_literal_pattern)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[expect(invalid_nan_comparisons)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this lint expectation is unfulfilled
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:116:14
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:108:14
|
||||
|
|
||||
LL | #[expect(clippy::almost_swapped)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this lint expectation is unfulfilled
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:124:14
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:116:14
|
||||
|
|
||||
LL | #[expect(clippy::bytes_nth)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this lint expectation is unfulfilled
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:130:14
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:122:14
|
||||
|
|
||||
LL | #[expect(clippy::if_same_then_else)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this lint expectation is unfulfilled
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:136:14
|
||||
--> $DIR/expect_tool_lint_rfc_2383.rs:128:14
|
||||
|
|
||||
LL | #[expect(clippy::overly_complex_bool_expr)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -33,7 +33,6 @@ fn main() {
|
|||
INT_MIN % NEG_ONE;
|
||||
//~^ ERROR: this operation will panic at runtime
|
||||
//~| ERROR: any number modulo -1 will panic/overflow or result in 0
|
||||
// ONLY caught by rustc
|
||||
// Not caught by lint, we don't look into static items, even if entirely immutable.
|
||||
INT_MIN % STATIC_NEG_ONE;
|
||||
//~^ ERROR: this operation will panic at runtime
|
||||
}
|
||||
|
|
|
@ -12,12 +12,6 @@ error: this operation will panic at runtime
|
|||
LL | INT_MIN % NEG_ONE;
|
||||
| ^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/modulo_one.rs:37:5
|
||||
|
|
||||
LL | INT_MIN % STATIC_NEG_ONE;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow
|
||||
|
||||
error: any number modulo 1 will be 0
|
||||
--> $DIR/modulo_one.rs:8:5
|
||||
|
|
||||
|
@ -57,5 +51,5 @@ error: any number modulo -1 will panic/overflow or result in 0
|
|||
LL | INT_MIN % NEG_ONE;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ mod should_lint {
|
|||
impl S {
|
||||
fn foo() {}
|
||||
//~^ ERROR: method's name is the same as an existing method in a trait
|
||||
//~| ERROR: method's name is the same as an existing method in a trait
|
||||
}
|
||||
|
||||
impl T1 for S {}
|
||||
|
|
|
@ -56,10 +56,22 @@ LL | fn foo() {}
|
|||
| ^^^^^^^^^^^
|
||||
|
|
||||
note: existing `foo` defined here
|
||||
--> $DIR/same_name_method.rs:79:9
|
||||
--> $DIR/same_name_method.rs:80:9
|
||||
|
|
||||
LL | impl T1 for S {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: method's name is the same as an existing method in a trait
|
||||
--> $DIR/same_name_method.rs:75:13
|
||||
|
|
||||
LL | fn foo() {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
note: existing `foo` defined here
|
||||
--> $DIR/same_name_method.rs:82:9
|
||||
|
|
||||
LL | impl T2 for S {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue