@@ -5302,6 +5302,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
53025302 Some ( original_span. with_lo ( original_span. hi ( ) - BytePos ( 1 ) ) )
53035303 }
53045304
5305+ // Rewrite `SelfCtor` to `StructCtor`
5306+ pub fn rewrite_self_ctor ( & self , def : Def , span : Span ) -> ( Def , DefId , Ty < ' tcx > ) {
5307+ let tcx = self . tcx ;
5308+ if let Def :: SelfCtor ( impl_def_id) = def {
5309+ let ty = self . impl_self_ty ( span, impl_def_id) . ty ;
5310+ let adt_def = ty. ty_adt_def ( ) ;
5311+
5312+ match adt_def {
5313+ Some ( adt_def) if adt_def. has_ctor ( ) => {
5314+ let variant = adt_def. non_enum_variant ( ) ;
5315+ let def = Def :: StructCtor ( variant. did , variant. ctor_kind ) ;
5316+ ( def, variant. did , tcx. type_of ( variant. did ) )
5317+ }
5318+ _ => {
5319+ let mut err = tcx. sess . struct_span_err ( span,
5320+ "the `Self` constructor can only be used with tuple or unit structs" ) ;
5321+ if let Some ( adt_def) = adt_def {
5322+ match adt_def. adt_kind ( ) {
5323+ AdtKind :: Enum => {
5324+ err. help ( "did you mean to use one of the enum's variants?" ) ;
5325+ } ,
5326+ AdtKind :: Struct |
5327+ AdtKind :: Union => {
5328+ err. span_suggestion (
5329+ span,
5330+ "use curly brackets" ,
5331+ String :: from ( "Self { /* fields */ }" ) ,
5332+ Applicability :: HasPlaceholders ,
5333+ ) ;
5334+ }
5335+ }
5336+ }
5337+ err. emit ( ) ;
5338+
5339+ ( def, impl_def_id, tcx. types . err )
5340+ }
5341+ }
5342+ } else {
5343+ let def_id = def. def_id ( ) ;
5344+
5345+ // The things we are substituting into the type should not contain
5346+ // escaping late-bound regions, and nor should the base type scheme.
5347+ let ty = tcx. type_of ( def_id) ;
5348+ ( def, def_id, ty)
5349+ }
5350+ }
5351+
53055352 // Instantiates the given path, which must refer to an item with the given
53065353 // number of type parameters and type.
53075354 pub fn instantiate_value_path ( & self ,
@@ -5321,6 +5368,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
53215368
53225369 let tcx = self . tcx ;
53235370
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+
5382+ let ( def, def_id, ty) = self . rewrite_self_ctor ( def, span) ;
53245383 let path_segs = AstConv :: def_ids_for_path_segments ( self , segments, self_ty, def) ;
53255384
53265385 let mut user_self_ty = None ;
@@ -5382,17 +5441,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
53825441 user_self_ty = None ;
53835442 }
53845443
5385- match def {
5386- Def :: Local ( nid) | Def :: Upvar ( nid, ..) => {
5387- let hid = self . tcx . hir ( ) . node_to_hir_id ( nid) ;
5388- let ty = self . local_ty ( span, hid) . decl_ty ;
5389- let ty = self . normalize_associated_types_in ( span, & ty) ;
5390- self . write_ty ( hir_id, ty) ;
5391- return ( ty, def) ;
5392- }
5393- _ => { }
5394- }
5395-
53965444 // Now we have to compare the types that the user *actually*
53975445 // provided against the types that were *expected*. If the user
53985446 // did not provide any types, then we want to substitute inference
@@ -5425,53 +5473,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
54255473 tcx. generics_of ( * def_id) . has_self
54265474 } ) . unwrap_or ( false ) ;
54275475
5428- let mut new_def = def;
5429- let ( def_id, ty) = match def {
5430- Def :: SelfCtor ( impl_def_id) => {
5431- let ty = self . impl_self_ty ( span, impl_def_id) . ty ;
5432- let adt_def = ty. ty_adt_def ( ) ;
5433-
5434- match adt_def {
5435- Some ( adt_def) if adt_def. has_ctor ( ) => {
5436- let variant = adt_def. non_enum_variant ( ) ;
5437- new_def = Def :: StructCtor ( variant. did , variant. ctor_kind ) ;
5438- ( variant. did , tcx. type_of ( variant. did ) )
5439- }
5440- _ => {
5441- let mut err = tcx. sess . struct_span_err ( span,
5442- "the `Self` constructor can only be used with tuple or unit structs" ) ;
5443- if let Some ( adt_def) = adt_def {
5444- match adt_def. adt_kind ( ) {
5445- AdtKind :: Enum => {
5446- err. help ( "did you mean to use one of the enum's variants?" ) ;
5447- } ,
5448- AdtKind :: Struct |
5449- AdtKind :: Union => {
5450- err. span_suggestion (
5451- span,
5452- "use curly brackets" ,
5453- String :: from ( "Self { /* fields */ }" ) ,
5454- Applicability :: HasPlaceholders ,
5455- ) ;
5456- }
5457- }
5458- }
5459- err. emit ( ) ;
5460-
5461- ( impl_def_id, tcx. types . err )
5462- }
5463- }
5464- }
5465- _ => {
5466- let def_id = def. def_id ( ) ;
5467-
5468- // The things we are substituting into the type should not contain
5469- // escaping late-bound regions, and nor should the base type scheme.
5470- let ty = tcx. type_of ( def_id) ;
5471- ( def_id, ty)
5472- }
5473- } ;
5474-
54755476 let substs = AstConv :: create_substs_for_generic_args (
54765477 tcx,
54775478 def_id,
@@ -5587,7 +5588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
55875588 ty_substituted) ;
55885589 self . write_substs ( hir_id, substs) ;
55895590
5590- ( ty_substituted, new_def )
5591+ ( ty_substituted, def )
55915592 }
55925593
55935594 fn check_rustc_args_require_const ( & self ,
0 commit comments