Skip to content

Commit 5911914

Browse files
Resolve self type alias in impl for RTN
1 parent a43f564 commit 5911914

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19271927
// from the generics of the parameter's definition, since we want
19281928
// to be able to resolve an RTN path on a nested body (e.g. method
19291929
// inside an impl) using the where clauses on the method.
1930+
// FIXME(return_type_notation): Think of some better way of doing this.
19301931
let Some(generics) = self.tcx.hir_owner_node(hir_id.owner).generics()
19311932
else {
19321933
return;
@@ -1965,7 +1966,30 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19651966
};
19661967
(bound_vars, assoc_item.def_id, item_segment)
19671968
}
1968-
Res::SelfTyAlias { is_trait_impl: true, .. } => todo!(),
1969+
// If we have a self type alias (in an impl), try to resolve an
1970+
// associated item from one of the supertraits of the impl's trait.
1971+
Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. } => {
1972+
let hir::ItemKind::Impl(hir::Impl { of_trait: Some(trait_ref), .. }) = self
1973+
.tcx
1974+
.hir_node_by_def_id(impl_def_id.expect_local())
1975+
.expect_item()
1976+
.kind
1977+
else {
1978+
return;
1979+
};
1980+
let Some(trait_def_id) = trait_ref.trait_def_id() else {
1981+
return;
1982+
};
1983+
let Some((bound_vars, assoc_item)) = BoundVarContext::supertrait_hrtb_vars(
1984+
self.tcx,
1985+
trait_def_id,
1986+
item_segment.ident,
1987+
ty::AssocKind::Fn,
1988+
) else {
1989+
return;
1990+
};
1991+
(bound_vars, assoc_item.def_id, item_segment)
1992+
}
19691993
_ => return,
19701994
}
19711995
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ check-pass
2+
3+
#![feature(return_type_notation)]
4+
//~^ WARN the feature `return_type_notation` is incomplete
5+
6+
trait Trait {
7+
fn method() -> impl Sized;
8+
}
9+
10+
fn is_send(_: impl Send) {}
11+
12+
struct W<T>(T);
13+
14+
impl<T> W<T> {
15+
fn test()
16+
where
17+
T: Trait,
18+
T::method(..): Send,
19+
{
20+
is_send(T::method());
21+
}
22+
}
23+
24+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/path-constrained-in-method.rs:3:12
3+
|
4+
LL | #![feature(return_type_notation)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

tests/ui/associated-type-bounds/return-type-notation/path-self-qself.rs

+11
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,15 @@ trait Bar: Foo {
1313
Self::method(..): Send;
1414
}
1515

16+
fn is_send(_: impl Send) {}
17+
18+
impl<T: Foo> Bar for T {
19+
fn other()
20+
where
21+
Self::method(..): Send,
22+
{
23+
is_send(Self::method());
24+
}
25+
}
26+
1627
fn main() {}

0 commit comments

Comments
 (0)