Account for `Self` as a type param

This commit is contained in:
Esteban Küber 2020-05-28 10:35:48 -07:00
parent f213acf4db
commit 1bd69702de
3 changed files with 79 additions and 3 deletions

View File

@ -6,6 +6,7 @@ use crate::infer::{Subtype, TyCtxtInferExt, ValuePairs};
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_middle::ty::error::ExpectedFound;
@ -124,15 +125,17 @@ impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
match arg.kind {
hir::TyKind::Slice(_) | hir::TyKind::Tup(_) | hir::TyKind::Array(..) => {
hir::intravisit::walk_ty(self, arg);
hir::TyKind::Rptr(_, ref mut_ty) => {
// We don't want to suggest looking into borrowing `&T` or `&Self`.
hir::intravisit::walk_ty(self, mut_ty.ty);
return;
}
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
[segment]
if segment
.res
.map(|res| match res {
hir::def::Res::Def(hir::def::DefKind::TyParam, _) => true,
Res::SelfTy(_, _) | Res::Def(hir::def::DefKind::TyParam, _) => true,
_ => false,
})
.unwrap_or(false) =>
@ -143,5 +146,6 @@ impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
},
_ => {}
}
hir::intravisit::walk_ty(self, arg);
}
}

View File

@ -0,0 +1,53 @@
use std::error::Error;
use std::fmt;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ValueRef<'a> {
Null,
Integer(i64),
Real(f64),
Text(&'a [u8]),
Blob(&'a [u8]),
}
impl<'a> ValueRef<'a> {
pub fn as_str(&self) -> FromSqlResult<&'a str, &'a &'a str> {
match *self {
ValueRef::Text(t) => {
std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType).map(|x| (x, &x))
}
_ => Err(FromSqlError::InvalidType),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum FromSqlError {
InvalidType
}
impl fmt::Display for FromSqlError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "InvalidType")
}
}
impl Error for FromSqlError {}
pub type FromSqlResult<T, K> = Result<(T, K), FromSqlError>;
pub trait FromSql: Sized {
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
}
impl FromSql for &str {
fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> {
//~^ ERROR `impl` item signature doesn't match `trait` item signature
value.as_str()
}
}
pub fn main() {
println!("{}", "Hello World");
}

View File

@ -0,0 +1,19 @@
error: `impl` item signature doesn't match `trait` item signature
--> $DIR/self-without-lifetime-constraint.rs:45:5
|
LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
| -------------------------------------------------------------------- expected `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), FromSqlError>`
...
LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), FromSqlError>`
|
= note: expected `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), _>`
found `fn(ValueRef<'_>) -> std::result::Result<(&str, &&str), _>`
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
--> $DIR/self-without-lifetime-constraint.rs:41:60
|
LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
| ^^^^ consider borrowing this type parameter in the trait
error: aborting due to previous error