Add inferred args to typeck
This commit is contained in:
parent
417b098cfc
commit
3605675bb1
18 changed files with 132 additions and 52 deletions
|
@ -437,7 +437,7 @@ pub trait Visitor<'v>: Sized {
|
|||
walk_label(self, label)
|
||||
}
|
||||
fn visit_infer(&mut self, inf: &'v InferArg) {
|
||||
self.visit_id(inf.hir_id);
|
||||
walk_inf(self, inf);
|
||||
}
|
||||
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
|
||||
match generic_arg {
|
||||
|
@ -447,11 +447,6 @@ pub trait Visitor<'v>: Sized {
|
|||
GenericArg::Infer(inf) => self.visit_infer(inf),
|
||||
}
|
||||
}
|
||||
/*
|
||||
fn tcx(&self) -> Option<&TyCtxt<'tcx>> {
|
||||
None
|
||||
}
|
||||
*/
|
||||
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
||||
walk_lifetime(self, lifetime)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,11 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
|
|||
hir_visit::walk_ty(self, t);
|
||||
}
|
||||
|
||||
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||
lint_callback!(self, check_infer, inf);
|
||||
hir_visit::walk_inf(self, inf);
|
||||
}
|
||||
|
||||
fn visit_name(&mut self, sp: Span, name: Symbol) {
|
||||
lint_callback!(self, check_name, sp, name);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ macro_rules! late_lint_methods {
|
|||
fn check_expr(a: &$hir hir::Expr<$hir>);
|
||||
fn check_expr_post(a: &$hir hir::Expr<$hir>);
|
||||
fn check_ty(a: &$hir hir::Ty<$hir>);
|
||||
fn check_infer(a: &$hir hir::InferArg);
|
||||
fn check_generic_arg(a: &$hir hir::GenericArg<$hir>);
|
||||
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
|
||||
fn check_generics(a: &$hir hir::Generics<$hir>);
|
||||
|
|
|
@ -272,11 +272,11 @@ impl<'hir> Map<'hir> {
|
|||
GenericParamKind::Type { .. } => DefKind::TyParam,
|
||||
GenericParamKind::Const { .. } => DefKind::ConstParam,
|
||||
},
|
||||
Node::Infer(_) => todo!(),
|
||||
Node::Crate(_) => DefKind::Mod,
|
||||
Node::Stmt(_)
|
||||
| Node::PathSegment(_)
|
||||
| Node::Ty(_)
|
||||
| Node::Infer(_)
|
||||
| Node::TraitRef(_)
|
||||
| Node::Pat(_)
|
||||
| Node::Binding(_)
|
||||
|
|
|
@ -133,11 +133,6 @@ rustc_queries! {
|
|||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
|
||||
query generic_arg_for_infer_arg(key: DefId) -> hir::GenericArg<'tcx> {
|
||||
desc { |tcx| "computes concrete type for inference, `{}`", tcx.def_path_str(key) }
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
}
|
||||
|
||||
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
|
||||
/// predicates (where-clauses) that must be proven true in order
|
||||
/// to reference it. This is almost always the "predicates query"
|
||||
|
|
|
@ -1191,16 +1191,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
|||
fn visit_generic_arg(&mut self, generic_arg: &'tcx hir::GenericArg<'tcx>) {
|
||||
match generic_arg {
|
||||
hir::GenericArg::Type(t) => self.visit_ty(t),
|
||||
hir::GenericArg::Infer(inf) => {
|
||||
self.span = inf.span;
|
||||
let parent_hir_id = self.tcx.hir().get_parent_node(inf.hir_id);
|
||||
if let Some(typeck_results) = self.maybe_typeck_results {
|
||||
let node_substs = typeck_results.node_substs(parent_hir_id);
|
||||
for ty in node_substs.types() {
|
||||
self.visit(ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::GenericArg::Infer(inf) => self.visit_infer(inf),
|
||||
hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
|
||||
}
|
||||
}
|
||||
|
@ -1224,6 +1215,23 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
|||
intravisit::walk_ty(self, hir_ty);
|
||||
}
|
||||
|
||||
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||
self.span = inf.span;
|
||||
if let Some(typeck_results) = self.maybe_typeck_results {
|
||||
if let Some(ty) = typeck_results.node_type_opt(inf.hir_id) {
|
||||
if self.visit(ty).is_break() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FIXME see above note for same issue.
|
||||
if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
intravisit::walk_inf(self, inf);
|
||||
}
|
||||
|
||||
fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
|
||||
self.span = trait_ref.path.span;
|
||||
if self.maybe_typeck_results.is_none() {
|
||||
|
|
|
@ -18,23 +18,6 @@ use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
|
|||
use rustc_span::{symbol::kw, MultiSpan, Span};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
/*
|
||||
pub fn generic_arg_for_infer_arg<'tcx>(tcx: TyCtxt<'tcx>, did: LocalDefId) -> GenericArg<'tcx> {
|
||||
todo!()
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(did);
|
||||
let arg = match tcx.hir().get(hir_id) {
|
||||
hir::Node::GenericParam(hir::GenericParam {
|
||||
kind: hir::GenericParamKind::Const { ty: _, default: _ },
|
||||
..
|
||||
}) => todo!(),
|
||||
_ => bug!("Expected GenericParam for generic_arg_for_infer_arg"),
|
||||
};
|
||||
|
||||
assert!(!matches!(arg, GenericArg::Infer(_)));
|
||||
arg
|
||||
}
|
||||
*/
|
||||
|
||||
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// Report an error that a generic argument did not match the generic parameter that was
|
||||
/// expected.
|
||||
|
|
|
@ -479,6 +479,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
param.def_id,
|
||||
Some(arg.id()),
|
||||
arg.span(),
|
||||
None,
|
||||
|_, _| {
|
||||
// Default generic parameters may not be marked
|
||||
// with stability attributes, i.e. when the
|
||||
|
|
|
@ -581,6 +581,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
|
||||
match self.typeck_results.borrow().node_types().get(id) {
|
||||
Some(&t) => Some(t),
|
||||
None if self.is_tainted_by_errors() => Some(self.tcx.ty_error()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
|
||||
pub fn register_wf_obligation(
|
||||
&self,
|
||||
|
|
|
@ -331,6 +331,15 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
|
|||
let ty = self.resolve(ty, &hir_ty.span);
|
||||
self.write_ty_to_typeck_results(hir_ty.hir_id, ty);
|
||||
}
|
||||
|
||||
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||
intravisit::walk_inf(self, inf);
|
||||
// Ignore cases where the inference is a const.
|
||||
if let Some(ty) = self.fcx.node_ty_opt(inf.hir_id) {
|
||||
let ty = self.resolve(ty, &inf.span);
|
||||
self.write_ty_to_typeck_results(inf.hir_id, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
|
|
|
@ -133,6 +133,7 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
|
|||
match generic_arg {
|
||||
hir::GenericArg::Infer(inf) => {
|
||||
self.0.push(inf.span);
|
||||
intravisit::walk_inf(self, inf);
|
||||
}
|
||||
hir::GenericArg::Type(t) => self.visit_ty(t),
|
||||
_ => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue