Skip to content

Commit

Permalink
Auto merge of #101831 - compiler-errors:issue-75899, r=jackh726
Browse files Browse the repository at this point in the history
Normalize struct field types in `confirm_builtin_unsize_candidate`

Fixes #75899

---

edited to move the normalization into `confirm_builtin_unsize_candidate` instead of the coercion code.
  • Loading branch information
bors committed Sep 15, 2022
2 parents df34db9 + 7893ca7 commit cf9ed0d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
22 changes: 19 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,9 +1039,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return Err(Unimplemented);
}

// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
let source_tail = tail_field_ty.subst(tcx, substs_a);
let target_tail = tail_field_ty.subst(tcx, substs_b);
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
// normalizing in the process, since `type_of` returns something directly from
// astconv (which means it's un-normalized).
let source_tail = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
tail_field_ty.subst(tcx, substs_a),
&mut nested,
);
let target_tail = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
tail_field_ty.subst(tcx, substs_b),
&mut nested,
);

// Check that the source struct with the target's
// unsizing parameters is equal to the target.
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/unsized/issue-75899-but-gats.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// check-pass

use std::fmt::Debug;
use std::marker::PhantomData;

trait Foo {
type Gat<'a>: ?Sized where Self: 'a;
}

struct Bar<'a, T: Foo + 'a>(T::Gat<'a>);

struct Baz<T: ?Sized>(PhantomData<T>);

impl<T: ?Sized> Foo for Baz<T> {
type Gat<'a> = T where Self: 'a;
}

fn main() {
let x = Bar::<'_, Baz<()>>(());
let y: &Bar<'_, Baz<dyn Debug>> = &x;
}
18 changes: 18 additions & 0 deletions src/test/ui/unsized/issue-75899.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// check-pass

trait Trait {}
impl<T> Trait for T {}

trait Noop {
type Assoc: ?Sized;
}
impl<T: ?Sized> Noop for T {
type Assoc = T;
}

struct NoopNewtype<T: ?Sized + Noop>(T::Assoc);
fn coerce_newtype<T: Trait>(x: &NoopNewtype<T>) -> &NoopNewtype<dyn Trait + '_> {
x
}

fn main() {}

0 comments on commit cf9ed0d

Please sign in to comment.