1
Fork 0

Incorporate feedback

This commit is contained in:
mejrs 2022-09-19 17:19:45 +02:00
parent 14e9893023
commit c65866000e
5 changed files with 74 additions and 88 deletions

View file

@ -1656,82 +1656,39 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}; };
enum Similar<'tcx> { enum Similar<'tcx> {
Adts(ty::AdtDef<'tcx>, ty::AdtDef<'tcx>), Adts { expected: ty::AdtDef<'tcx>, found: ty::AdtDef<'tcx> },
PrimitiveFound(Ty<'tcx>, ty::AdtDef<'tcx>), PrimitiveFound { expected: ty::AdtDef<'tcx>, found: Ty<'tcx> },
PrimitiveExpected(ty::AdtDef<'tcx>, Ty<'tcx>), PrimitiveExpected { expected: Ty<'tcx>, found: ty::AdtDef<'tcx> },
} }
let primitive_sym = |kind: &_| match kind { let similarity = |ExpectedFound { expected, found }: ExpectedFound<Ty<'tcx>>| {
ty::Bool => Some(sym::bool), if let ty::Adt(expected, _) = expected.kind() && let Some(primitive) = found.primitive_symbol() {
ty::Char => Some(sym::char), let path = self.tcx.def_path(expected.did()).data;
ty::Float(f) => match f { let name = path.last().unwrap().data.get_opt_name();
ty::FloatTy::F32 => Some(sym::f32), if name == Some(primitive) {
ty::FloatTy::F64 => Some(sym::f64), return Some(Similar::PrimitiveFound { expected: *expected, found });
},
ty::Int(f) => match f {
ty::IntTy::Isize => Some(sym::isize),
ty::IntTy::I8 => Some(sym::i8),
ty::IntTy::I16 => Some(sym::i16),
ty::IntTy::I32 => Some(sym::i32),
ty::IntTy::I64 => Some(sym::i64),
ty::IntTy::I128 => Some(sym::i128),
},
ty::Uint(f) => match f {
ty::UintTy::Usize => Some(sym::usize),
ty::UintTy::U8 => Some(sym::u8),
ty::UintTy::U16 => Some(sym::u16),
ty::UintTy::U32 => Some(sym::u32),
ty::UintTy::U64 => Some(sym::u64),
ty::UintTy::U128 => Some(sym::u128),
},
_ => None,
};
let similarity = |e: ExpectedFound<Ty<'tcx>>| {
let (fk, ek) = (e.found.kind(), e.expected.kind());
match (fk, ek) {
(
ty::Adt(adt, _),
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_),
) => {
let path = self.tcx.def_path(adt.did()).data;
let name = path.last().unwrap().data.get_opt_name();
let prim_sym = primitive_sym(ek);
if name == prim_sym {
return Some(Similar::PrimitiveExpected(*adt, e.expected));
}
None
} }
( } else if let Some(primitive) = expected.primitive_symbol() && let ty::Adt(found, _) = found.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_), let path = self.tcx.def_path(found.did()).data;
ty::Adt(adt, _), let name = path.last().unwrap().data.get_opt_name();
) => { if name == Some(primitive) {
let path = self.tcx.def_path(adt.did()).data; return Some(Similar::PrimitiveExpected { expected, found: *found });
let name = path.last().unwrap().data.get_opt_name(); }
let prim_sym = primitive_sym(fk); } else if let ty::Adt(expected, _) = expected.kind() && let ty::Adt(found, _) = found.kind() {
if !expected.did().is_local() && expected.did().krate == found.did().krate {
// Most likely types from different versions of the same crate
// are in play, in which case this message isn't so helpful.
// A "perhaps two different versions..." error is already emitted for that.
return None;
}
let f_path = self.tcx.def_path(found.did()).data;
let e_path = self.tcx.def_path(expected.did()).data;
if name == prim_sym { if let (Some(e_last), Some(f_last)) = (e_path.last(), f_path.last()) && e_last == f_last {
return Some(Similar::PrimitiveFound(e.expected, *adt)); return Some(Similar::Adts{expected: *expected, found: *found});
}
None
} }
(ty::Adt(f, _), ty::Adt(e, _)) => {
if !f.did().is_local() && f.did().krate == e.did().krate {
// Most likely types from different versions of the same crate
// are in play, in which case this message isn't so helpful.
// A "perhaps two different versions..." error is already emitted for that.
return None;
}
let e_path = self.tcx.def_path(e.did()).data;
let f_path = self.tcx.def_path(f.did()).data;
if let (Some(e_last), Some(f_last)) = (e_path.last(), f_path.last()) && e_last == f_last {
return Some(Similar::Adts(*f, *e));
}
None
}
_ => None,
} }
None
}; };
match terr { match terr {
@ -1759,8 +1716,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}; };
let diagnose_adts = let diagnose_adts =
|found_adt: ty::AdtDef<'tcx>, |expected_adt : ty::AdtDef<'tcx>,
expected_adt: ty::AdtDef<'tcx>, found_adt: ty::AdtDef<'tcx>,
diagnostic: &mut Diagnostic| { diagnostic: &mut Diagnostic| {
let found_name = values.found.sort_string(self.tcx); let found_name = values.found.sort_string(self.tcx);
let expected_name = values.expected.sort_string(self.tcx); let expected_name = values.expected.sort_string(self.tcx);
@ -1792,14 +1749,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}; };
match s { match s {
Similar::Adts(found_adt, expected_adt) => { Similar::Adts{expected, found} => {
diagnose_adts(found_adt, expected_adt, diag) diagnose_adts(expected, found, diag)
} }
Similar::PrimitiveFound(prim, e) => { Similar::PrimitiveFound{expected, found: prim} => {
diagnose_primitive(prim, values.expected, e.did(), diag) diagnose_primitive(prim, values.expected, expected.did(), diag)
} }
Similar::PrimitiveExpected(f, prim) => { Similar::PrimitiveExpected{expected: prim, found} => {
diagnose_primitive(prim, values.found, f.did(), diag) diagnose_primitive(prim, values.found, found.did(), diag)
} }
} }
} }

View file

@ -19,7 +19,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_span::symbol::{kw, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi; use rustc_target::spec::abi;
use std::borrow::Cow; use std::borrow::Cow;
@ -2274,6 +2274,35 @@ impl<'tcx> Ty<'tcx> {
} }
} }
} }
// If `self` is a primitive, return its [`Symbol`].
pub fn primitive_symbol(self) -> Option<Symbol> {
match self.kind() {
ty::Bool => Some(sym::bool),
ty::Char => Some(sym::char),
ty::Float(f) => match f {
ty::FloatTy::F32 => Some(sym::f32),
ty::FloatTy::F64 => Some(sym::f64),
},
ty::Int(f) => match f {
ty::IntTy::Isize => Some(sym::isize),
ty::IntTy::I8 => Some(sym::i8),
ty::IntTy::I16 => Some(sym::i16),
ty::IntTy::I32 => Some(sym::i32),
ty::IntTy::I64 => Some(sym::i64),
ty::IntTy::I128 => Some(sym::i128),
},
ty::Uint(f) => match f {
ty::UintTy::Usize => Some(sym::usize),
ty::UintTy::U8 => Some(sym::u8),
ty::UintTy::U16 => Some(sym::u16),
ty::UintTy::U32 => Some(sym::u32),
ty::UintTy::U64 => Some(sym::u64),
ty::UintTy::U128 => Some(sym::u128),
},
_ => None,
}
}
} }
/// Extra information about why we ended up with a particular variance. /// Extra information about why we ended up with a particular variance.

View file

@ -1,10 +1,10 @@
pub mod blah{ pub mod blah {
pub mod baz{ pub mod baz {
pub struct Foo; pub struct Foo;
} }
} }
pub mod meh{ pub mod meh {
pub struct Foo; pub struct Foo;
} }
@ -15,4 +15,4 @@ fn foo() -> Foo {
//~^ ERROR mismatched types [E0308] //~^ ERROR mismatched types [E0308]
} }
fn main(){} fn main() {}

View file

@ -1,11 +1,11 @@
enum Option<T>{ enum Option<T> {
Some(T), Some(T),
None, None,
} }
pub fn foo() -> Option<u8>{ pub fn foo() -> Option<u8> {
Some(42_u8) Some(42_u8)
//~^ ERROR mismatched types [E0308] //~^ ERROR mismatched types [E0308]
} }
fn main(){} fn main() {}

View file

@ -1,7 +1,7 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/similar_paths.rs:7:5 --> $DIR/similar_paths.rs:7:5
| |
LL | pub fn foo() -> Option<u8>{ LL | pub fn foo() -> Option<u8> {
| ---------- expected `Option<u8>` because of return type | ---------- expected `Option<u8>` because of return type
LL | Some(42_u8) LL | Some(42_u8)
| ^^^^^^^^^^^ expected enum `Option`, found enum `std::option::Option` | ^^^^^^^^^^^ expected enum `Option`, found enum `std::option::Option`
@ -15,7 +15,7 @@ LL | pub enum Option<T> {
note: enum `Option` is defined in the current crate note: enum `Option` is defined in the current crate
--> $DIR/similar_paths.rs:1:1 --> $DIR/similar_paths.rs:1:1
| |
LL | enum Option<T>{ LL | enum Option<T> {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error