Skip to content

Commit f2d9a3d

Browse files
committed
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.
2 parents 82bfda8 + 2ca350c commit f2d9a3d

File tree

10 files changed

+69
-33
lines changed

10 files changed

+69
-33
lines changed

compiler/rustc_hir/src/definitions.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,8 @@ impl DefPathData {
404404
match *self {
405405
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
406406

407-
// We use this name when collecting `ModChild`s.
408-
// FIXME this could probably be removed with some refactoring to the name resolver.
409-
ImplTraitAssocTy => Some(kw::Empty),
410-
411407
Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
412-
| ImplTrait => None,
408+
| ImplTrait | ImplTraitAssocTy => None,
413409
}
414410
}
415411

compiler/rustc_metadata/src/rmeta/decoder.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10211021
} else {
10221022
// Iterate over all children.
10231023
for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
1024-
yield self.get_mod_child(child_index, sess);
1024+
if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() {
1025+
yield self.get_mod_child(child_index, sess);
1026+
}
10251027
}
10261028

10271029
if let Some(reexports) = self.root.tables.module_reexports.get(self, id) {
@@ -1067,8 +1069,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10671069
}
10681070

10691071
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
1070-
let name = self.item_name(id);
1071-
1072+
let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() {
1073+
kw::Empty
1074+
} else {
1075+
self.item_name(id)
1076+
};
10721077
let (kind, has_self) = match self.def_kind(id) {
10731078
DefKind::AssocConst => (ty::AssocKind::Const, false),
10741079
DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)),

compiler/rustc_ty_utils/src/assoc.rs

+19-16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_data_structures::fx::FxIndexSet;
12
use rustc_hir as hir;
23
use rustc_hir::def::DefKind;
34
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
@@ -196,20 +197,26 @@ fn associated_types_for_impl_traits_in_associated_fn(
196197

197198
match tcx.def_kind(parent_def_id) {
198199
DefKind::Trait => {
199-
struct RPITVisitor {
200-
rpits: Vec<LocalDefId>,
200+
struct RPITVisitor<'tcx> {
201+
rpits: FxIndexSet<LocalDefId>,
202+
tcx: TyCtxt<'tcx>,
201203
}
202204

203-
impl<'v> Visitor<'v> for RPITVisitor {
204-
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
205-
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind {
206-
self.rpits.push(item_id.owner_id.def_id)
205+
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
206+
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
207+
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind
208+
&& self.rpits.insert(item_id.owner_id.def_id)
209+
{
210+
let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
211+
for bound in opaque_item.bounds {
212+
intravisit::walk_param_bound(self, bound);
213+
}
207214
}
208215
intravisit::walk_ty(self, ty)
209216
}
210217
}
211218

212-
let mut visitor = RPITVisitor { rpits: Vec::new() };
219+
let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() };
213220

214221
if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
215222
visitor.visit_fn_ret_ty(output);
@@ -227,13 +234,9 @@ fn associated_types_for_impl_traits_in_associated_fn(
227234

228235
tcx.arena.alloc_from_iter(
229236
tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map(
230-
move |trait_assoc_def_id| {
231-
associated_type_for_impl_trait_in_impl(
232-
tcx,
233-
trait_assoc_def_id.expect_local(),
234-
fn_def_id,
235-
)
236-
.to_def_id()
237+
move |&trait_assoc_def_id| {
238+
associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id)
239+
.to_def_id()
237240
},
238241
),
239242
)
@@ -355,7 +358,7 @@ fn associated_type_for_impl_trait_in_trait(
355358
/// that inherits properties that we infer from the method and the associated type.
356359
fn associated_type_for_impl_trait_in_impl(
357360
tcx: TyCtxt<'_>,
358-
trait_assoc_def_id: LocalDefId,
361+
trait_assoc_def_id: DefId,
359362
impl_fn_def_id: LocalDefId,
360363
) -> LocalDefId {
361364
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
@@ -380,7 +383,7 @@ fn associated_type_for_impl_trait_in_impl(
380383
name: kw::Empty,
381384
kind: ty::AssocKind::Type,
382385
def_id,
383-
trait_item_def_id: Some(trait_assoc_def_id.to_def_id()),
386+
trait_item_def_id: Some(trait_assoc_def_id),
384387
container: ty::ImplContainer,
385388
fn_has_self_parameter: false,
386389
opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }),

tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
#![feature(return_position_impl_trait_in_trait)]
44

5+
use std::ops::Deref;
6+
57
pub trait Foo {
6-
fn bar() -> impl Sized;
8+
fn bar() -> impl Deref<Target = impl Sized>;
79
}
810

911
pub struct Foreign;
10-
1112
impl Foo for Foreign {
12-
fn bar() {}
13+
fn bar() -> &'static () { &() }
1314
}

tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ note: required by a bound in `Foo::{opaque#0}`
1010
--> $DIR/doesnt-satisfy.rs:8:22
1111
|
1212
LL | fn bar() -> impl std::fmt::Display;
13-
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::`
13+
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
1414

1515
error: aborting due to previous error
1616

tests/ui/impl-trait/in-trait/foreign.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55

66
extern crate rpitit;
77

8+
use std::sync::Arc;
9+
10+
// Implement an RPITIT from another crate.
11+
struct Local;
12+
impl rpitit::Foo for Local {
13+
fn bar() -> Arc<String> { Arc::new(String::new()) }
14+
}
15+
816
fn main() {
9-
// Witness an RPITIT from another crate
10-
let () = <rpitit::Foreign as rpitit::Foo>::bar();
17+
// Witness an RPITIT from another crate.
18+
let &() = <rpitit::Foreign as rpitit::Foo>::bar();
19+
20+
let x: Arc<String> = <Local as rpitit::Foo>::bar();
1121
}

tests/ui/impl-trait/in-trait/nested-rpitit.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// check-pass
2+
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
3+
// revisions: current next
24

35
#![feature(return_position_impl_trait_in_trait)]
46
#![allow(incomplete_features)]

tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0277]: the trait bound `Something: Termination` is not satisfied
2-
--> $DIR/issue-103052-2.rs:12:22
2+
--> $DIR/issue-103052-2.rs:15:22
33
|
44
LL | fn main() -> Something {
55
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
66
|
77
note: required by a bound in `Main::main::{opaque#0}`
8-
--> $DIR/issue-103052-2.rs:6:27
8+
--> $DIR/issue-103052-2.rs:9:27
99
|
1010
LL | fn main() -> impl std::process::Termination;
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `Something: Termination` is not satisfied
2+
--> $DIR/issue-103052-2.rs:15:22
3+
|
4+
LL | fn main() -> Something {
5+
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
6+
|
7+
note: required by a bound in `Main::{opaque#0}`
8+
--> $DIR/issue-103052-2.rs:9:27
9+
|
10+
LL | fn main() -> impl std::process::Termination;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{opaque#0}`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.

tests/ui/rfc-1937-termination-trait/issue-103052-2.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
2+
// revisions: current next
3+
14
#![feature(return_position_impl_trait_in_trait)]
25
#![allow(incomplete_features)]
36

@@ -9,7 +12,8 @@ mod child {
912
struct Something;
1013

1114
impl Main for () {
12-
fn main() -> Something { //~ ERROR the trait bound `Something: Termination` is not satisfied
15+
fn main() -> Something {
16+
//~^ ERROR the trait bound `Something: Termination` is not satisfied
1317
Something
1418
}
1519
}

0 commit comments

Comments
 (0)