From 75b48eeb0f8ea180fb31e534a289c89fb0a0aa98 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 14 Oct 2026 14:31:49 +0000 Subject: [PATCH] Implement better resolution for delegation mapping field --- .../rustc_ast_lowering/src/delegation/mod.rs | 4 +- compiler/rustc_hir_typeck/src/expr.rs | 89 ++++++++----- compiler/rustc_privacy/src/lib.rs | 11 +- .../pretty/delegation/self-mapping-output.pp | 4 +- .../delegation/self-mapping-output-privacy.rs | 14 ++ .../self-mapping-output-privacy.stderr | 18 ++- tests/ui/delegation/self-mapping-output.rs | 6 +- .../ui/delegation/self-mapping-output.stderr | 124 +++++++----------- .../self-type-mapping-field-name.rs | 56 ++++++++ 9 files changed, 207 insertions(+), 119 deletions(-) create mode 100644 tests/ui/delegation/self-type-mapping-field-name.rs diff --git a/compiler/rustc_ast_lowering/src/delegation/mod.rs b/compiler/rustc_ast_lowering/src/delegation/mod.rs index b2c0e1ffa81b1..eb980d31ce1ef 100644 --- a/compiler/rustc_ast_lowering/src/delegation/mod.rs +++ b/compiler/rustc_ast_lowering/src/delegation/mod.rs @@ -51,7 +51,7 @@ use rustc_hir::{self as hir, FnDeclFlags, QPath}; use rustc_middle::ty::Asyncness; use rustc_span::def_id::DefId; use rustc_span::symbol::kw; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{Ident, Span, Symbol}; use crate::delegation::generics::{GenericsGenerationResults, GenericsPosition}; use crate::delegation::resolution::resolver::DelegationResolver; @@ -480,7 +480,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc_slice(&[hir::ExprField { hir_id: self.next_id(), is_shorthand: false, - ident: Ident::new(sym::integer(0), span), + ident: Ident::new(kw::Underscore, span), expr: self.arena.alloc(call), span, }]), diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b1b8ecb7d1844..6a85430248d84 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1898,10 +1898,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let adt_kind = adt.adt_kind(); + let get_field_ident = |field: &ty::FieldDef| field.ident(tcx).normalize_to_macros_2_0(); let mut remaining_fields = variant .fields .iter_enumerated() - .map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field))) + .map(|(i, field)| (get_field_ident(field), (i, field))) .collect::>(); let mut seen_fields = FxHashMap::default(); @@ -1919,41 +1920,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Type-check each field. for (idx, field) in hir_fields.iter().enumerate() { - let ident = tcx.adjust_ident(field.ident, variant.def_id); - let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) { - seen_fields.insert(ident, field.span); - self.write_field_index(field.hir_id, i); - - // We don't look at stability attributes on - // struct-like enums (yet...), but it's definitely not - // a bug to have constructed one. - if adt_kind != AdtKind::Enum { - tcx.check_stability(v_field.did, Some(field.hir_id), field.span, None); + let ident = if field.ident.name == kw::Underscore { + // We are processing delegation `Self` mapping field, we expect that it is a struct + // with one field, so if it is not true we emit an error as we can't infer + // what field to use to initialize the struct. + // The `_` is a keyword so if user uses it during struct initialization as a field name + // it will be error anyway. + if let [v_field] = &variant.fields[..] { + Ok(get_field_ident(v_field)) + } else { + Err(tcx.dcx().span_delayed_bug( + field.ident.span, + format!( + "can not infer the delegation `Self` mapping field for {:?}", + self.body_def_id + ), + )) } - - self.field_ty(field.span, v_field, args) } else { - error_happened = true; - let guar = if let Some(prev_span) = seen_fields.get(&ident) { - self.dcx().emit_err(FieldMultiplySpecifiedInInitializer { - span: field.ident.span, - prev_span: *prev_span, - ident, - }) - } else { - self.report_unknown_field( - adt_ty, - variant, - expr, - field, - hir_fields, - adt.variant_descr(), - ) - }; - - Ty::new_error(tcx, guar) + Ok(tcx.adjust_ident(field.ident, variant.def_id)) }; + let field_type = ident + .and_then(|ident| { + if let Some((i, v_field)) = remaining_fields.remove(&ident) { + seen_fields.insert(ident, field.span); + self.write_field_index(field.hir_id, i); + + // We don't look at stability attributes on + // struct-like enums (yet...), but it's definitely not + // a bug to have constructed one. + if adt_kind != AdtKind::Enum { + tcx.check_stability(v_field.did, Some(field.hir_id), field.span, None); + } + + Ok(self.field_ty(field.span, v_field, args)) + } else { + error_happened = true; + let guar = if let Some(prev_span) = seen_fields.get(&ident) { + self.dcx().emit_err(FieldMultiplySpecifiedInInitializer { + span: field.ident.span, + prev_span: *prev_span, + ident, + }) + } else { + self.report_unknown_field( + adt_ty, + variant, + expr, + field, + hir_fields, + adt.variant_descr(), + ) + }; + + Err(guar) + } + }) + .unwrap_or_else(|err| Ty::new_error(tcx, err)); + // Check that the expected field type is WF. Otherwise, we emit no use-site error // in the case of coercions for non-WF fields, which leads to incorrect error // tainting. See issue #126272. diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 16a2ee9f22eaf..926efb9ccd7c0 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -35,7 +35,7 @@ use rustc_middle::ty::{ self, AssocContainer, Const, GenericParamDefKind, PredicateProxy, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; -use rustc_span::{Ident, Span, Symbol, bug, span_bug, sym}; +use rustc_span::{Ident, Span, Symbol, bug, kw, span_bug, sym}; use tracing::debug; //////////////////////////////////////////////////////////////////////////////// @@ -1077,7 +1077,14 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { for field in fields { let index = self.typeck_results().field_index(field.hir_id); if self.check_field(field.ident.span, adt, &variant.fields[index]) { - failed_fields.push((field.ident.name, field.ident.span, true)); + // kw::Underscore is a `Self` mapping delegation field which is + // generated by compiler, see delegation AST -> HIR lowering code + // and `check_expr_struct_fields` for details. + let name = match field.ident.name { + kw::Underscore => variant.fields[index].name, + name => name, + }; + failed_fields.push((name, field.ident.span, true)); } } self.emit_unreachable_field_error(failed_fields, adt, None, qpath.span()); diff --git a/tests/pretty/delegation/self-mapping-output.pp b/tests/pretty/delegation/self-mapping-output.pp index 5bce43315e1d0..3c77be7ed6831 100644 --- a/tests/pretty/delegation/self-mapping-output.pp +++ b/tests/pretty/delegation/self-mapping-output.pp @@ -24,7 +24,7 @@ struct W(S); impl Trait for W { #[attr = Inline(Hint)] - fn method(self: _) -> _ { from(Self { 0: Trait::method(self.0) }) } + fn method(self: _) -> _ { from(Self { _: Trait::method(self.0) }) } #[attr = Inline(Hint)] fn r#static() -> _ { Trait::r#static() } //~^ WARN: function cannot return without recursing [unconditional_recursion] @@ -34,7 +34,7 @@ impl W { #[attr = Inline(Hint)] - fn method(self: _) -> _ { from(Self { 0: Trait::method(self.0) }) } + fn method(self: _) -> _ { from(Self { _: Trait::method(self.0) }) } #[attr = Inline(Hint)] fn r#static() -> _ { Trait::r#static() } #[attr = Inline(Hint)] diff --git a/tests/ui/delegation/self-mapping-output-privacy.rs b/tests/ui/delegation/self-mapping-output-privacy.rs index f072d240608f8..ee5843884f268 100644 --- a/tests/ui/delegation/self-mapping-output-privacy.rs +++ b/tests/ui/delegation/self-mapping-output-privacy.rs @@ -13,6 +13,10 @@ impl Trait for S { mod private { pub struct W(super::S); + + pub struct W1 { + sss: super::S, + } } impl Trait for private::W { @@ -25,4 +29,14 @@ impl private::W { //~^ ERROR: field `0` of struct `W` is private } +impl Trait for private::W1 { + reuse Trait::method { S } + //~^ ERROR: field `sss` of struct `W1` is private +} + +impl private::W1 { + reuse Trait::method { S } + //~^ ERROR: field `sss` of struct `W1` is private +} + fn main() {} diff --git a/tests/ui/delegation/self-mapping-output-privacy.stderr b/tests/ui/delegation/self-mapping-output-privacy.stderr index 38f6b1a4a9ddf..113b43a2893f4 100644 --- a/tests/ui/delegation/self-mapping-output-privacy.stderr +++ b/tests/ui/delegation/self-mapping-output-privacy.stderr @@ -1,15 +1,27 @@ error[E0451]: field `0` of struct `W` is private - --> $DIR/self-mapping-output-privacy.rs:19:18 + --> $DIR/self-mapping-output-privacy.rs:23:18 | LL | reuse Trait::method { S } | ^^^^^^ private field error[E0451]: field `0` of struct `W` is private - --> $DIR/self-mapping-output-privacy.rs:24:18 + --> $DIR/self-mapping-output-privacy.rs:28:18 | LL | reuse Trait::method { S } | ^^^^^^ private field -error: aborting due to 2 previous errors +error[E0451]: field `sss` of struct `W1` is private + --> $DIR/self-mapping-output-privacy.rs:33:18 + | +LL | reuse Trait::method { S } + | ^^^^^^ private field + +error[E0451]: field `sss` of struct `W1` is private + --> $DIR/self-mapping-output-privacy.rs:38:18 + | +LL | reuse Trait::method { S } + | ^^^^^^ private field + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0451`. diff --git a/tests/ui/delegation/self-mapping-output.rs b/tests/ui/delegation/self-mapping-output.rs index 47b122b0accda..d20240bd6d88f 100644 --- a/tests/ui/delegation/self-mapping-output.rs +++ b/tests/ui/delegation/self-mapping-output.rs @@ -109,7 +109,6 @@ mod no_constructor { impl Trait for W { reuse Trait::method { self.0 } //~^ ERROR: no field `0` on type `&no_constructor::W` - //~| ERROR: struct `no_constructor::W` has no field named `0` reuse Trait::r#static; //~^ WARN: function cannot return without recursing [unconditional_recursion] reuse Trait::raw_S { self.0 } @@ -119,7 +118,6 @@ mod no_constructor { impl W { reuse Trait::method { self.0 } //~^ ERROR: no field `0` on type `&no_constructor::W` - //~| ERROR: struct `no_constructor::W` has no field named `0` reuse Trait::r#static; reuse Trait::raw_S { self.0 } //~^ ERROR: no field `0` on type `&no_constructor::W` @@ -142,7 +140,7 @@ mod more_than_one_field { struct W(S, S, S); impl Trait for W { reuse Trait::method { self.0 } - //~^ ERROR: missing fields `1` and `2` in initializer of `more_than_one_field::W` + //~^ ERROR: missing fields `0`, `1` and `2` in initializer of `more_than_one_field::W` reuse Trait::r#static; //~^ WARN: function cannot return without recursing [unconditional_recursion] reuse Trait::raw_S { self.0 } @@ -150,7 +148,7 @@ mod more_than_one_field { impl W { reuse Trait::method { self.0 } - //~^ ERROR: missing fields `1` and `2` in initializer of `more_than_one_field::W` + //~^ ERROR: missing fields `0`, `1` and `2` in initializer of `more_than_one_field::W` reuse Trait::r#static; reuse Trait::raw_S { self.0 } } diff --git a/tests/ui/delegation/self-mapping-output.stderr b/tests/ui/delegation/self-mapping-output.stderr index 86ce822a1821c..621ad70811381 100644 --- a/tests/ui/delegation/self-mapping-output.stderr +++ b/tests/ui/delegation/self-mapping-output.stderr @@ -1,15 +1,3 @@ -error[E0560]: struct `no_constructor::W` has no field named `0` - --> $DIR/self-mapping-output.rs:110:22 - | -LL | reuse Trait::method { self.0 } - | ^^^^^^ unknown field - | -help: a field with a similar name exists - | -LL - reuse Trait::method { self.0 } -LL + reuse Trait::s { self.0 } - | - error[E0609]: no field `0` on type `&no_constructor::W` --> $DIR/self-mapping-output.rs:110:36 | @@ -23,7 +11,7 @@ LL + reuse Trait::method { self.s } | error[E0609]: no field `0` on type `&no_constructor::W` - --> $DIR/self-mapping-output.rs:115:35 + --> $DIR/self-mapping-output.rs:114:35 | LL | reuse Trait::raw_S { self.0 } | ^ unknown field @@ -34,20 +22,8 @@ LL - reuse Trait::raw_S { self.0 } LL + reuse Trait::raw_S { self.s } | -error[E0560]: struct `no_constructor::W` has no field named `0` - --> $DIR/self-mapping-output.rs:120:22 - | -LL | reuse Trait::method { self.0 } - | ^^^^^^ unknown field - | -help: a field with a similar name exists - | -LL - reuse Trait::method { self.0 } -LL + reuse Trait::s { self.0 } - | - error[E0609]: no field `0` on type `&no_constructor::W` - --> $DIR/self-mapping-output.rs:120:36 + --> $DIR/self-mapping-output.rs:119:36 | LL | reuse Trait::method { self.0 } | ^ unknown field @@ -59,7 +35,7 @@ LL + reuse Trait::method { self.s } | error[E0609]: no field `0` on type `&no_constructor::W` - --> $DIR/self-mapping-output.rs:124:35 + --> $DIR/self-mapping-output.rs:122:35 | LL | reuse Trait::raw_S { self.0 } | ^ unknown field @@ -70,20 +46,20 @@ LL - reuse Trait::raw_S { self.0 } LL + reuse Trait::raw_S { self.s } | -error[E0063]: missing fields `1` and `2` in initializer of `more_than_one_field::W` - --> $DIR/self-mapping-output.rs:144:22 +error[E0063]: missing fields `0`, `1` and `2` in initializer of `more_than_one_field::W` + --> $DIR/self-mapping-output.rs:142:22 | LL | reuse Trait::method { self.0 } - | ^^^^^^ missing `1` and `2` + | ^^^^^^ missing `0`, `1` and `2` -error[E0063]: missing fields `1` and `2` in initializer of `more_than_one_field::W` - --> $DIR/self-mapping-output.rs:152:22 +error[E0063]: missing fields `0`, `1` and `2` in initializer of `more_than_one_field::W` + --> $DIR/self-mapping-output.rs:150:22 | LL | reuse Trait::method { self.0 } - | ^^^^^^ missing `1` and `2` + | ^^^^^^ missing `0`, `1` and `2` error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:184:25 + --> $DIR/self-mapping-output.rs:182:25 | LL | pub fn method(_: impl super::Trait) -> impl super::Trait { | ----------------- the found opaque type @@ -98,7 +74,7 @@ LL | reuse to_reuse::method { self.0 } found opaque type `impl non_trait_path_reuse::Trait` error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:186:25 + --> $DIR/self-mapping-output.rs:184:25 | LL | pub fn r#static() -> impl super::Trait { | ----------------- the found opaque type @@ -113,13 +89,13 @@ LL | reuse to_reuse::r#static; found opaque type `impl non_trait_path_reuse::Trait` error[E0609]: no field `0` on type `impl super::Trait` - --> $DIR/self-mapping-output.rs:191:39 + --> $DIR/self-mapping-output.rs:189:39 | LL | reuse to_reuse::method { self.0 } | ^ unknown field error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:213:31 + --> $DIR/self-mapping-output.rs:211:31 | LL | reuse Trait::method { self.0 } | ------ ^^^^^^ expected `&_`, found `()` @@ -129,7 +105,7 @@ LL | reuse Trait::method { self.0 } = note: expected reference `&_` found unit type `()` note: method defined here - --> $DIR/self-mapping-output.rs:199:12 + --> $DIR/self-mapping-output.rs:197:12 | LL | fn method(&self) -> (); | ^^^^^^ ---- @@ -139,14 +115,14 @@ LL | reuse Trait::method { &self.0 } | + error[E0283]: type annotations needed - --> $DIR/self-mapping-output.rs:216:22 + --> $DIR/self-mapping-output.rs:214:22 | LL | reuse Trait::r#static; | ^^^^^^^^ cannot infer type | = note: the type must implement `non_Self_return_type::Trait` help: the following types implement trait `non_Self_return_type::Trait` - --> $DIR/self-mapping-output.rs:205:5 + --> $DIR/self-mapping-output.rs:203:5 | LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ `non_Self_return_type::S` @@ -155,7 +131,7 @@ LL | impl Trait for W { | ^^^^^^^^^^^^^^^^ `non_Self_return_type::W` error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:219:30 + --> $DIR/self-mapping-output.rs:217:30 | LL | reuse Trait::raw_S { self.0 } | ----- ^^^^^^ expected `&_`, found `()` @@ -165,7 +141,7 @@ LL | reuse Trait::raw_S { self.0 } = note: expected reference `&_` found unit type `()` note: method defined here - --> $DIR/self-mapping-output.rs:201:12 + --> $DIR/self-mapping-output.rs:199:12 | LL | fn raw_S(&self) -> S { S } | ^^^^^ ----- @@ -175,7 +151,7 @@ LL | reuse Trait::raw_S { &self.0 } | + error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:224:31 + --> $DIR/self-mapping-output.rs:222:31 | LL | reuse Trait::method { self.0 } | ------ ^^^^^^ expected `&_`, found `()` @@ -185,7 +161,7 @@ LL | reuse Trait::method { self.0 } = note: expected reference `&_` found unit type `()` note: method defined here - --> $DIR/self-mapping-output.rs:199:12 + --> $DIR/self-mapping-output.rs:197:12 | LL | fn method(&self) -> (); | ^^^^^^ ---- @@ -195,14 +171,14 @@ LL | reuse Trait::method { &self.0 } | + error[E0283]: type annotations needed - --> $DIR/self-mapping-output.rs:227:22 + --> $DIR/self-mapping-output.rs:225:22 | LL | reuse Trait::r#static; | ^^^^^^^^ cannot infer type | = note: the type must implement `non_Self_return_type::Trait` help: the following types implement trait `non_Self_return_type::Trait` - --> $DIR/self-mapping-output.rs:205:5 + --> $DIR/self-mapping-output.rs:203:5 | LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ `non_Self_return_type::S` @@ -211,7 +187,7 @@ LL | impl Trait for W { | ^^^^^^^^^^^^^^^^ `non_Self_return_type::W` error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:230:30 + --> $DIR/self-mapping-output.rs:228:30 | LL | reuse Trait::raw_S { self.0 } | ----- ^^^^^^ expected `&_`, found `()` @@ -221,7 +197,7 @@ LL | reuse Trait::raw_S { self.0 } = note: expected reference `&_` found unit type `()` note: method defined here - --> $DIR/self-mapping-output.rs:201:12 + --> $DIR/self-mapping-output.rs:199:12 | LL | fn raw_S(&self) -> S { S } | ^^^^^ ----- @@ -231,7 +207,7 @@ LL | reuse Trait::raw_S { &self.0 } | + error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:256:38 + --> $DIR/self-mapping-output.rs:254:38 | LL | reuse ::method { self.0 } | ------ ^^^^^^ expected `&F`, found `&S` @@ -242,19 +218,19 @@ LL | reuse ::method { self.0 } = note: expected reference `&wrong_return_type::F` found reference `&wrong_return_type::S` note: method defined here - --> $DIR/self-mapping-output.rs:237:12 + --> $DIR/self-mapping-output.rs:235:12 | LL | fn method(&self) -> Self; | ^^^^^^ ---- error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:256:29 + --> $DIR/self-mapping-output.rs:254:29 | LL | reuse ::method { self.0 } | ^^^^^^ expected `S`, found `F` error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:260:29 + --> $DIR/self-mapping-output.rs:258:29 | LL | reuse ::r#static; | ^^^^^^^^ @@ -263,7 +239,7 @@ LL | reuse ::r#static; | expected `wrong_return_type::W` because of return type error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:263:37 + --> $DIR/self-mapping-output.rs:261:37 | LL | reuse ::raw_S { self.0 } | ----- ^^^^^^ expected `&F`, found `&S` @@ -273,13 +249,13 @@ LL | reuse ::raw_S { self.0 } = note: expected reference `&wrong_return_type::F` found reference `&wrong_return_type::S` note: method defined here - --> $DIR/self-mapping-output.rs:239:12 + --> $DIR/self-mapping-output.rs:237:12 | LL | fn raw_S(&self) -> S { S } | ^^^^^ ----- error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:268:38 + --> $DIR/self-mapping-output.rs:266:38 | LL | reuse ::method { self.0 } | ------ ^^^^^^ expected `&F`, found `&S` @@ -290,19 +266,19 @@ LL | reuse ::method { self.0 } = note: expected reference `&wrong_return_type::F` found reference `&wrong_return_type::S` note: method defined here - --> $DIR/self-mapping-output.rs:237:12 + --> $DIR/self-mapping-output.rs:235:12 | LL | fn method(&self) -> Self; | ^^^^^^ ---- error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:268:29 + --> $DIR/self-mapping-output.rs:266:29 | LL | reuse ::method { self.0 } | ^^^^^^ expected `S`, found `F` error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:272:29 + --> $DIR/self-mapping-output.rs:270:29 | LL | reuse ::r#static; | ^^^^^^^^ @@ -311,7 +287,7 @@ LL | reuse ::r#static; | expected `wrong_return_type::W` because of return type error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:275:37 + --> $DIR/self-mapping-output.rs:273:37 | LL | reuse ::raw_S { self.0 } | ----- ^^^^^^ expected `&F`, found `&S` @@ -321,13 +297,13 @@ LL | reuse ::raw_S { self.0 } = note: expected reference `&wrong_return_type::F` found reference `&wrong_return_type::S` note: method defined here - --> $DIR/self-mapping-output.rs:239:12 + --> $DIR/self-mapping-output.rs:237:12 | LL | fn raw_S(&self) -> S { S } | ^^^^^ ----- error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:301:31 + --> $DIR/self-mapping-output.rs:299:31 | LL | reuse Trait::method { F } | ------ ^ expected `&S`, found `&F` @@ -338,13 +314,13 @@ LL | reuse Trait::method { F } = note: expected reference `&wrong_target_expression::S` found reference `&wrong_target_expression::F` note: method defined here - --> $DIR/self-mapping-output.rs:282:12 + --> $DIR/self-mapping-output.rs:280:12 | LL | fn method(&self) -> Self; | ^^^^^^ ---- error[E0308]: mismatched types - --> $DIR/self-mapping-output.rs:310:31 + --> $DIR/self-mapping-output.rs:308:31 | LL | reuse Trait::method { F } | ------ ^ expected `&S`, found `&F` @@ -355,31 +331,31 @@ LL | reuse Trait::method { F } = note: expected reference `&wrong_target_expression::S` found reference `&wrong_target_expression::F` note: method defined here - --> $DIR/self-mapping-output.rs:282:12 + --> $DIR/self-mapping-output.rs:280:12 | LL | fn method(&self) -> Self; | ^^^^^^ ---- error[E0616]: field `0` of struct `private::W` is private - --> $DIR/self-mapping-output.rs:336:36 + --> $DIR/self-mapping-output.rs:334:36 | LL | reuse Trait::method { self.0 } | ^ private field error[E0616]: field `0` of struct `private::W` is private - --> $DIR/self-mapping-output.rs:342:35 + --> $DIR/self-mapping-output.rs:340:35 | LL | reuse Trait::raw_S { self.0 } | ^ private field error[E0616]: field `0` of struct `private::W` is private - --> $DIR/self-mapping-output.rs:347:36 + --> $DIR/self-mapping-output.rs:345:36 | LL | reuse Trait::method { self.0 } | ^ private field error[E0616]: field `0` of struct `private::W` is private - --> $DIR/self-mapping-output.rs:352:35 + --> $DIR/self-mapping-output.rs:350:35 | LL | reuse Trait::raw_S { self.0 } | ^ private field @@ -419,7 +395,7 @@ LL | reuse Trait::<'a, T, N>::r#static; = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing - --> $DIR/self-mapping-output.rs:113:22 + --> $DIR/self-mapping-output.rs:112:22 | LL | reuse Trait::r#static; | ^^^^^^^^ @@ -430,7 +406,7 @@ LL | reuse Trait::r#static; = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing - --> $DIR/self-mapping-output.rs:146:22 + --> $DIR/self-mapping-output.rs:144:22 | LL | reuse Trait::r#static; | ^^^^^^^^ @@ -441,7 +417,7 @@ LL | reuse Trait::r#static; = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing - --> $DIR/self-mapping-output.rs:304:22 + --> $DIR/self-mapping-output.rs:302:22 | LL | reuse Trait::r#static; | ^^^^^^^^ @@ -452,7 +428,7 @@ LL | reuse Trait::r#static; = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing - --> $DIR/self-mapping-output.rs:339:22 + --> $DIR/self-mapping-output.rs:337:22 | LL | reuse Trait::r#static; | ^^^^^^^^ @@ -462,7 +438,7 @@ LL | reuse Trait::r#static; | = help: a `loop` may express intention better if this is on purpose -error: aborting due to 31 previous errors; 7 warnings emitted +error: aborting due to 29 previous errors; 7 warnings emitted -Some errors have detailed explanations: E0063, E0283, E0308, E0560, E0609, E0616. +Some errors have detailed explanations: E0063, E0283, E0308, E0609, E0616. For more information about an error, try `rustc --explain E0063`. diff --git a/tests/ui/delegation/self-type-mapping-field-name.rs b/tests/ui/delegation/self-type-mapping-field-name.rs new file mode 100644 index 0000000000000..c57f701801da7 --- /dev/null +++ b/tests/ui/delegation/self-type-mapping-field-name.rs @@ -0,0 +1,56 @@ +//@ check-pass + +#![feature(fn_delegation)] + +mod simple_test { + trait Trait { + fn foo(&self) -> Self; + } + + struct S; + impl Trait for S { + fn foo(&self) -> S { S } + } + + struct W { s: S } + impl Trait for W { + reuse Trait::foo { self.s } + } + + impl W { + reuse Trait::foo { self.s } + } + + struct W1(S); + impl Trait for W1 { + reuse Trait::foo { self.0 } + } + + impl W1 { + reuse Trait::foo { self.0 } + } +} + +mod rfc { + struct BTreeMap { + _inner: std::collections::HashMap + } + + impl Clone for BTreeMap { + fn clone(&self) -> Self { + panic!() + } + + fn clone_from(&mut self, source: &Self) { + panic!() + } + } + + struct BTreeSet { + map: BTreeMap + } + + reuse impl Clone for BTreeSet { self.map } +} + +fn main() {}