Rollup merge of #106363 - estebank:mutability-mismatch-arg, r=Nilstrieb
Structured suggestion for `&mut dyn Iterator` when possible Fix #37914.
This commit is contained in:
commit
334426b7a8
@ -57,7 +57,12 @@ pub enum MethodError<'tcx> {
|
||||
PrivateMatch(DefKind, DefId, Vec<DefId>),
|
||||
|
||||
// Found a `Self: Sized` bound where `Self` is a trait object.
|
||||
IllegalSizedBound(Vec<DefId>, bool, Span),
|
||||
IllegalSizedBound {
|
||||
candidates: Vec<DefId>,
|
||||
needs_mut: bool,
|
||||
bound_span: Span,
|
||||
self_expr: &'tcx hir::Expr<'tcx>,
|
||||
},
|
||||
|
||||
// Found a match, but the return type is wrong
|
||||
BadReturnType,
|
||||
@ -112,7 +117,7 @@ pub fn method_exists(
|
||||
Err(NoMatch(..)) => false,
|
||||
Err(Ambiguity(..)) => true,
|
||||
Err(PrivateMatch(..)) => allow_private,
|
||||
Err(IllegalSizedBound(..)) => true,
|
||||
Err(IllegalSizedBound { .. }) => true,
|
||||
Err(BadReturnType) => bug!("no return type expectations but got BadReturnType"),
|
||||
}
|
||||
}
|
||||
@ -236,7 +241,7 @@ pub fn lookup_method(
|
||||
_ => Vec::new(),
|
||||
};
|
||||
|
||||
return Err(IllegalSizedBound(candidates, needs_mut, span));
|
||||
return Err(IllegalSizedBound { candidates, needs_mut, bound_span: span, self_expr });
|
||||
}
|
||||
|
||||
Ok(result.callee)
|
||||
|
@ -176,10 +176,18 @@ pub fn report_method_error(
|
||||
err.emit();
|
||||
}
|
||||
|
||||
MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
|
||||
let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
|
||||
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
|
||||
let msg = if needs_mut {
|
||||
with_forced_trimmed_paths!(format!(
|
||||
"the `{item_name}` method cannot be invoked on `{rcvr_ty}`"
|
||||
))
|
||||
} else {
|
||||
format!("the `{item_name}` method cannot be invoked on a trait object")
|
||||
};
|
||||
let mut err = self.sess().struct_span_err(span, &msg);
|
||||
err.span_label(bound_span, "this has a `Sized` requirement");
|
||||
if !needs_mut {
|
||||
err.span_label(bound_span, "this has a `Sized` requirement");
|
||||
}
|
||||
if !candidates.is_empty() {
|
||||
let help = format!(
|
||||
"{an}other candidate{s} {were} found in the following trait{s}, perhaps \
|
||||
@ -197,7 +205,32 @@ pub fn report_method_error(
|
||||
*region,
|
||||
ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() },
|
||||
);
|
||||
err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
|
||||
let msg = format!("you need `{}` instead of `{}`", trait_type, rcvr_ty);
|
||||
let mut kind = &self_expr.kind;
|
||||
while let hir::ExprKind::AddrOf(_, _, expr)
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, expr) = kind
|
||||
{
|
||||
kind = &expr.kind;
|
||||
}
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
|
||||
&& let hir::def::Res::Local(hir_id) = path.res
|
||||
&& let Some(hir::Node::Pat(b)) = self.tcx.hir().find(hir_id)
|
||||
&& let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
|
||||
&& let Some(node) = self.tcx.hir().find_parent(p.hir_id)
|
||||
&& let Some(decl) = node.fn_decl()
|
||||
&& let Some(ty) = decl.inputs.iter().find(|ty| ty.span == p.ty_span)
|
||||
&& let hir::TyKind::Ref(_, mut_ty) = &ty.kind
|
||||
&& let hir::Mutability::Not = mut_ty.mutbl
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
mut_ty.ty.span.shrink_to_lo(),
|
||||
&msg,
|
||||
"mut ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.help(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
@ -0,0 +1,9 @@
|
||||
// run-rustfix
|
||||
fn test(t: &mut dyn Iterator<Item=&u64>) -> u64 {
|
||||
*t.min().unwrap() //~ ERROR the `min` method cannot be invoked on
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let array = [0u64];
|
||||
test(&mut array.iter());
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
// run-rustfix
|
||||
fn test(t: &dyn Iterator<Item=&u64>) -> u64 {
|
||||
*t.min().unwrap() //~ ERROR the `min` method cannot be invoked on
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let array = [0u64];
|
||||
test(&mut array.iter());
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
error: the `min` method cannot be invoked on `&dyn Iterator<Item = &u64>`
|
||||
--> $DIR/mutability-mismatch-arg.rs:3:9
|
||||
|
|
||||
LL | *t.min().unwrap()
|
||||
| ^^^
|
||||
|
|
||||
help: you need `&mut dyn Iterator<Item = &u64>` instead of `&dyn Iterator<Item = &u64>`
|
||||
|
|
||||
LL | fn test(t: &mut dyn Iterator<Item=&u64>) -> u64 {
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -4,7 +4,6 @@ pub trait MutTrait {
|
||||
fn function(&mut self)
|
||||
where
|
||||
Self: Sized;
|
||||
//~^ this has a `Sized` requirement
|
||||
}
|
||||
|
||||
impl MutTrait for MutType {
|
||||
@ -17,7 +16,6 @@ pub trait Trait {
|
||||
fn function(&self)
|
||||
where
|
||||
Self: Sized;
|
||||
//~^ this has a `Sized` requirement
|
||||
}
|
||||
|
||||
impl Trait for Type {
|
||||
@ -26,9 +24,9 @@ fn function(&self) {}
|
||||
|
||||
fn main() {
|
||||
(&MutType as &dyn MutTrait).function();
|
||||
//~^ ERROR the `function` method cannot be invoked on a trait object
|
||||
//~| NOTE you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
//~^ ERROR the `function` method cannot be invoked on `&dyn MutTrait`
|
||||
//~| HELP you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
(&mut Type as &mut dyn Trait).function();
|
||||
//~^ ERROR the `function` method cannot be invoked on a trait object
|
||||
//~| NOTE you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
//~^ ERROR the `function` method cannot be invoked on `&mut dyn Trait`
|
||||
//~| HELP you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
}
|
||||
|
@ -1,24 +1,18 @@
|
||||
error: the `function` method cannot be invoked on a trait object
|
||||
--> $DIR/mutability-mismatch.rs:28:33
|
||||
error: the `function` method cannot be invoked on `&dyn MutTrait`
|
||||
--> $DIR/mutability-mismatch.rs:26:33
|
||||
|
|
||||
LL | Self: Sized;
|
||||
| ----- this has a `Sized` requirement
|
||||
...
|
||||
LL | (&MutType as &dyn MutTrait).function();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
= help: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
|
||||
error: the `function` method cannot be invoked on a trait object
|
||||
--> $DIR/mutability-mismatch.rs:31:35
|
||||
error: the `function` method cannot be invoked on `&mut dyn Trait`
|
||||
--> $DIR/mutability-mismatch.rs:29:35
|
||||
|
|
||||
LL | Self: Sized;
|
||||
| ----- this has a `Sized` requirement
|
||||
...
|
||||
LL | (&mut Type as &mut dyn Trait).function();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
= help: you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
fn test(t: &dyn Iterator<Item=&u64>) -> u64 {
|
||||
t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object
|
||||
t.min().unwrap() //~ ERROR the `min` method cannot be invoked on `&dyn Iterator<Item = &u64>`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,13 +1,13 @@
|
||||
error: the `min` method cannot be invoked on a trait object
|
||||
error: the `min` method cannot be invoked on `&dyn Iterator<Item = &u64>`
|
||||
--> $DIR/imm-ref-trait-object.rs:2:8
|
||||
|
|
||||
LL | t.min().unwrap()
|
||||
| ^^^
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
= note: this has a `Sized` requirement
|
||||
help: you need `&mut dyn Iterator<Item = &u64>` instead of `&dyn Iterator<Item = &u64>`
|
||||
|
|
||||
= note: you need `&mut dyn Iterator<Item = &u64>` instead of `&dyn Iterator<Item = &u64>`
|
||||
LL | fn test(t: &mut dyn Iterator<Item=&u64>) -> u64 {
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user