@@ -5288,6 +5288,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5288
5288
Some ( original_span. with_lo ( original_span. hi ( ) - BytePos ( 1 ) ) )
5289
5289
}
5290
5290
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
+
5291
5338
// Instantiates the given path, which must refer to an item with the given
5292
5339
// number of type parameters and type.
5293
5340
pub fn instantiate_value_path ( & self ,
@@ -5307,6 +5354,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5307
5354
5308
5355
let tcx = self . tcx ;
5309
5356
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) ;
5310
5369
let path_segs = AstConv :: def_ids_for_path_segments ( self , segments, self_ty, def) ;
5311
5370
5312
5371
let mut user_self_ty = None ;
@@ -5368,17 +5427,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5368
5427
user_self_ty = None ;
5369
5428
}
5370
5429
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
5430
// Now we have to compare the types that the user *actually*
5383
5431
// provided against the types that were *expected*. If the user
5384
5432
// did not provide any types, then we want to substitute inference
@@ -5411,53 +5459,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5411
5459
tcx. generics_of ( * def_id) . has_self
5412
5460
} ) . unwrap_or ( false ) ;
5413
5461
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
-
5461
5462
let substs = AstConv :: create_substs_for_generic_args (
5462
5463
tcx,
5463
5464
def_id,
@@ -5573,7 +5574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5573
5574
ty_substituted) ;
5574
5575
self . write_substs ( hir_id, substs) ;
5575
5576
5576
- ( ty_substituted, new_def )
5577
+ ( ty_substituted, def )
5577
5578
}
5578
5579
5579
5580
fn check_rustc_args_require_const ( & self ,
0 commit comments