Make diagnostics clearer for ?
operators
This commit is contained in:
parent
78a46efff0
commit
378300a63d
@ -74,6 +74,10 @@ pub fn normal<S: Into<String>>(t: S) -> DiagnosticStyledString {
|
||||
pub fn highlighted<S: Into<String>>(t: S) -> DiagnosticStyledString {
|
||||
DiagnosticStyledString(vec![StringPart::Highlighted(t.into())])
|
||||
}
|
||||
|
||||
pub fn content(&self) -> String {
|
||||
self.0.iter().map(|x| x.content()).collect::<String>()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@ -82,6 +86,14 @@ pub enum StringPart {
|
||||
Highlighted(String),
|
||||
}
|
||||
|
||||
impl StringPart {
|
||||
pub fn content(&self) -> &str {
|
||||
match self {
|
||||
&StringPart::Normal(ref s) | &StringPart::Highlighted(ref s) => s,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
pub fn new(level: Level, message: &str) -> Self {
|
||||
Diagnostic::new_with_code(level, None, message)
|
||||
|
@ -1971,6 +1971,8 @@ pub fn report_and_explain_type_error(
|
||||
trace: TypeTrace<'tcx>,
|
||||
terr: &TypeError<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
use crate::traits::ObligationCauseCode::MatchExpressionArm;
|
||||
|
||||
debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
|
||||
|
||||
let span = trace.cause.span(self.tcx);
|
||||
@ -2013,6 +2015,19 @@ pub fn report_and_explain_type_error(
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if let MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =
|
||||
trace.cause.code
|
||||
{
|
||||
if let hir::MatchSource::TryDesugar = source {
|
||||
if let Some((expected_ty, found_ty)) = self.values_str(trace.values) {
|
||||
err.note(&format!(
|
||||
"`?` operator cannot convert from `{}` to `{}`",
|
||||
found_ty.content(),
|
||||
expected_ty.content(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
err
|
||||
}
|
||||
FailureCode::Error0644(failure_str) => {
|
||||
@ -2585,9 +2600,7 @@ fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
|
||||
CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
|
||||
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
|
||||
Error0308(match source {
|
||||
hir::MatchSource::TryDesugar => {
|
||||
"try expression alternatives have incompatible types"
|
||||
}
|
||||
hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
|
||||
_ => "`match` arms have incompatible types",
|
||||
})
|
||||
}
|
||||
|
7
src/test/ui/inference/issue-71309.rs
Normal file
7
src/test/ui/inference/issue-71309.rs
Normal file
@ -0,0 +1,7 @@
|
||||
fn foo(x: Result<i32, ()>) -> Result<(), ()> {
|
||||
let y: u32 = x?;
|
||||
//~^ ERROR: `?` operator has incompatible types
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/inference/issue-71309.stderr
Normal file
15
src/test/ui/inference/issue-71309.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0308]: `?` operator has incompatible types
|
||||
--> $DIR/issue-71309.rs:2:18
|
||||
|
|
||||
LL | let y: u32 = x?;
|
||||
| ^^ expected `u32`, found `i32`
|
||||
|
|
||||
= note: `?` operator cannot convert from `i32` to `u32`
|
||||
help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
|
||||
|
|
||||
LL | let y: u32 = x?.try_into().unwrap();
|
||||
| ++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -6,7 +6,7 @@ fn missing_discourses() -> Result<isize, ()> {
|
||||
|
||||
fn forbidden_narratives() -> Result<isize, ()> {
|
||||
missing_discourses()?
|
||||
//~^ ERROR try expression alternatives have incompatible types
|
||||
//~^ ERROR: `?` operator has incompatible types
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,10 @@
|
||||
error[E0308]: try expression alternatives have incompatible types
|
||||
error[E0308]: `?` operator has incompatible types
|
||||
--> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
|
||||
|
|
||||
LL | missing_discourses()?
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `isize`
|
||||
|
|
||||
= note: `?` operator cannot convert from `isize` to `Result<isize, ()>`
|
||||
= note: expected enum `Result<isize, ()>`
|
||||
found type `isize`
|
||||
help: try removing this `?`
|
||||
|
Loading…
Reference in New Issue
Block a user