@@ -5288,6 +5288,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
52885288 Some ( original_span. with_lo ( original_span. hi ( ) - BytePos ( 1 ) ) )
52895289 }
52905290
5291+ // Rewrite `SelfCtor` to `StructCtor`
5292+ pub fn rewrite_self_ctor ( & self , def : Def , span : Span ) -> ( Def , DefId , Ty < ' tcx > ) {
5293+ let tcx = self . tcx ;
5294+ if let Def :: SelfCtor ( impl_def_id) = def {
5295+ let ty = self . impl_self_ty ( span, impl_def_id) . ty ;
5296+ let adt_def = ty. ty_adt_def ( ) ;
5297+
5298+ match adt_def {
5299+ Some ( adt_def) if adt_def. has_ctor ( ) => {
5300+ let variant = adt_def. non_enum_variant ( ) ;
5301+ let def = Def :: StructCtor ( variant. did , variant. ctor_kind ) ;
5302+ ( def, variant. did , tcx. type_of ( variant. did ) )
5303+ }
5304+ _ => {
5305+ let mut err = tcx. sess . struct_span_err ( span,
5306+ "the `Self` constructor can only be used with tuple or unit structs" ) ;
5307+ if let Some ( adt_def) = adt_def {
5308+ match adt_def. adt_kind ( ) {
5309+ AdtKind :: Enum => {
5310+ err. help ( "did you mean to use one of the enum's variants?" ) ;
5311+ } ,
5312+ AdtKind :: Struct |
5313+ AdtKind :: Union => {
5314+ err. span_suggestion (
5315+ span,
5316+ "use curly brackets" ,
5317+ String :: from ( "Self { /* fields */ }" ) ,
5318+ Applicability :: HasPlaceholders ,
5319+ ) ;
5320+ }
5321+ }
5322+ }
5323+ err. emit ( ) ;
5324+
5325+ ( def, impl_def_id, tcx. types . err )
5326+ }
5327+ }
5328+ } else {
5329+ let def_id = def. def_id ( ) ;
5330+
5331+ // The things we are substituting into the type should not contain
5332+ // escaping late-bound regions, and nor should the base type scheme.
5333+ let ty = tcx. type_of ( def_id) ;
5334+ ( def, def_id, ty)
5335+ }
5336+ }
5337+
52915338 // Instantiates the given path, which must refer to an item with the given
52925339 // number of type parameters and type.
52935340 pub fn instantiate_value_path ( & self ,
@@ -5307,6 +5354,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
53075354
53085355 let tcx = self . tcx ;
53095356
5357+ match def {
5358+ Def :: Local ( nid) | Def :: Upvar ( nid, ..) => {
5359+ let hid = self . tcx . hir ( ) . node_to_hir_id ( nid) ;
5360+ let ty = self . local_ty ( span, hid) . decl_ty ;
5361+ let ty = self . normalize_associated_types_in ( span, & ty) ;
5362+ self . write_ty ( hir_id, ty) ;
5363+ return ( ty, def) ;
5364+ }
5365+ _ => { }
5366+ }
5367+
5368+ let ( def, def_id, ty) = self . rewrite_self_ctor ( def, span) ;
53105369 let path_segs = AstConv :: def_ids_for_path_segments ( self , segments, self_ty, def) ;
53115370
53125371 let mut user_self_ty = None ;
@@ -5368,17 +5427,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
53685427 user_self_ty = None ;
53695428 }
53705429
5371- match def {
5372- Def :: Local ( nid) | Def :: Upvar ( nid, ..) => {
5373- let hid = self . tcx . hir ( ) . node_to_hir_id ( nid) ;
5374- let ty = self . local_ty ( span, hid) . decl_ty ;
5375- let ty = self . normalize_associated_types_in ( span, & ty) ;
5376- self . write_ty ( hir_id, ty) ;
5377- return ( ty, def) ;
5378- }
5379- _ => { }
5380- }
5381-
53825430 // Now we have to compare the types that the user *actually*
53835431 // provided against the types that were *expected*. If the user
53845432 // did not provide any types, then we want to substitute inference
@@ -5411,53 +5459,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
54115459 tcx. generics_of ( * def_id) . has_self
54125460 } ) . unwrap_or ( false ) ;
54135461
5414- let mut new_def = def;
5415- let ( def_id, ty) = match def {
5416- Def :: SelfCtor ( impl_def_id) => {
5417- let ty = self . impl_self_ty ( span, impl_def_id) . ty ;
5418- let adt_def = ty. ty_adt_def ( ) ;
5419-
5420- match adt_def {
5421- Some ( adt_def) if adt_def. has_ctor ( ) => {
5422- let variant = adt_def. non_enum_variant ( ) ;
5423- new_def = Def :: StructCtor ( variant. did , variant. ctor_kind ) ;
5424- ( variant. did , tcx. type_of ( variant. did ) )
5425- }
5426- _ => {
5427- let mut err = tcx. sess . struct_span_err ( span,
5428- "the `Self` constructor can only be used with tuple or unit structs" ) ;
5429- if let Some ( adt_def) = adt_def {
5430- match adt_def. adt_kind ( ) {
5431- AdtKind :: Enum => {
5432- err. help ( "did you mean to use one of the enum's variants?" ) ;
5433- } ,
5434- AdtKind :: Struct |
5435- AdtKind :: Union => {
5436- err. span_suggestion (
5437- span,
5438- "use curly brackets" ,
5439- String :: from ( "Self { /* fields */ }" ) ,
5440- Applicability :: HasPlaceholders ,
5441- ) ;
5442- }
5443- }
5444- }
5445- err. emit ( ) ;
5446-
5447- ( impl_def_id, tcx. types . err )
5448- }
5449- }
5450- }
5451- _ => {
5452- let def_id = def. def_id ( ) ;
5453-
5454- // The things we are substituting into the type should not contain
5455- // escaping late-bound regions, and nor should the base type scheme.
5456- let ty = tcx. type_of ( def_id) ;
5457- ( def_id, ty)
5458- }
5459- } ;
5460-
54615462 let substs = AstConv :: create_substs_for_generic_args (
54625463 tcx,
54635464 def_id,
@@ -5573,7 +5574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
55735574 ty_substituted) ;
55745575 self . write_substs ( hir_id, substs) ;
55755576
5576- ( ty_substituted, new_def )
5577+ ( ty_substituted, def )
55775578 }
55785579
55795580 fn check_rustc_args_require_const ( & self ,
0 commit comments