Properly compare types for Option::as_deref
suggestion
This commit is contained in:
parent
e4106065bf
commit
896ccb9606
6 changed files with 54 additions and 38 deletions
|
@ -3593,7 +3593,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
&& let Some(deref_target_did) = tcx.lang_items().deref_target()
|
&& let Some(deref_target_did) = tcx.lang_items().deref_target()
|
||||||
&& let projection = tcx.mk_projection(deref_target_did, tcx.mk_substs(&[ty::GenericArg::from(found_ty)]))
|
&& let projection = tcx.mk_projection(deref_target_did, tcx.mk_substs(&[ty::GenericArg::from(found_ty)]))
|
||||||
&& let Ok(deref_target) = tcx.try_normalize_erasing_regions(param_env, projection)
|
&& let Ok(deref_target) = tcx.try_normalize_erasing_regions(param_env, projection)
|
||||||
&& deref_target == target_ty
|
&& infcx.can_eq(param_env, deref_target, target_ty)
|
||||||
{
|
{
|
||||||
let help = if let hir::Mutability::Mut = needs_mut
|
let help = if let hir::Mutability::Mut = needs_mut
|
||||||
&& let Some(deref_mut_did) = tcx.lang_items().deref_mut_trait()
|
&& let Some(deref_mut_did) = tcx.lang_items().deref_mut_trait()
|
||||||
|
|
|
@ -10,10 +10,6 @@ fn no_args() -> Option<()> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generic_ref<T>(_: &T) -> Option<()> {
|
|
||||||
Some(())
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" fn takes_str_but_wrong_abi(_: &str) -> Option<()> {
|
extern "C" fn takes_str_but_wrong_abi(_: &str) -> Option<()> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
@ -33,8 +29,6 @@ fn main() {
|
||||||
//~^ ERROR expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
|
//~^ ERROR expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
|
||||||
let _ = produces_string().and_then(no_args);
|
let _ = produces_string().and_then(no_args);
|
||||||
//~^ ERROR function is expected to take 1 argument, but it takes 0 arguments
|
//~^ ERROR function is expected to take 1 argument, but it takes 0 arguments
|
||||||
let _ = produces_string().and_then(generic_ref);
|
|
||||||
//~^ ERROR type mismatch in function arguments
|
|
||||||
let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
|
let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
|
||||||
//~^ ERROR type mismatch in function arguments
|
//~^ ERROR type mismatch in function arguments
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0631]: type mismatch in function arguments
|
error[E0631]: type mismatch in function arguments
|
||||||
--> $DIR/suggest-option-asderef-unfixable.rs:28:40
|
--> $DIR/suggest-option-asderef-unfixable.rs:24:40
|
||||||
|
|
|
|
||||||
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
|
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
|
||||||
| ------------------------------------------------------ found signature defined here
|
| ------------------------------------------------------ found signature defined here
|
||||||
|
@ -15,7 +15,7 @@ note: required by a bound in `Option::<T>::and_then`
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: expected a `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
|
error[E0277]: expected a `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
|
||||||
--> $DIR/suggest-option-asderef-unfixable.rs:30:40
|
--> $DIR/suggest-option-asderef-unfixable.rs:26:40
|
||||||
|
|
|
|
||||||
LL | let _ = produces_string().and_then(takes_str_but_wrong_abi);
|
LL | let _ = produces_string().and_then(takes_str_but_wrong_abi);
|
||||||
| -------- ^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
|
| -------- ^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
|
||||||
|
@ -27,7 +27,7 @@ note: required by a bound in `Option::<T>::and_then`
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
|
error[E0277]: expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
|
||||||
--> $DIR/suggest-option-asderef-unfixable.rs:32:40
|
--> $DIR/suggest-option-asderef-unfixable.rs:28:40
|
||||||
|
|
|
|
||||||
LL | let _ = produces_string().and_then(takes_str_but_unsafe);
|
LL | let _ = produces_string().and_then(takes_str_but_unsafe);
|
||||||
| -------- ^^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
|
| -------- ^^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
|
||||||
|
@ -40,7 +40,7 @@ note: required by a bound in `Option::<T>::and_then`
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||||
|
|
||||||
error[E0593]: function is expected to take 1 argument, but it takes 0 arguments
|
error[E0593]: function is expected to take 1 argument, but it takes 0 arguments
|
||||||
--> $DIR/suggest-option-asderef-unfixable.rs:34:40
|
--> $DIR/suggest-option-asderef-unfixable.rs:30:40
|
||||||
|
|
|
|
||||||
LL | fn no_args() -> Option<()> {
|
LL | fn no_args() -> Option<()> {
|
||||||
| -------------------------- takes 0 arguments
|
| -------------------------- takes 0 arguments
|
||||||
|
@ -54,28 +54,7 @@ note: required by a bound in `Option::<T>::and_then`
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||||
|
|
||||||
error[E0631]: type mismatch in function arguments
|
error[E0631]: type mismatch in function arguments
|
||||||
--> $DIR/suggest-option-asderef-unfixable.rs:36:40
|
--> $DIR/suggest-option-asderef-unfixable.rs:32:45
|
||||||
|
|
|
||||||
LL | fn generic_ref<T>(_: &T) -> Option<()> {
|
|
||||||
| -------------------------------------- found signature defined here
|
|
||||||
...
|
|
||||||
LL | let _ = produces_string().and_then(generic_ref);
|
|
||||||
| -------- ^^^^^^^^^^^ expected due to this
|
|
||||||
| |
|
|
||||||
| required by a bound introduced by this call
|
|
||||||
|
|
|
||||||
= note: expected function signature `fn(String) -> _`
|
|
||||||
found function signature `for<'a> fn(&'a _) -> _`
|
|
||||||
note: required by a bound in `Option::<T>::and_then`
|
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
|
||||||
help: do not borrow the argument
|
|
||||||
|
|
|
||||||
LL - fn generic_ref<T>(_: &T) -> Option<()> {
|
|
||||||
LL + fn generic_ref<T>(_: T) -> Option<()> {
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0631]: type mismatch in function arguments
|
|
||||||
--> $DIR/suggest-option-asderef-unfixable.rs:38:45
|
|
||||||
|
|
|
|
||||||
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
|
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
|
||||||
| ------------------------------------------------------ found signature defined here
|
| ------------------------------------------------------ found signature defined here
|
||||||
|
@ -90,7 +69,7 @@ LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
|
||||||
note: required by a bound in `Option::<T>::and_then`
|
note: required by a bound in `Option::<T>::and_then`
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0593, E0631.
|
Some errors have detailed explanations: E0277, E0593, E0631.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -16,6 +16,11 @@ fn generic<T>(_: T) -> Option<()> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generic_ref<T>(_: T) -> Option<()> {
|
||||||
|
//~^ HELP do not borrow the argument
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: Option<()> = produces_string().as_deref().and_then(takes_str);
|
let _: Option<()> = produces_string().as_deref().and_then(takes_str);
|
||||||
//~^ ERROR type mismatch in function arguments
|
//~^ ERROR type mismatch in function arguments
|
||||||
|
@ -27,4 +32,8 @@ fn main() {
|
||||||
//~^ ERROR type mismatch in function arguments
|
//~^ ERROR type mismatch in function arguments
|
||||||
//~| HELP call `Option::as_deref_mut()` first
|
//~| HELP call `Option::as_deref_mut()` first
|
||||||
let _ = produces_string().and_then(generic);
|
let _ = produces_string().and_then(generic);
|
||||||
|
|
||||||
|
let _ = produces_string().as_deref().and_then(generic_ref);
|
||||||
|
//~^ ERROR type mismatch in function arguments
|
||||||
|
//~| HELP call `Option::as_deref()` first
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,11 @@ fn generic<T>(_: T) -> Option<()> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generic_ref<T>(_: &T) -> Option<()> {
|
||||||
|
//~^ HELP do not borrow the argument
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: Option<()> = produces_string().and_then(takes_str);
|
let _: Option<()> = produces_string().and_then(takes_str);
|
||||||
//~^ ERROR type mismatch in function arguments
|
//~^ ERROR type mismatch in function arguments
|
||||||
|
@ -27,4 +32,8 @@ fn main() {
|
||||||
//~^ ERROR type mismatch in function arguments
|
//~^ ERROR type mismatch in function arguments
|
||||||
//~| HELP call `Option::as_deref_mut()` first
|
//~| HELP call `Option::as_deref_mut()` first
|
||||||
let _ = produces_string().and_then(generic);
|
let _ = produces_string().and_then(generic);
|
||||||
|
|
||||||
|
let _ = produces_string().and_then(generic_ref);
|
||||||
|
//~^ ERROR type mismatch in function arguments
|
||||||
|
//~| HELP call `Option::as_deref()` first
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0631]: type mismatch in function arguments
|
error[E0631]: type mismatch in function arguments
|
||||||
--> $DIR/suggest-option-asderef.rs:20:52
|
--> $DIR/suggest-option-asderef.rs:25:52
|
||||||
|
|
|
|
||||||
LL | fn takes_str(_: &str) -> Option<()> {
|
LL | fn takes_str(_: &str) -> Option<()> {
|
||||||
| ----------------------------------- found signature defined here
|
| ----------------------------------- found signature defined here
|
||||||
|
@ -19,7 +19,7 @@ LL | let _: Option<()> = produces_string().as_deref().and_then(takes_str);
|
||||||
| +++++++++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0631]: type mismatch in function arguments
|
error[E0631]: type mismatch in function arguments
|
||||||
--> $DIR/suggest-option-asderef.rs:23:55
|
--> $DIR/suggest-option-asderef.rs:28:55
|
||||||
|
|
|
|
||||||
LL | fn takes_str(_: &str) -> Option<()> {
|
LL | fn takes_str(_: &str) -> Option<()> {
|
||||||
| ----------------------------------- found signature defined here
|
| ----------------------------------- found signature defined here
|
||||||
|
@ -39,7 +39,7 @@ LL | let _: Option<Option<()>> = produces_string().as_deref().map(takes_str)
|
||||||
| +++++++++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0631]: type mismatch in function arguments
|
error[E0631]: type mismatch in function arguments
|
||||||
--> $DIR/suggest-option-asderef.rs:26:55
|
--> $DIR/suggest-option-asderef.rs:31:55
|
||||||
|
|
|
|
||||||
LL | fn takes_str_mut(_: &mut str) -> Option<()> {
|
LL | fn takes_str_mut(_: &mut str) -> Option<()> {
|
||||||
| ------------------------------------------- found signature defined here
|
| ------------------------------------------- found signature defined here
|
||||||
|
@ -58,6 +58,31 @@ help: call `Option::as_deref_mut()` first
|
||||||
LL | let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut);
|
LL | let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut);
|
||||||
| +++++++++++++++
|
| +++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0631]: type mismatch in function arguments
|
||||||
|
--> $DIR/suggest-option-asderef.rs:36:40
|
||||||
|
|
|
||||||
|
LL | fn generic_ref<T>(_: &T) -> Option<()> {
|
||||||
|
| -------------------------------------- found signature defined here
|
||||||
|
...
|
||||||
|
LL | let _ = produces_string().and_then(generic_ref);
|
||||||
|
| -------- ^^^^^^^^^^^ expected due to this
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= note: expected function signature `fn(String) -> _`
|
||||||
|
found function signature `for<'a> fn(&'a _) -> _`
|
||||||
|
note: required by a bound in `Option::<T>::and_then`
|
||||||
|
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||||
|
help: do not borrow the argument
|
||||||
|
|
|
||||||
|
LL - fn generic_ref<T>(_: &T) -> Option<()> {
|
||||||
|
LL + fn generic_ref<T>(_: T) -> Option<()> {
|
||||||
|
|
|
||||||
|
help: call `Option::as_deref()` first
|
||||||
|
|
|
||||||
|
LL | let _ = produces_string().as_deref().and_then(generic_ref);
|
||||||
|
| +++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0631`.
|
For more information about this error, try `rustc --explain E0631`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue