Auto merge of #109499 - spastorino:new-rpitit-19, r=compiler-errors
Give return-position impl traits in trait a (synthetic) name to avoid name collisions with new lowering strategy The only needed commit from this PR is the last one. r? `@compiler-errors` Needs #109455.
This commit is contained in:
commit
f2d9a3d077
@ -404,12 +404,8 @@ impl DefPathData {
|
|||||||
match *self {
|
match *self {
|
||||||
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
|
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
|
||||||
|
|
||||||
// We use this name when collecting `ModChild`s.
|
|
||||||
// FIXME this could probably be removed with some refactoring to the name resolver.
|
|
||||||
ImplTraitAssocTy => Some(kw::Empty),
|
|
||||||
|
|
||||||
Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
|
Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
|
||||||
| ImplTrait => None,
|
| ImplTrait | ImplTraitAssocTy => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,7 +1021,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
} else {
|
} else {
|
||||||
// Iterate over all children.
|
// Iterate over all children.
|
||||||
for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
|
for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
|
||||||
yield self.get_mod_child(child_index, sess);
|
if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() {
|
||||||
|
yield self.get_mod_child(child_index, sess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(reexports) = self.root.tables.module_reexports.get(self, id) {
|
if let Some(reexports) = self.root.tables.module_reexports.get(self, id) {
|
||||||
@ -1067,8 +1069,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
|
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
|
||||||
let name = self.item_name(id);
|
let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() {
|
||||||
|
kw::Empty
|
||||||
|
} else {
|
||||||
|
self.item_name(id)
|
||||||
|
};
|
||||||
let (kind, has_self) = match self.def_kind(id) {
|
let (kind, has_self) = match self.def_kind(id) {
|
||||||
DefKind::AssocConst => (ty::AssocKind::Const, false),
|
DefKind::AssocConst => (ty::AssocKind::Const, false),
|
||||||
DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)),
|
DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
|
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
|
||||||
@ -196,20 +197,26 @@ fn associated_types_for_impl_traits_in_associated_fn(
|
|||||||
|
|
||||||
match tcx.def_kind(parent_def_id) {
|
match tcx.def_kind(parent_def_id) {
|
||||||
DefKind::Trait => {
|
DefKind::Trait => {
|
||||||
struct RPITVisitor {
|
struct RPITVisitor<'tcx> {
|
||||||
rpits: Vec<LocalDefId>,
|
rpits: FxIndexSet<LocalDefId>,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'v> Visitor<'v> for RPITVisitor {
|
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
|
||||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind {
|
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind
|
||||||
self.rpits.push(item_id.owner_id.def_id)
|
&& self.rpits.insert(item_id.owner_id.def_id)
|
||||||
|
{
|
||||||
|
let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
|
||||||
|
for bound in opaque_item.bounds {
|
||||||
|
intravisit::walk_param_bound(self, bound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
intravisit::walk_ty(self, ty)
|
intravisit::walk_ty(self, ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut visitor = RPITVisitor { rpits: Vec::new() };
|
let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() };
|
||||||
|
|
||||||
if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
|
if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
|
||||||
visitor.visit_fn_ret_ty(output);
|
visitor.visit_fn_ret_ty(output);
|
||||||
@ -227,13 +234,9 @@ fn associated_types_for_impl_traits_in_associated_fn(
|
|||||||
|
|
||||||
tcx.arena.alloc_from_iter(
|
tcx.arena.alloc_from_iter(
|
||||||
tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map(
|
tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map(
|
||||||
move |trait_assoc_def_id| {
|
move |&trait_assoc_def_id| {
|
||||||
associated_type_for_impl_trait_in_impl(
|
associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id)
|
||||||
tcx,
|
.to_def_id()
|
||||||
trait_assoc_def_id.expect_local(),
|
|
||||||
fn_def_id,
|
|
||||||
)
|
|
||||||
.to_def_id()
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -355,7 +358,7 @@ fn associated_type_for_impl_trait_in_trait(
|
|||||||
/// that inherits properties that we infer from the method and the associated type.
|
/// that inherits properties that we infer from the method and the associated type.
|
||||||
fn associated_type_for_impl_trait_in_impl(
|
fn associated_type_for_impl_trait_in_impl(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
trait_assoc_def_id: LocalDefId,
|
trait_assoc_def_id: DefId,
|
||||||
impl_fn_def_id: LocalDefId,
|
impl_fn_def_id: LocalDefId,
|
||||||
) -> LocalDefId {
|
) -> LocalDefId {
|
||||||
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
|
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
|
||||||
@ -380,7 +383,7 @@ fn associated_type_for_impl_trait_in_impl(
|
|||||||
name: kw::Empty,
|
name: kw::Empty,
|
||||||
kind: ty::AssocKind::Type,
|
kind: ty::AssocKind::Type,
|
||||||
def_id,
|
def_id,
|
||||||
trait_item_def_id: Some(trait_assoc_def_id.to_def_id()),
|
trait_item_def_id: Some(trait_assoc_def_id),
|
||||||
container: ty::ImplContainer,
|
container: ty::ImplContainer,
|
||||||
fn_has_self_parameter: false,
|
fn_has_self_parameter: false,
|
||||||
opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }),
|
opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }),
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn bar() -> impl Sized;
|
fn bar() -> impl Deref<Target = impl Sized>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Foreign;
|
pub struct Foreign;
|
||||||
|
|
||||||
impl Foo for Foreign {
|
impl Foo for Foreign {
|
||||||
fn bar() {}
|
fn bar() -> &'static () { &() }
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ note: required by a bound in `Foo::{opaque#0}`
|
|||||||
--> $DIR/doesnt-satisfy.rs:8:22
|
--> $DIR/doesnt-satisfy.rs:8:22
|
||||||
|
|
|
|
||||||
LL | fn bar() -> impl std::fmt::Display;
|
LL | fn bar() -> impl std::fmt::Display;
|
||||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::`
|
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -5,7 +5,17 @@
|
|||||||
|
|
||||||
extern crate rpitit;
|
extern crate rpitit;
|
||||||
|
|
||||||
fn main() {
|
use std::sync::Arc;
|
||||||
// Witness an RPITIT from another crate
|
|
||||||
let () = <rpitit::Foreign as rpitit::Foo>::bar();
|
// Implement an RPITIT from another crate.
|
||||||
|
struct Local;
|
||||||
|
impl rpitit::Foo for Local {
|
||||||
|
fn bar() -> Arc<String> { Arc::new(String::new()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Witness an RPITIT from another crate.
|
||||||
|
let &() = <rpitit::Foreign as rpitit::Foo>::bar();
|
||||||
|
|
||||||
|
let x: Arc<String> = <Local as rpitit::Foo>::bar();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
error[E0277]: the trait bound `Something: Termination` is not satisfied
|
error[E0277]: the trait bound `Something: Termination` is not satisfied
|
||||||
--> $DIR/issue-103052-2.rs:12:22
|
--> $DIR/issue-103052-2.rs:15:22
|
||||||
|
|
|
|
||||||
LL | fn main() -> Something {
|
LL | fn main() -> Something {
|
||||||
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
|
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
|
||||||
|
|
|
|
||||||
note: required by a bound in `Main::main::{opaque#0}`
|
note: required by a bound in `Main::main::{opaque#0}`
|
||||||
--> $DIR/issue-103052-2.rs:6:27
|
--> $DIR/issue-103052-2.rs:9:27
|
||||||
|
|
|
|
||||||
LL | fn main() -> impl std::process::Termination;
|
LL | fn main() -> impl std::process::Termination;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}`
|
@ -0,0 +1,15 @@
|
|||||||
|
error[E0277]: the trait bound `Something: Termination` is not satisfied
|
||||||
|
--> $DIR/issue-103052-2.rs:15:22
|
||||||
|
|
|
||||||
|
LL | fn main() -> Something {
|
||||||
|
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
|
||||||
|
|
|
||||||
|
note: required by a bound in `Main::{opaque#0}`
|
||||||
|
--> $DIR/issue-103052-2.rs:9:27
|
||||||
|
|
|
||||||
|
LL | fn main() -> impl std::process::Termination;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{opaque#0}`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -1,3 +1,6 @@
|
|||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
@ -9,7 +12,8 @@ mod child {
|
|||||||
struct Something;
|
struct Something;
|
||||||
|
|
||||||
impl Main for () {
|
impl Main for () {
|
||||||
fn main() -> Something { //~ ERROR the trait bound `Something: Termination` is not satisfied
|
fn main() -> Something {
|
||||||
|
//~^ ERROR the trait bound `Something: Termination` is not satisfied
|
||||||
Something
|
Something
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user