Skip to content

Commit

Permalink
Account for Self as a type param
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed May 28, 2020
1 parent f213acf commit 1bd6970
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) =>
Expand All @@ -143,5 +146,6 @@ impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
},
_ => {}
}
hir::intravisit::walk_ty(self, arg);
}
}
53 changes: 53 additions & 0 deletions src/test/ui/traits/self-without-lifetime-constraint.rs
Original file line number Diff line number Diff line change
@@ -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");
}
19 changes: 19 additions & 0 deletions src/test/ui/traits/self-without-lifetime-constraint.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 1bd6970

Please sign in to comment.