Skip to content

Commit

Permalink
Rollup merge of rust-lang#70982 - ldm0:fncoerce, r=eddyb
Browse files Browse the repository at this point in the history
Normalize function signature in function casting check procedure

Fixes rust-lang#54094
```rust
trait Zoo {
    type X;
}

impl Zoo for u16 {
    type X = usize;
}

fn foo(abc: <u16 as Zoo>::X) {}

fn main() {
    let x: *const u8 = foo as _;
}
```

Currently a `FnDef` need to be checked if it's able to cast to `FnPtr` before it is actually casted. But the signature of `FnPtr` target's associated types are not normalized:

https://github.com/rust-lang/rust/blob/96d77f0e5f103612d62b85938aacfb33f5768433/src/librustc_typeck/check/cast.rs#L536-L553
However, during the coercion check, the signature of `FnPtr` target's associated types are normalized (The `<u16 as Zoo>::X` turns into `usize`).

https://github.com/rust-lang/rust/blob/96d77f0e5f103612d62b85938aacfb33f5768433/src/librustc_typeck/check/coercion.rs#L687-L729

This inconsistency leads to the error:`Err(Sorts(ExpectedFound { expected: <u16 as Zoo>::X, found: usize }))`.
  • Loading branch information
Dylan-DPC committed Apr 10, 2020
2 parents 12e3c7b + 75cc403 commit 2af0b16
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/librustc_typeck/check/cast.rs
Expand Up @@ -536,7 +536,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
match self.expr_ty.kind {
ty::FnDef(..) => {
// Attempt a coercion to a fn pointer type.
let f = self.expr_ty.fn_sig(fcx.tcx);
let f = fcx.normalize_associated_types_in(
self.expr.span,
&self.expr_ty.fn_sig(fcx.tcx),
);
let res = fcx.try_coerce(
self.expr,
self.expr_ty,
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/issues/issue-54094.rs
@@ -0,0 +1,14 @@
// check-pass
trait Zoo {
type X;
}

impl Zoo for u16 {
type X = usize;
}

fn foo(abc: <u16 as Zoo>::X) {}

fn main() {
let x: *const u8 = foo as _;
}

0 comments on commit 2af0b16

Please sign in to comment.