Auto merge of #87141 - spastorino:remove_impl_trait_in_bindings, r=oli-obk
Remove impl trait in bindings Closes #86729 r? `@oli-obk`
This commit is contained in:
commit
a72c360a30
113 changed files with 540 additions and 1954 deletions
|
@ -221,9 +221,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||
fcx.resume_yield_tys = Some((resume_ty, yield_ty));
|
||||
}
|
||||
|
||||
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
|
||||
let outer_hir_id = hir.local_def_id_to_hir_id(outer_def_id);
|
||||
GatherLocalsVisitor::new(&fcx, outer_hir_id).visit_body(body);
|
||||
GatherLocalsVisitor::new(&fcx).visit_body(body);
|
||||
|
||||
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
|
||||
// (as it's created inside the body itself, not passed in from outside).
|
||||
|
@ -665,13 +663,9 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
|
|||
span: Span,
|
||||
origin: &hir::OpaqueTyOrigin,
|
||||
) -> Result<(), ErrorReported> {
|
||||
if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
|
||||
{
|
||||
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
|
||||
match origin {
|
||||
hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
|
||||
hir::OpaqueTyOrigin::Binding => {
|
||||
binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
|
||||
}
|
||||
_ => opaque_type_cycle_error(tcx, def_id, span),
|
||||
}
|
||||
Err(ErrorReported)
|
||||
|
@ -704,8 +698,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||
// Checked when type checking the function containing them.
|
||||
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return,
|
||||
// Can have different predicates to their defining use
|
||||
hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::Misc | hir::OpaqueTyOrigin::TyAlias => {
|
||||
}
|
||||
hir::OpaqueTyOrigin::TyAlias => {}
|
||||
}
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
|
|
|
@ -4,12 +4,11 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
|||
use rustc_hir::PatKind;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
|
||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
parent_id: hir::HirId,
|
||||
// parameters are special cases of patterns, but we want to handle them as
|
||||
// *distinct* cases. so track when we are hitting a pattern *within* an fn
|
||||
// parameter.
|
||||
|
@ -17,8 +16,8 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
|
||||
pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>, parent_id: hir::HirId) -> Self {
|
||||
Self { fcx, parent_id, outermost_fn_param_pat: None }
|
||||
pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
|
||||
Self { fcx, outermost_fn_param_pat: None }
|
||||
}
|
||||
|
||||
fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
|
||||
|
@ -57,26 +56,15 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
|
|||
Some(ref ty) => {
|
||||
let o_ty = self.fcx.to_ty(&ty);
|
||||
|
||||
let revealed_ty = self.fcx.instantiate_opaque_types_from_value(
|
||||
self.parent_id,
|
||||
o_ty,
|
||||
ty.span,
|
||||
Some(sym::impl_trait_in_bindings),
|
||||
);
|
||||
|
||||
let c_ty =
|
||||
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(revealed_ty));
|
||||
debug!(
|
||||
"visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
|
||||
ty.hir_id, o_ty, revealed_ty, c_ty
|
||||
);
|
||||
let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty));
|
||||
debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
|
||||
self.fcx
|
||||
.typeck_results
|
||||
.borrow_mut()
|
||||
.user_provided_types_mut()
|
||||
.insert(ty.hir_id, c_ty);
|
||||
|
||||
Some(LocalTy { decl_ty: o_ty, revealed_ty })
|
||||
Some(LocalTy { decl_ty: o_ty, revealed_ty: o_ty })
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
|
|
@ -118,9 +118,9 @@ use rustc_middle::ty::{self, Ty, TyCtxt, UserType};
|
|||
use rustc_session::config;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::{self, BytePos, MultiSpan, Span};
|
||||
use rustc_span::{source_map::DUMMY_SP, sym};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::traits;
|
||||
|
@ -441,19 +441,12 @@ fn typeck_with_fallback<'tcx>(
|
|||
let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
|
||||
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
|
||||
|
||||
let revealed_ty = fcx.instantiate_opaque_types_from_value(
|
||||
id,
|
||||
expected_type,
|
||||
body.value.span,
|
||||
Some(sym::impl_trait_in_bindings),
|
||||
);
|
||||
|
||||
// Gather locals in statics (because of block expressions).
|
||||
GatherLocalsVisitor::new(&fcx, id).visit_body(body);
|
||||
GatherLocalsVisitor::new(&fcx).visit_body(body);
|
||||
|
||||
fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
|
||||
fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
|
||||
|
||||
fcx.write_ty(id, revealed_ty);
|
||||
fcx.write_ty(id, expected_type);
|
||||
|
||||
fcx
|
||||
};
|
||||
|
@ -573,66 +566,6 @@ fn get_owner_return_paths(
|
|||
})
|
||||
}
|
||||
|
||||
/// Emit an error for recursive opaque types in a `let` binding.
|
||||
fn binding_opaque_type_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
span: Span,
|
||||
partially_expanded_type: Ty<'tcx>,
|
||||
) {
|
||||
let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
|
||||
err.span_label(span, "cannot resolve opaque type");
|
||||
// Find the owner that declared this `impl Trait` type.
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let mut prev_hir_id = hir_id;
|
||||
let mut hir_id = tcx.hir().get_parent_node(hir_id);
|
||||
while let Some(node) = tcx.hir().find(hir_id) {
|
||||
match node {
|
||||
hir::Node::Local(hir::Local {
|
||||
pat,
|
||||
init: None,
|
||||
ty: Some(ty),
|
||||
source: hir::LocalSource::Normal,
|
||||
..
|
||||
}) => {
|
||||
err.span_label(pat.span, "this binding might not have a concrete type");
|
||||
err.span_suggestion_verbose(
|
||||
ty.span.shrink_to_hi(),
|
||||
"set the binding to a value for a concrete type to be resolved",
|
||||
" = /* value */".to_string(),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
hir::Node::Local(hir::Local {
|
||||
init: Some(expr),
|
||||
source: hir::LocalSource::Normal,
|
||||
..
|
||||
}) => {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let typeck_results =
|
||||
tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
|
||||
if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
|
||||
err.span_label(
|
||||
expr.span,
|
||||
&format!(
|
||||
"this is of type `{}`, which doesn't constrain \
|
||||
`{}` enough to arrive to a concrete type",
|
||||
ty, partially_expanded_type
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if prev_hir_id == hir_id {
|
||||
break;
|
||||
}
|
||||
prev_hir_id = hir_id;
|
||||
hir_id = tcx.hir().get_parent_node(hir_id);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
// Forbid defining intrinsics in Rust code,
|
||||
// as they must always be defined by the compiler.
|
||||
fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
|
||||
|
|
|
@ -521,8 +521,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
let mut skip_add = false;
|
||||
|
||||
if let ty::Opaque(definition_ty_def_id, _substs) = *definition_ty.kind() {
|
||||
if let hir::OpaqueTyOrigin::Misc | hir::OpaqueTyOrigin::TyAlias = opaque_defn.origin
|
||||
{
|
||||
if opaque_defn.origin == hir::OpaqueTyOrigin::TyAlias {
|
||||
if opaque_type_key.def_id == definition_ty_def_id {
|
||||
debug!(
|
||||
"skipping adding concrete definition for opaque type {:?} {:?}",
|
||||
|
|
|
@ -356,9 +356,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_adt(def, substs)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }) => {
|
||||
let_position_impl_trait_type(tcx, def_id)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {
|
||||
find_opaque_ty_constraints(tcx, def_id)
|
||||
}
|
||||
|
@ -696,60 +693,6 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Retrieve the inferred concrete type for let position impl trait.
|
||||
///
|
||||
/// This is different to other kinds of impl trait because:
|
||||
///
|
||||
/// 1. We know which function contains the defining use (the function that
|
||||
/// contains the let statement)
|
||||
/// 2. We do not currently allow (free) lifetimes in the return type. `let`
|
||||
/// statements in some statically unreachable code are removed from the MIR
|
||||
/// by the time we borrow check, and it's not clear how we should handle
|
||||
/// those.
|
||||
fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty<'_> {
|
||||
let scope = tcx.hir().get_defining_scope(tcx.hir().local_def_id_to_hir_id(opaque_ty_id));
|
||||
let scope_def_id = tcx.hir().local_def_id(scope);
|
||||
|
||||
let opaque_ty_def_id = opaque_ty_id.to_def_id();
|
||||
|
||||
let owner_typeck_results = tcx.typeck(scope_def_id);
|
||||
let concrete_ty = owner_typeck_results
|
||||
.concrete_opaque_types
|
||||
.get_by(|(key, _)| key.def_id == opaque_ty_def_id)
|
||||
.map(|concrete_ty| *concrete_ty)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"owner {:?} has no opaque type for {:?} in its typeck results",
|
||||
scope_def_id, opaque_ty_id
|
||||
),
|
||||
);
|
||||
if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
|
||||
// Some error in the owner fn prevented us from populating the
|
||||
// `concrete_opaque_types` table.
|
||||
tcx.ty_error()
|
||||
} else {
|
||||
// We failed to resolve the opaque type or it resolves to
|
||||
// itself. Return the non-revealed type, which should result in
|
||||
// E0720.
|
||||
tcx.mk_opaque(
|
||||
opaque_ty_def_id,
|
||||
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
|
||||
)
|
||||
}
|
||||
});
|
||||
debug!("concrete_ty = {:?}", concrete_ty);
|
||||
if concrete_ty.has_erased_regions() {
|
||||
// FIXME(impl_trait_in_bindings) Handle this case.
|
||||
tcx.sess.span_fatal(
|
||||
tcx.hir().span(tcx.hir().local_def_id_to_hir_id(opaque_ty_id)),
|
||||
"lifetimes in impl Trait types in bindings are not currently supported",
|
||||
);
|
||||
}
|
||||
concrete_ty
|
||||
}
|
||||
|
||||
fn infer_placeholder_type<'a>(
|
||||
tcx: TyCtxt<'a>,
|
||||
def_id: LocalDefId,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue