1717: Don't add `?` bounds as real bounds r=flodiebold a=matklad

closes #1709


Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-08-22 13:13:07 +00:00 committed by GitHub
commit 79a46f2588
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 0 deletions

View file

@ -75,6 +75,7 @@ impl GenericParams {
}; };
generics.parent_params = parent.map(|p| db.generic_params(p)); generics.parent_params = parent.map(|p| db.generic_params(p));
let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
// FIXME: add `: Sized` bound for everything except for `Self` in traits
match def { match def {
GenericDef::Function(it) => generics.fill(&it.source(db).ast, start), GenericDef::Function(it) => generics.fill(&it.source(db).ast, start),
GenericDef::Struct(it) => generics.fill(&it.source(db).ast, start), GenericDef::Struct(it) => generics.fill(&it.source(db).ast, start),
@ -86,6 +87,9 @@ impl GenericParams {
generics.fill(&it.source(db).ast, start + 1); generics.fill(&it.source(db).ast, start + 1);
} }
GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start),
// Note that we don't add `Self` here: in `impl`s, `Self` is not a
// type-parameter, but rather is a type-alias for impl's target
// type, so this is handled by the resovler.
GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start), GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start),
GenericDef::EnumVariant(_) => {} GenericDef::EnumVariant(_) => {}
} }
@ -135,6 +139,10 @@ impl GenericParams {
} }
fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) {
if bound.has_question_mark() {
// FIXME: remove this bound
return;
}
let path = bound let path = bound
.type_ref() .type_ref()
.and_then(|tr| match tr { .and_then(|tr| match tr {

View file

@ -3028,6 +3028,35 @@ fn test(s: S) {
assert_eq!(t, "{unknown}"); assert_eq!(t, "{unknown}");
} }
#[test]
fn deref_trait_with_question_mark_size() {
let t = type_at(
r#"
//- /main.rs
#[lang = "deref"]
trait Deref {
type Target;
fn deref(&self) -> &Self::Target;
}
struct Arc<T>;
impl<T: ?Sized> Deref for Arc<T> {
type Target = T;
}
struct S;
impl S {
fn foo(&self) -> u128 {}
}
fn test(s: Arc<S>) {
(*s, s.foo())<|>
}
"#,
);
assert_eq!(t, "(S, u128)");
}
#[test] #[test]
fn obligation_from_function_clause() { fn obligation_from_function_clause() {
let t = type_at( let t = type_at(

View file

@ -382,6 +382,18 @@ impl ast::WherePred {
} }
} }
impl ast::TypeBound {
pub fn question_mark_token(&self) -> Option<SyntaxToken> {
self.syntax()
.children_with_tokens()
.filter_map(|it| it.into_token())
.find(|it| it.kind() == T![?])
}
pub fn has_question_mark(&self) -> bool {
self.question_mark_token().is_some()
}
}
impl ast::TraitDef { impl ast::TraitDef {
pub fn is_auto(&self) -> bool { pub fn is_auto(&self) -> bool {
self.syntax().children_with_tokens().any(|t| t.kind() == T![auto]) self.syntax().children_with_tokens().any(|t| t.kind() == T![auto])