Auto merge of #92007 - oli-obk:lazy_tait2, r=nikomatsakis
Lazy type-alias-impl-trait Previously opaque types were processed by 1. replacing all mentions of them with inference variables 2. memorizing these inference variables in a side-table 3. at the end of typeck, resolve the inference variables in the side table and use the resolved type as the hidden type of the opaque type This worked okayish for `impl Trait` in return position, but required lots of roundabout type inference hacks and processing. This PR instead stops this process of replacing opaque types with inference variables, and just keeps the opaque types around. Whenever an opaque type `O` is compared with another type `T`, we make the comparison succeed and record `T` as the hidden type. If `O` is compared to `U` while there is a recorded hidden type for it, we grab the recorded type (`T`) and compare that against `U`. This makes implementing * https://github.com/rust-lang/rfcs/pull/2515 much simpler (previous attempts on the inference based scheme were very prone to ICEs and general misbehaviour that was not explainable except by random implementation defined oddities). r? `@nikomatsakis` fixes #93411 fixes #88236
This commit is contained in:
commit
e7cc3bddbe
359 changed files with 3311 additions and 2447 deletions
|
@ -1,8 +1,8 @@
|
|||
use crate::build::matches::ArmHasGuard;
|
||||
use crate::build::ForGuard::OutsideGuard;
|
||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_middle::{mir::*, ty};
|
||||
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_span::Span;
|
||||
|
@ -192,7 +192,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// This return type is usually `()`, unless the block is diverging, in which case the
|
||||
// return type is `!`. For the unit type, we need to actually return the unit, but in
|
||||
// the case of `!`, no return value is required, as the block will never return.
|
||||
if destination_ty.is_unit() {
|
||||
// Opaque types of empty bodies also need this unit assignment, in order to infer that their
|
||||
// type is actually unit. Otherwise there will be no defining use found in the MIR.
|
||||
if destination_ty.is_unit() || matches!(destination_ty.kind(), ty::Opaque(..)) {
|
||||
// We only want to assign an implicit `()` as the return value of the block if the
|
||||
// block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
|
||||
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue