Normalize struct tail properly in borrowck and hir typeck
This commit is contained in:
parent
41dd149fd6
commit
c5205e9d56
@ -7,6 +7,7 @@
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
|
||||
use rustc_trait_selection::traits::ObligationCause;
|
||||
|
||||
@ -165,6 +166,52 @@ pub(super) fn normalize_with_category<T>(
|
||||
result.unwrap_or(value)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn struct_tail(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
location: impl NormalizeLocation,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
if self.infcx.next_trait_solver() {
|
||||
let body = self.body;
|
||||
let param_env = self.param_env;
|
||||
self.fully_perform_op(
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Boring,
|
||||
CustomTypeOp::new(
|
||||
|ocx| {
|
||||
let structurally_normalize = |ty| {
|
||||
ocx.structurally_normalize(
|
||||
&ObligationCause::misc(
|
||||
location.to_locations().span(body),
|
||||
body.source.def_id().expect_local(),
|
||||
),
|
||||
param_env,
|
||||
ty,
|
||||
)
|
||||
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
|
||||
};
|
||||
|
||||
let tail = tcx.struct_tail_with_normalize(
|
||||
ty,
|
||||
structurally_normalize,
|
||||
|| {},
|
||||
);
|
||||
|
||||
Ok(tail)
|
||||
},
|
||||
"normalizing struct tail",
|
||||
),
|
||||
)
|
||||
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
|
||||
} else {
|
||||
let mut normalize = |ty| self.normalize(ty, location);
|
||||
let tail = tcx.struct_tail_with_normalize(ty, &mut normalize, || {});
|
||||
normalize(tail)
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn ascribe_user_type(
|
||||
&mut self,
|
||||
|
@ -2329,17 +2329,8 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
||||
let cast_ty_to = CastTy::from_ty(*ty);
|
||||
match (cast_ty_from, cast_ty_to) {
|
||||
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
|
||||
let mut normalize = |t| self.normalize(t, location);
|
||||
|
||||
// N.B. `struct_tail_with_normalize` only "structurally resolves"
|
||||
// the type. It is not fully normalized, so we have to normalize it
|
||||
// afterwards.
|
||||
let src_tail =
|
||||
tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ());
|
||||
let src_tail = normalize(src_tail);
|
||||
let dst_tail =
|
||||
tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ());
|
||||
let dst_tail = normalize(dst_tail);
|
||||
let src_tail = self.struct_tail(src.ty, location);
|
||||
let dst_tail = self.struct_tail(dst.ty, location);
|
||||
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).
|
||||
|
@ -97,6 +97,8 @@ fn pointer_kind(
|
||||
return Ok(Some(PointerKind::Thin));
|
||||
}
|
||||
|
||||
let t = self.try_structurally_resolve_type(span, t);
|
||||
|
||||
Ok(match *t.kind() {
|
||||
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
|
||||
ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty)),
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:21:17
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17
|
||||
|
|
||||
LL | fn m<'a>() {
|
||||
| -- lifetime `'a` defined here
|
@ -0,0 +1,15 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17
|
||||
|
|
||||
LL | fn m<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let unsend: *const dyn Cat<'a> = &();
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of the type `S<dyn Cat<'_>>`, which makes the generic argument `dyn Cat<'_>` invariant
|
||||
= note: the struct `S<T>` is invariant over the parameter `T`
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -1,3 +1,6 @@
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@ check-fail
|
||||
//
|
||||
// Make sure we can't trick the compiler by using a projection.
|
||||
|
Loading…
Reference in New Issue
Block a user