Skip to content

Commit

Permalink
Resolve self type alias in impl for RTN
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 26, 2024
1 parent a43f564 commit 5911914
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
26 changes: 25 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// from the generics of the parameter's definition, since we want
// to be able to resolve an RTN path on a nested body (e.g. method
// inside an impl) using the where clauses on the method.
// FIXME(return_type_notation): Think of some better way of doing this.
let Some(generics) = self.tcx.hir_owner_node(hir_id.owner).generics()
else {
return;
Expand Down Expand Up @@ -1965,7 +1966,30 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
};
(bound_vars, assoc_item.def_id, item_segment)
}
Res::SelfTyAlias { is_trait_impl: true, .. } => todo!(),
// If we have a self type alias (in an impl), try to resolve an
// associated item from one of the supertraits of the impl's trait.
Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. } => {
let hir::ItemKind::Impl(hir::Impl { of_trait: Some(trait_ref), .. }) = self
.tcx
.hir_node_by_def_id(impl_def_id.expect_local())
.expect_item()
.kind
else {
return;
};
let Some(trait_def_id) = trait_ref.trait_def_id() else {
return;
};
let Some((bound_vars, assoc_item)) = BoundVarContext::supertrait_hrtb_vars(
self.tcx,
trait_def_id,
item_segment.ident,
ty::AssocKind::Fn,
) else {
return;
};
(bound_vars, assoc_item.def_id, item_segment)
}
_ => return,
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ check-pass

#![feature(return_type_notation)]
//~^ WARN the feature `return_type_notation` is incomplete

trait Trait {
fn method() -> impl Sized;
}

fn is_send(_: impl Send) {}

struct W<T>(T);

impl<T> W<T> {
fn test()
where
T: Trait,
T::method(..): Send,
{
is_send(T::method());
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/path-constrained-in-method.rs:3:12
|
LL | #![feature(return_type_notation)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
= note: `#[warn(incomplete_features)]` on by default

warning: 1 warning emitted

Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,15 @@ trait Bar: Foo {
Self::method(..): Send;
}

fn is_send(_: impl Send) {}

impl<T: Foo> Bar for T {
fn other()
where
Self::method(..): Send,
{
is_send(Self::method());
}
}

fn main() {}

0 comments on commit 5911914

Please sign in to comment.