@@ -5302,6 +5302,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5302
5302
Some ( original_span. with_lo ( original_span. hi ( ) - BytePos ( 1 ) ) )
5303
5303
}
5304
5304
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
+
5305
5352
// Instantiates the given path, which must refer to an item with the given
5306
5353
// number of type parameters and type.
5307
5354
pub fn instantiate_value_path ( & self ,
@@ -5321,6 +5368,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5321
5368
5322
5369
let tcx = self . tcx ;
5323
5370
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) ;
5324
5383
let path_segs = AstConv :: def_ids_for_path_segments ( self , segments, self_ty, def) ;
5325
5384
5326
5385
let mut user_self_ty = None ;
@@ -5382,17 +5441,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5382
5441
user_self_ty = None ;
5383
5442
}
5384
5443
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
-
5396
5444
// Now we have to compare the types that the user *actually*
5397
5445
// provided against the types that were *expected*. If the user
5398
5446
// did not provide any types, then we want to substitute inference
@@ -5425,53 +5473,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5425
5473
tcx. generics_of ( * def_id) . has_self
5426
5474
} ) . unwrap_or ( false ) ;
5427
5475
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
-
5475
5476
let substs = AstConv :: create_substs_for_generic_args (
5476
5477
tcx,
5477
5478
def_id,
@@ -5587,7 +5588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5587
5588
ty_substituted) ;
5588
5589
self . write_substs ( hir_id, substs) ;
5589
5590
5590
- ( ty_substituted, new_def )
5591
+ ( ty_substituted, def )
5591
5592
}
5592
5593
5593
5594
fn check_rustc_args_require_const ( & self ,
0 commit comments