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 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)
|
||||
&& deref_target == target_ty
|
||||
&& infcx.can_eq(param_env, deref_target, target_ty)
|
||||
{
|
||||
let help = if let hir::Mutability::Mut = needs_mut
|
||||
&& let Some(deref_mut_did) = tcx.lang_items().deref_mut_trait()
|
||||
|
|
|
@ -10,10 +10,6 @@ fn no_args() -> Option<()> {
|
|||
Some(())
|
||||
}
|
||||
|
||||
fn generic_ref<T>(_: &T) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
||||
extern "C" fn takes_str_but_wrong_abi(_: &str) -> Option<()> {
|
||||
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}`
|
||||
let _ = produces_string().and_then(no_args);
|
||||
//~^ 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);
|
||||
//~^ ERROR type mismatch in function arguments
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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<()> {
|
||||
| ------------------------------------------------------ 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
|
||||
|
||||
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);
|
||||
| -------- ^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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);
|
||||
| -------- ^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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<()> {
|
||||
| -------------------------- 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
|
||||
|
||||
error[E0631]: type mismatch in function arguments
|
||||
--> $DIR/suggest-option-asderef-unfixable.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<()> {
|
||||
|
|
||||
|
||||
error[E0631]: type mismatch in function arguments
|
||||
--> $DIR/suggest-option-asderef-unfixable.rs:38:45
|
||||
--> $DIR/suggest-option-asderef-unfixable.rs:32:45
|
||||
|
|
||||
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
|
||||
| ------------------------------------------------------ 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`
|
||||
--> $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.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -16,6 +16,11 @@ fn generic<T>(_: T) -> Option<()> {
|
|||
Some(())
|
||||
}
|
||||
|
||||
fn generic_ref<T>(_: T) -> Option<()> {
|
||||
//~^ HELP do not borrow the argument
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: Option<()> = produces_string().as_deref().and_then(takes_str);
|
||||
//~^ ERROR type mismatch in function arguments
|
||||
|
@ -27,4 +32,8 @@ fn main() {
|
|||
//~^ ERROR type mismatch in function arguments
|
||||
//~| HELP call `Option::as_deref_mut()` first
|
||||
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(())
|
||||
}
|
||||
|
||||
fn generic_ref<T>(_: &T) -> Option<()> {
|
||||
//~^ HELP do not borrow the argument
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: Option<()> = produces_string().and_then(takes_str);
|
||||
//~^ ERROR type mismatch in function arguments
|
||||
|
@ -27,4 +32,8 @@ fn main() {
|
|||
//~^ ERROR type mismatch in function arguments
|
||||
//~| HELP call `Option::as_deref_mut()` first
|
||||
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
|
||||
--> $DIR/suggest-option-asderef.rs:20:52
|
||||
--> $DIR/suggest-option-asderef.rs:25:52
|
||||
|
|
||||
LL | fn takes_str(_: &str) -> Option<()> {
|
||||
| ----------------------------------- 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
|
||||
--> $DIR/suggest-option-asderef.rs:23:55
|
||||
--> $DIR/suggest-option-asderef.rs:28:55
|
||||
|
|
||||
LL | fn takes_str(_: &str) -> Option<()> {
|
||||
| ----------------------------------- 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
|
||||
--> $DIR/suggest-option-asderef.rs:26:55
|
||||
--> $DIR/suggest-option-asderef.rs:31:55
|
||||
|
|
||||
LL | fn takes_str_mut(_: &mut str) -> Option<()> {
|
||||
| ------------------------------------------- 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);
|
||||
| +++++++++++++++
|
||||
|
||||
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`.
|
||||
|
|
Loading…
Add table
Reference in a new issue