@@ -51,6 +51,7 @@ use rustc_span::lev_distance::find_best_match_for_name;
51
51
use rustc_span:: source_map:: Span ;
52
52
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
53
53
use rustc_span:: { BytePos , Pos } ;
54
+ use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
54
55
use rustc_trait_selection:: infer:: InferCtxtExt ;
55
56
use rustc_trait_selection:: traits:: { self , ObligationCauseCode } ;
56
57
@@ -294,7 +295,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
294
295
self . check_lang_item_path ( lang_item, expr, hir_id)
295
296
}
296
297
ExprKind :: Path ( ref qpath) => self . check_expr_path ( qpath, expr, & [ ] ) ,
297
- ExprKind :: InlineAsm ( asm) => self . check_expr_asm ( asm) ,
298
+ ExprKind :: InlineAsm ( asm) => {
299
+ // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
300
+ self . deferred_asm_checks . borrow_mut ( ) . push ( ( asm, expr. hir_id ) ) ;
301
+ self . check_expr_asm ( asm)
302
+ }
298
303
ExprKind :: Break ( destination, ref expr_opt) => {
299
304
self . check_expr_break ( destination, expr_opt. as_deref ( ) , expr)
300
305
}
@@ -530,8 +535,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
530
535
_ => self . instantiate_value_path ( segs, opt_ty, res, expr. span , expr. hir_id ) . 0 ,
531
536
} ;
532
537
533
- if let ty:: FnDef ( ..) = ty. kind ( ) {
538
+ if let ty:: FnDef ( did , ..) = * ty. kind ( ) {
534
539
let fn_sig = ty. fn_sig ( tcx) ;
540
+ if tcx. fn_sig ( did) . abi ( ) == RustIntrinsic && tcx. item_name ( did) == sym:: transmute {
541
+ let from = fn_sig. inputs ( ) . skip_binder ( ) [ 0 ] ;
542
+ let to = fn_sig. output ( ) . skip_binder ( ) ;
543
+ // We defer the transmute to the end of typeck, once all inference vars have
544
+ // been resolved or we errored. This is important as we can only check transmute
545
+ // on concrete types, but the output type may not be known yet (it would only
546
+ // be known if explicitly specified via turbofish).
547
+ self . deferred_transmute_checks . borrow_mut ( ) . push ( ( from, to, expr. span ) ) ;
548
+ }
535
549
if !tcx. features ( ) . unsized_fn_params {
536
550
// We want to remove some Sized bounds from std functions,
537
551
// but don't want to expose the removal to stable Rust.
0 commit comments