@@ -317,7 +317,7 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
317
317
match ast_ty. node {
318
318
ast:: TyPath ( ref path, _, id) => {
319
319
let a_def = match tcx. def_map . borrow ( ) . find ( & id) {
320
- None => tcx. sess . span_fatal (
320
+ None => tcx. sess . span_bug (
321
321
ast_ty. span , format ! ( "unbound path {}" , path_to_str( path) ) ) ,
322
322
Some ( & d) => d
323
323
} ;
@@ -366,95 +366,173 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
366
366
}
367
367
}
368
368
369
- // Parses the programmer's textual representation of a type into our
370
- // internal notion of a type.
371
- pub fn ast_ty_to_ty < AC : AstConv , RS : RegionScope > (
372
- this : & AC , rscope : & RS , ast_ty : & ast:: Ty ) -> ty:: t {
373
-
374
- enum PointerTy {
375
- Box ,
376
- RPtr ( ty:: Region ) ,
377
- Uniq
369
+ /// Converts the given AST type to a built-in type. A "built-in type" is, at
370
+ /// present, either a core numeric type, a string, or `Box`.
371
+ pub fn ast_ty_to_builtin_ty < AC : AstConv ,
372
+ RS : RegionScope > (
373
+ this : & AC ,
374
+ rscope : & RS ,
375
+ ast_ty : & ast:: Ty )
376
+ -> Option < ty:: t > {
377
+ match ast_ty_to_prim_ty ( this. tcx ( ) , ast_ty) {
378
+ Some ( typ) => return Some ( typ) ,
379
+ None => { }
378
380
}
379
381
380
- fn ast_ty_to_mt < AC : AstConv , RS : RegionScope > ( this : & AC ,
381
- rscope : & RS ,
382
- ty : & ast:: Ty ) -> ty:: mt {
383
- ty:: mt { ty : ast_ty_to_ty ( this, rscope, ty) , mutbl : ast:: MutImmutable }
384
- }
382
+ match ast_ty. node {
383
+ ast:: TyPath ( ref path, _, id) => {
384
+ let a_def = match this. tcx ( ) . def_map . borrow ( ) . find ( & id) {
385
+ None => this. tcx ( ) . sess . span_bug (
386
+ ast_ty. span , format ! ( "unbound path {}" , path_to_str( path) ) ) ,
387
+ Some ( & d) => d
388
+ } ;
385
389
386
- // Handle ~, and & being able to mean strs and vecs.
387
- // If a_seq_ty is a str or a vec, make it a str/vec.
388
- // Also handle first-class trait types.
389
- fn mk_pointer < AC : AstConv ,
390
- RS : RegionScope > (
391
- this : & AC ,
392
- rscope : & RS ,
393
- a_seq_ty : & ast:: MutTy ,
394
- ptr_ty : PointerTy ,
395
- constr: |ty:: t| -> ty:: t)
396
- -> ty:: t {
397
- let tcx = this. tcx ( ) ;
398
- debug ! ( "mk_pointer(ptr_ty={:?})" , ptr_ty) ;
399
-
400
- match a_seq_ty. ty . node {
401
- ast:: TyVec ( ty) => {
402
- let mut mt = ast_ty_to_mt ( this, rscope, ty) ;
403
- if a_seq_ty. mutbl == ast:: MutMutable {
404
- mt. mutbl = ast:: MutMutable ;
405
- }
406
- return constr ( ty:: mk_vec ( tcx, mt, None ) ) ;
407
- }
408
- ast:: TyPath ( ref path, ref bounds, id) => {
409
- // Note that the "bounds must be empty if path is not a trait"
410
- // restriction is enforced in the below case for ty_path, which
411
- // will run after this as long as the path isn't a trait.
412
- match tcx. def_map . borrow ( ) . find ( & id) {
413
- Some ( & ast:: DefPrimTy ( ast:: TyStr ) ) => {
414
- check_path_args ( tcx, path, NO_TPS | NO_REGIONS ) ;
415
- match ptr_ty {
416
- Uniq => {
417
- return ty:: mk_uniq ( tcx, ty:: mk_str ( tcx) ) ;
418
- }
419
- RPtr ( r) => {
420
- return ty:: mk_str_slice ( tcx, r, ast:: MutImmutable ) ;
421
- }
422
- _ => tcx. sess . span_err ( path. span ,
423
- format ! ( "managed strings are not supported" ) ) ,
424
- }
390
+ // FIXME(#12938): This is a hack until we have full support for
391
+ // DST.
392
+ match a_def {
393
+ ast:: DefTy ( did) | ast:: DefStruct ( did)
394
+ if Some ( did) == this. tcx ( ) . lang_items . owned_box ( ) => {
395
+ if path. segments
396
+ . iter ( )
397
+ . flat_map ( |s| s. types . iter ( ) )
398
+ . len ( ) > 1 {
399
+ this. tcx ( )
400
+ . sess
401
+ . span_err ( path. span ,
402
+ "`Box` has only one type parameter" )
425
403
}
426
- Some ( & ast:: DefTrait ( trait_def_id) ) => {
427
- let result = ast_path_to_trait_ref (
428
- this, rscope, trait_def_id, None , path) ;
429
- let trait_store = match ptr_ty {
430
- Uniq => ty:: UniqTraitStore ,
431
- RPtr ( r) => {
432
- ty:: RegionTraitStore ( r, a_seq_ty. mutbl )
433
- }
434
- _ => {
435
- tcx. sess . span_err (
436
- path. span ,
437
- "~trait or &trait are the only supported \
438
- forms of casting-to-trait") ;
439
- return ty:: mk_err ( ) ;
440
- }
404
+
405
+ for inner_ast_type in path. segments
406
+ . iter ( )
407
+ . flat_map ( |s| s. types . iter ( ) ) {
408
+ let mt = ast:: MutTy {
409
+ ty : * inner_ast_type,
410
+ mutbl : ast:: MutImmutable ,
441
411
} ;
442
- let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds, trait_store) ;
443
- return ty:: mk_trait ( tcx,
444
- result. def_id ,
445
- result. substs . clone ( ) ,
446
- trait_store,
447
- bounds) ;
412
+ return Some ( mk_pointer ( this,
413
+ rscope,
414
+ & mt,
415
+ Uniq ,
416
+ |typ| {
417
+ match ty:: get ( typ) . sty {
418
+ ty:: ty_str => {
419
+ this. tcx ( )
420
+ . sess
421
+ . span_err ( path. span ,
422
+ "`Box<str>` is not a type" ) ;
423
+ ty:: mk_err ( )
424
+ }
425
+ ty:: ty_vec( _, None ) => {
426
+ this. tcx ( )
427
+ . sess
428
+ . span_err ( path. span ,
429
+ "`Box<[T]>` is not a type" ) ;
430
+ ty:: mk_err ( )
431
+ }
432
+ _ => ty:: mk_uniq ( this. tcx ( ) , typ) ,
433
+ }
434
+ } ) )
448
435
}
449
- _ => { }
436
+ this. tcx ( ) . sess . span_bug ( path. span ,
437
+ "not enough type parameters \
438
+ supplied to `Box<T>`")
450
439
}
440
+ _ => None
451
441
}
452
- _ => { }
453
442
}
443
+ _ => None
444
+ }
445
+ }
446
+
447
+ enum PointerTy {
448
+ Box ,
449
+ RPtr ( ty:: Region ) ,
450
+ Uniq
451
+ }
452
+
453
+ fn ast_ty_to_mt < AC : AstConv , RS : RegionScope > ( this : & AC ,
454
+ rscope : & RS ,
455
+ ty : & ast:: Ty ) -> ty:: mt {
456
+ ty:: mt { ty : ast_ty_to_ty ( this, rscope, ty) , mutbl : ast:: MutImmutable }
457
+ }
458
+
459
+ // Handle `~`, `Box`, and `&` being able to mean strs and vecs.
460
+ // If a_seq_ty is a str or a vec, make it a str/vec.
461
+ // Also handle first-class trait types.
462
+ fn mk_pointer < AC : AstConv ,
463
+ RS : RegionScope > (
464
+ this : & AC ,
465
+ rscope : & RS ,
466
+ a_seq_ty : & ast:: MutTy ,
467
+ ptr_ty : PointerTy ,
468
+ constr: |ty:: t| -> ty:: t)
469
+ -> ty:: t {
470
+ let tcx = this. tcx ( ) ;
471
+ debug ! ( "mk_pointer(ptr_ty={:?})" , ptr_ty) ;
454
472
455
- constr ( ast_ty_to_ty ( this, rscope, a_seq_ty. ty ) )
473
+ match a_seq_ty. ty . node {
474
+ ast:: TyVec ( ty) => {
475
+ let mut mt = ast_ty_to_mt ( this, rscope, ty) ;
476
+ if a_seq_ty. mutbl == ast:: MutMutable {
477
+ mt. mutbl = ast:: MutMutable ;
478
+ }
479
+ return constr ( ty:: mk_vec ( tcx, mt, None ) ) ;
480
+ }
481
+ ast:: TyPath ( ref path, ref bounds, id) => {
482
+ // Note that the "bounds must be empty if path is not a trait"
483
+ // restriction is enforced in the below case for ty_path, which
484
+ // will run after this as long as the path isn't a trait.
485
+ match tcx. def_map . borrow ( ) . find ( & id) {
486
+ Some ( & ast:: DefPrimTy ( ast:: TyStr ) ) => {
487
+ check_path_args ( tcx, path, NO_TPS | NO_REGIONS ) ;
488
+ match ptr_ty {
489
+ Uniq => {
490
+ return constr ( ty:: mk_str ( tcx) ) ;
491
+ }
492
+ RPtr ( r) => {
493
+ return ty:: mk_str_slice ( tcx, r, ast:: MutImmutable ) ;
494
+ }
495
+ _ => tcx. sess . span_err ( path. span ,
496
+ format ! ( "managed strings are not supported" ) ) ,
497
+ }
498
+ }
499
+ Some ( & ast:: DefTrait ( trait_def_id) ) => {
500
+ let result = ast_path_to_trait_ref (
501
+ this, rscope, trait_def_id, None , path) ;
502
+ let trait_store = match ptr_ty {
503
+ Uniq => ty:: UniqTraitStore ,
504
+ RPtr ( r) => {
505
+ ty:: RegionTraitStore ( r, a_seq_ty. mutbl )
506
+ }
507
+ _ => {
508
+ tcx. sess . span_err (
509
+ path. span ,
510
+ "~trait or &trait are the only supported \
511
+ forms of casting-to-trait") ;
512
+ return ty:: mk_err ( ) ;
513
+ }
514
+ } ;
515
+ let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds, trait_store) ;
516
+ return ty:: mk_trait ( tcx,
517
+ result. def_id ,
518
+ result. substs . clone ( ) ,
519
+ trait_store,
520
+ bounds) ;
521
+ }
522
+ _ => { }
523
+ }
524
+ }
525
+ _ => { }
456
526
}
457
527
528
+ constr ( ast_ty_to_ty ( this, rscope, a_seq_ty. ty ) )
529
+ }
530
+
531
+ // Parses the programmer's textual representation of a type into our
532
+ // internal notion of a type.
533
+ pub fn ast_ty_to_ty < AC : AstConv , RS : RegionScope > (
534
+ this : & AC , rscope : & RS , ast_ty : & ast:: Ty ) -> ty:: t {
535
+
458
536
let tcx = this. tcx ( ) ;
459
537
460
538
let mut ast_ty_to_ty_cache = tcx. ast_ty_to_ty_cache . borrow_mut ( ) ;
@@ -471,7 +549,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
471
549
ast_ty_to_ty_cache. insert ( ast_ty. id , ty:: atttce_unresolved) ;
472
550
drop ( ast_ty_to_ty_cache) ;
473
551
474
- let typ = ast_ty_to_prim_ty ( tcx, ast_ty) . unwrap_or_else ( || match ast_ty. node {
552
+ let typ = ast_ty_to_builtin_ty ( this, rscope, ast_ty) . unwrap_or_else ( || {
553
+ match ast_ty. node {
475
554
ast:: TyNil => ty:: mk_nil ( ) ,
476
555
ast:: TyBot => ty:: mk_bot ( ) ,
477
556
ast:: TyBox ( ty) => {
@@ -555,7 +634,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
555
634
}
556
635
ast:: TyPath ( ref path, ref bounds, id) => {
557
636
let a_def = match tcx. def_map . borrow ( ) . find ( & id) {
558
- None => tcx. sess . span_fatal (
637
+ None => tcx. sess . span_bug (
559
638
ast_ty. span , format ! ( "unbound path {}" , path_to_str( path) ) ) ,
560
639
Some ( & d) => d
561
640
} ;
@@ -639,7 +718,8 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
639
718
// and will not descend into this routine.
640
719
this. ty_infer ( ast_ty. span )
641
720
}
642
- } ) ;
721
+ }
722
+ } ) ;
643
723
644
724
tcx. ast_ty_to_ty_cache . borrow_mut ( ) . insert ( ast_ty. id , ty:: atttce_resolved ( typ) ) ;
645
725
return typ;
0 commit comments