Rollup merge of #119803 - oli-obk:even_more_follow_up_errors, r=compiler-errors
Silence some follow-up errors [1/x] this is one piece of the requested cleanups from https://github.com/rust-lang/rust/pull/117449 When we use `-> impl SomeTrait<_>` as a return type, we are both using the "infer return type suggestion" code path, and the infer opaque type code path within the same function. That can lead to confusing diagnostics, so silence all opaque type diagnostics in that case.
This commit is contained in:
commit
d37de53425
7 changed files with 73 additions and 86 deletions
|
@ -642,7 +642,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
tcx.ensure().generics_of(def_id);
|
||||
tcx.ensure().type_of(def_id);
|
||||
tcx.ensure().predicates_of(def_id);
|
||||
if !is_suggestable_infer_ty(ty) {
|
||||
if !ty.is_suggestable_infer_ty() {
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_item(it);
|
||||
placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr());
|
||||
|
@ -674,7 +674,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||
hir::TraitItemKind::Const(ty, body_id) => {
|
||||
tcx.ensure().type_of(def_id);
|
||||
if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
|
||||
&& !(is_suggestable_infer_ty(ty) && body_id.is_some())
|
||||
&& !(ty.is_suggestable_infer_ty() && body_id.is_some())
|
||||
{
|
||||
// Account for `const C: _;`.
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
|
@ -726,7 +726,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
|
|||
}
|
||||
hir::ImplItemKind::Const(ty, _) => {
|
||||
// Account for `const T: _ = ..;`
|
||||
if !is_suggestable_infer_ty(ty) {
|
||||
if !ty.is_suggestable_infer_ty() {
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_impl_item(impl_item);
|
||||
placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant");
|
||||
|
@ -1054,48 +1054,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
|||
}
|
||||
}
|
||||
|
||||
fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
|
||||
generic_args.iter().any(|arg| match arg {
|
||||
hir::GenericArg::Type(ty) => is_suggestable_infer_ty(ty),
|
||||
hir::GenericArg::Infer(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
|
||||
/// use inference to provide suggestions for the appropriate type if possible.
|
||||
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
|
||||
debug!(?ty);
|
||||
use hir::TyKind::*;
|
||||
match &ty.kind {
|
||||
Infer => true,
|
||||
Slice(ty) => is_suggestable_infer_ty(ty),
|
||||
Array(ty, length) => {
|
||||
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
|
||||
}
|
||||
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
|
||||
Ptr(mut_ty) | Ref(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
|
||||
OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
|
||||
Path(hir::QPath::TypeRelative(ty, segment)) => {
|
||||
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
|
||||
}
|
||||
Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => {
|
||||
ty_opt.is_some_and(is_suggestable_infer_ty)
|
||||
|| segments.iter().any(|segment| are_suggestable_generic_args(segment.args().args))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> {
|
||||
if let hir::FnRetTy::Return(ty) = output {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
return Some(*ty);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<'_>> {
|
||||
use rustc_hir::Node::*;
|
||||
|
@ -1188,7 +1146,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||
) -> ty::PolyFnSig<'tcx> {
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
match get_infer_ret_ty(&sig.decl.output) {
|
||||
match sig.decl.output.get_infer_ret_ty() {
|
||||
Some(ty) => {
|
||||
let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
|
||||
// Typeck doesn't expect erased regions to be returned from `type_of`.
|
||||
|
|
|
@ -9,8 +9,8 @@ use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, Ty
|
|||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use super::bad_placeholder;
|
||||
use super::ItemCtxt;
|
||||
use super::{bad_placeholder, is_suggestable_infer_ty};
|
||||
pub use opaque::test_opaque_hidden_types;
|
||||
|
||||
mod opaque;
|
||||
|
@ -368,7 +368,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
}
|
||||
TraitItemKind::Const(ty, body_id) => body_id
|
||||
.and_then(|body_id| {
|
||||
is_suggestable_infer_ty(ty).then(|| {
|
||||
ty.is_suggestable_infer_ty().then(|| {
|
||||
infer_placeholder_type(
|
||||
tcx,
|
||||
def_id,
|
||||
|
@ -392,7 +392,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ImplItemKind::Const(ty, body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
if ty.is_suggestable_infer_ty() {
|
||||
infer_placeholder_type(
|
||||
tcx,
|
||||
def_id,
|
||||
|
@ -416,7 +416,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::Static(ty, .., body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
if ty.is_suggestable_infer_ty() {
|
||||
infer_placeholder_type(
|
||||
tcx,
|
||||
def_id,
|
||||
|
@ -430,7 +430,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
}
|
||||
}
|
||||
ItemKind::Const(ty, _, body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
if ty.is_suggestable_infer_ty() {
|
||||
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
|
@ -603,6 +603,8 @@ fn infer_placeholder_type<'a>(
|
|||
}
|
||||
|
||||
err.emit();
|
||||
// diagnostic stashing loses the information of whether something is a hard error.
|
||||
Ty::new_error_with_message(tcx, span, "ItemNoType is a hard error")
|
||||
}
|
||||
None => {
|
||||
let mut diag = bad_placeholder(tcx, vec![span], kind);
|
||||
|
@ -623,15 +625,9 @@ fn infer_placeholder_type<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
diag.emit();
|
||||
Ty::new_error(tcx, diag.emit())
|
||||
}
|
||||
}
|
||||
|
||||
// Typeck doesn't expect erased regions to be returned from `type_of`.
|
||||
tcx.fold_regions(ty, |r, _| match *r {
|
||||
ty::ReErased => tcx.lifetimes.re_static,
|
||||
_ => r,
|
||||
})
|
||||
}
|
||||
|
||||
fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
|
||||
|
|
|
@ -134,6 +134,21 @@ impl TaitConstraintLocator<'_> {
|
|||
debug!("no constraint: no typeck results");
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(hir_sig) = self.tcx.hir_node_by_def_id(item_def_id).fn_decl() {
|
||||
if hir_sig.output.get_infer_ret_ty().is_some() {
|
||||
let guar = self.tcx.dcx().span_delayed_bug(
|
||||
hir_sig.output.span(),
|
||||
"inferring return types and opaque types do not mix well",
|
||||
);
|
||||
self.found = Some(ty::OpaqueHiddenType {
|
||||
span: DUMMY_SP,
|
||||
ty: Ty::new_error(self.tcx, guar),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Calling `mir_borrowck` can lead to cycle errors through
|
||||
// const-checking, avoid calling it if we don't have to.
|
||||
// ```rust
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue