Skip to content

Commit

Permalink
Rollup merge of #125819 - oli-obk:localize, r=fmease
Browse files Browse the repository at this point in the history
Various `HirTyLowerer` cleanups

Previously there was some ad-hoc specialization going on, because you could call `allows_infer`, which basically was deciding between whether the trait object was backed by `FnCtxt` or by `ItemCtxt`. I moved all the different logic into dedicated methods on `HirTyLowerer` and removed `allows_infer`

best reviewed commit-by-commit
  • Loading branch information
matthiaskrgr committed Jun 5, 2024
2 parents e174512 + c8a331a commit 94c19c6
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 210 deletions.
117 changes: 105 additions & 12 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ use rustc_ast::Recovered;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_errors::{struct_span_code_err, Applicability, Diag, ErrorGuaranteed, StashKey, E0228};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::intravisit::{self, walk_generics, Visitor};
use rustc_hir::{self as hir};
use rustc_hir::{GenericParamKind, Node};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
Expand All @@ -44,7 +44,7 @@ use std::ops::Bound;

use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors;
use crate::hir_ty_lowering::HirTyLowerer;
use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
pub use type_of::test_opaque_hidden_types;

mod generics_of;
Expand Down Expand Up @@ -370,16 +370,26 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
self.tcx
}

fn item_def_id(&self) -> DefId {
self.item_def_id.to_def_id()
fn item_def_id(&self) -> LocalDefId {
self.item_def_id
}

fn allow_infer(&self) -> bool {
false
}

fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
None
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
let e = struct_span_code_err!(
self.tcx().dcx(),
span,
E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
)
.emit();
self.set_tainted_by_errors(e);
ty::Region::new_error(self.tcx(), e)
} else {
// This indicates an illegal lifetime in a non-assoc-trait position
ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")
}
}

fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
Expand Down Expand Up @@ -510,6 +520,89 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
self.tainted_by_errors.set(Some(err));
}

fn lower_fn_sig(
&self,
decl: &hir::FnDecl<'tcx>,
generics: Option<&hir::Generics<'_>>,
hir_id: rustc_hir::HirId,
hir_ty: Option<&hir::Ty<'_>>,
) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
let tcx = self.tcx();
// We proactively collect all the inferred type params to emit a single error per fn def.
let mut visitor = HirPlaceholderCollector::default();
let mut infer_replacements = vec![];

if let Some(generics) = generics {
walk_generics(&mut visitor, generics);
}

let input_tys = decl
.inputs
.iter()
.enumerate()
.map(|(i, a)| {
if let hir::TyKind::Infer = a.kind {
if let Some(suggested_ty) =
self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
{
infer_replacements.push((a.span, suggested_ty.to_string()));
return Ty::new_error_with_message(tcx, a.span, suggested_ty.to_string());
}
}

// Only visit the type looking for `_` if we didn't fix the type above
visitor.visit_ty(a);
self.lowerer().lower_arg_ty(a, None)
})
.collect();

let output_ty = match decl.output {
hir::FnRetTy::Return(output) => {
if let hir::TyKind::Infer = output.kind
&& let Some(suggested_ty) =
self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
{
infer_replacements.push((output.span, suggested_ty.to_string()));
Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string())
} else {
visitor.visit_ty(output);
self.lower_ty(output)
}
}
hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
};

if !(visitor.0.is_empty() && infer_replacements.is_empty()) {
// We check for the presence of
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.

let mut diag = crate::collect::placeholder_type_error_diag(
tcx,
generics,
visitor.0,
infer_replacements.iter().map(|(s, _)| *s).collect(),
true,
hir_ty,
"function",
);

if !infer_replacements.is_empty() {
diag.multipart_suggestion(
format!(
"try replacing `_` with the type{} in the corresponding trait method signature",
rustc_errors::pluralize!(infer_replacements.len()),
),
infer_replacements,
Applicability::MachineApplicable,
);
}

self.set_tainted_by_errors(diag.emit());
}

(input_tys, output_ty)
}
}

/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
Expand Down
14 changes: 8 additions & 6 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::bounds::Bounds;
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
use hir::{HirId, Node};
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
Expand Down Expand Up @@ -117,7 +117,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
let mut is_trait = None;
let mut is_default_impl_trait = None;

// FIXME: Should ItemCtxt take a LocalDefId?
let icx = ItemCtxt::new(tcx, def_id);

const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
Expand Down Expand Up @@ -244,12 +243,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}

hir::WherePredicate::RegionPredicate(region_pred) => {
let r1 = icx.lowerer().lower_lifetime(region_pred.lifetime, None);
let r1 = icx
.lowerer()
.lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
predicates.extend(region_pred.bounds.iter().map(|bound| {
let (r2, span) = match bound {
hir::GenericBound::Outlives(lt) => {
(icx.lowerer().lower_lifetime(lt, None), lt.ident.span)
}
hir::GenericBound::Outlives(lt) => (
icx.lowerer().lower_lifetime(lt, RegionInferReason::RegionPredicate),
lt.ident.span,
),
bound => {
span_bug!(
bound.span(),
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use crate::bounds::Bounds;
use crate::errors;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};

use super::RegionInferReason;

impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Add a `Sized` bound to the `bounds` if appropriate.
///
Expand Down Expand Up @@ -166,7 +168,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
);
}
hir::GenericBound::Outlives(lifetime) => {
let region = self.lower_lifetime(lifetime, None);
let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
bounds.push_region_bound(
self.tcx(),
ty::Binder::bind_with_vars(
Expand Down
Loading

0 comments on commit 94c19c6

Please sign in to comment.