Skip to content

Commit 3605675

Browse files
committed
Add inferred args to typeck
1 parent 417b098 commit 3605675

File tree

18 files changed

+132
-52
lines changed

18 files changed

+132
-52
lines changed

compiler/rustc_hir/src/intravisit.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ pub trait Visitor<'v>: Sized {
437437
walk_label(self, label)
438438
}
439439
fn visit_infer(&mut self, inf: &'v InferArg) {
440-
self.visit_id(inf.hir_id);
440+
walk_inf(self, inf);
441441
}
442442
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
443443
match generic_arg {
@@ -447,11 +447,6 @@ pub trait Visitor<'v>: Sized {
447447
GenericArg::Infer(inf) => self.visit_infer(inf),
448448
}
449449
}
450-
/*
451-
fn tcx(&self) -> Option<&TyCtxt<'tcx>> {
452-
None
453-
}
454-
*/
455450
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
456451
walk_lifetime(self, lifetime)
457452
}

compiler/rustc_lint/src/late.rs

+5
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
244244
hir_visit::walk_ty(self, t);
245245
}
246246

247+
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
248+
lint_callback!(self, check_infer, inf);
249+
hir_visit::walk_inf(self, inf);
250+
}
251+
247252
fn visit_name(&mut self, sp: Span, name: Symbol) {
248253
lint_callback!(self, check_name, sp, name);
249254
}

compiler/rustc_lint/src/passes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ macro_rules! late_lint_methods {
3333
fn check_expr(a: &$hir hir::Expr<$hir>);
3434
fn check_expr_post(a: &$hir hir::Expr<$hir>);
3535
fn check_ty(a: &$hir hir::Ty<$hir>);
36+
fn check_infer(a: &$hir hir::InferArg);
3637
fn check_generic_arg(a: &$hir hir::GenericArg<$hir>);
3738
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
3839
fn check_generics(a: &$hir hir::Generics<$hir>);

compiler/rustc_middle/src/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,11 @@ impl<'hir> Map<'hir> {
272272
GenericParamKind::Type { .. } => DefKind::TyParam,
273273
GenericParamKind::Const { .. } => DefKind::ConstParam,
274274
},
275-
Node::Infer(_) => todo!(),
276275
Node::Crate(_) => DefKind::Mod,
277276
Node::Stmt(_)
278277
| Node::PathSegment(_)
279278
| Node::Ty(_)
279+
| Node::Infer(_)
280280
| Node::TraitRef(_)
281281
| Node::Pat(_)
282282
| Node::Binding(_)

compiler/rustc_middle/src/query/mod.rs

-5
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,6 @@ rustc_queries! {
133133
cache_on_disk_if { key.is_local() }
134134
}
135135

136-
query generic_arg_for_infer_arg(key: DefId) -> hir::GenericArg<'tcx> {
137-
desc { |tcx| "computes concrete type for inference, `{}`", tcx.def_path_str(key) }
138-
storage(ArenaCacheSelector<'tcx>)
139-
}
140-
141136
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
142137
/// predicates (where-clauses) that must be proven true in order
143138
/// to reference it. This is almost always the "predicates query"

compiler/rustc_privacy/src/lib.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -1191,16 +1191,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
11911191
fn visit_generic_arg(&mut self, generic_arg: &'tcx hir::GenericArg<'tcx>) {
11921192
match generic_arg {
11931193
hir::GenericArg::Type(t) => self.visit_ty(t),
1194-
hir::GenericArg::Infer(inf) => {
1195-
self.span = inf.span;
1196-
let parent_hir_id = self.tcx.hir().get_parent_node(inf.hir_id);
1197-
if let Some(typeck_results) = self.maybe_typeck_results {
1198-
let node_substs = typeck_results.node_substs(parent_hir_id);
1199-
for ty in node_substs.types() {
1200-
self.visit(ty);
1201-
}
1202-
}
1203-
}
1194+
hir::GenericArg::Infer(inf) => self.visit_infer(inf),
12041195
hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
12051196
}
12061197
}
@@ -1224,6 +1215,23 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
12241215
intravisit::walk_ty(self, hir_ty);
12251216
}
12261217

1218+
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
1219+
self.span = inf.span;
1220+
if let Some(typeck_results) = self.maybe_typeck_results {
1221+
if let Some(ty) = typeck_results.node_type_opt(inf.hir_id) {
1222+
if self.visit(ty).is_break() {
1223+
return;
1224+
}
1225+
}
1226+
} else {
1227+
// FIXME see above note for same issue.
1228+
if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() {
1229+
return;
1230+
}
1231+
}
1232+
intravisit::walk_inf(self, inf);
1233+
}
1234+
12271235
fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
12281236
self.span = trait_ref.path.span;
12291237
if self.maybe_typeck_results.is_none() {

compiler/rustc_typeck/src/astconv/generics.rs

-17
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,6 @@ use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
1818
use rustc_span::{symbol::kw, MultiSpan, Span};
1919
use smallvec::SmallVec;
2020

21-
/*
22-
pub fn generic_arg_for_infer_arg<'tcx>(tcx: TyCtxt<'tcx>, did: LocalDefId) -> GenericArg<'tcx> {
23-
todo!()
24-
let hir_id = tcx.hir().local_def_id_to_hir_id(did);
25-
let arg = match tcx.hir().get(hir_id) {
26-
hir::Node::GenericParam(hir::GenericParam {
27-
kind: hir::GenericParamKind::Const { ty: _, default: _ },
28-
..
29-
}) => todo!(),
30-
_ => bug!("Expected GenericParam for generic_arg_for_infer_arg"),
31-
};
32-
33-
assert!(!matches!(arg, GenericArg::Infer(_)));
34-
arg
35-
}
36-
*/
37-
3821
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
3922
/// Report an error that a generic argument did not match the generic parameter that was
4023
/// expected.

compiler/rustc_typeck/src/astconv/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
479479
param.def_id,
480480
Some(arg.id()),
481481
arg.span(),
482+
None,
482483
|_, _| {
483484
// Default generic parameters may not be marked
484485
// with stability attributes, i.e. when the

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+8
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
581581
}
582582
}
583583

584+
pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
585+
match self.typeck_results.borrow().node_types().get(id) {
586+
Some(&t) => Some(t),
587+
None if self.is_tainted_by_errors() => Some(self.tcx.ty_error()),
588+
None => None,
589+
}
590+
}
591+
584592
/// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
585593
pub fn register_wf_obligation(
586594
&self,

compiler/rustc_typeck/src/check/writeback.rs

+9
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,15 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
331331
let ty = self.resolve(ty, &hir_ty.span);
332332
self.write_ty_to_typeck_results(hir_ty.hir_id, ty);
333333
}
334+
335+
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
336+
intravisit::walk_inf(self, inf);
337+
// Ignore cases where the inference is a const.
338+
if let Some(ty) = self.fcx.node_ty_opt(inf.hir_id) {
339+
let ty = self.resolve(ty, &inf.span);
340+
self.write_ty_to_typeck_results(inf.hir_id, ty);
341+
}
342+
}
334343
}
335344

336345
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {

compiler/rustc_typeck/src/collect.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
133133
match generic_arg {
134134
hir::GenericArg::Infer(inf) => {
135135
self.0.push(inf.span);
136+
intravisit::walk_inf(self, inf);
136137
}
137138
hir::GenericArg::Type(t) => self.visit_ty(t),
138139
_ => {}

src/test/ui/privacy/associated-item-privacy-trait.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,17 @@ LL | priv_parent_substs::mac!();
273273
|
274274
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
275275

276+
error: type `priv_parent_substs::Priv` is private
277+
--> $DIR/associated-item-privacy-trait.rs:117:30
278+
|
279+
LL | let _: <Pub as PubTr<_>>::AssocTy;
280+
| ^ private type
281+
...
282+
LL | priv_parent_substs::mac!();
283+
| --------------------------- in this macro invocation
284+
|
285+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
286+
276287
error: type `priv_parent_substs::Priv` is private
277288
--> $DIR/associated-item-privacy-trait.rs:119:17
278289
|
@@ -317,5 +328,5 @@ LL | priv_parent_substs::mac!();
317328
|
318329
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
319330

320-
error: aborting due to 29 previous errors
331+
error: aborting due to 30 previous errors
321332

src/tools/clippy/clippy_lints/src/implicit_hasher.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::collections::BTreeMap;
55

66
use rustc_errors::DiagnosticBuilder;
77
use rustc_hir as hir;
8-
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, NestedVisitorMap, Visitor};
8+
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, walk_inf, NestedVisitorMap, Visitor};
99
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
1010
use rustc_lint::{LateContext, LateLintPass, LintContext};
1111
use rustc_middle::hir::map::Map;
@@ -295,6 +295,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> {
295295
walk_ty(self, t);
296296
}
297297

298+
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
299+
if let Some(target) = ImplicitHasherType::new(self.cx, &inf.to_ty()) {
300+
self.found.push(target);
301+
}
302+
303+
walk_inf(self, inf);
304+
}
305+
298306
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
299307
NestedVisitorMap::None
300308
}

src/tools/clippy/clippy_lints/src/types/type_complexity.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint;
22
use rustc_hir as hir;
3-
use rustc_hir::intravisit::{walk_ty, NestedVisitorMap, Visitor};
3+
use rustc_hir::intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor};
44
use rustc_hir::{GenericParamKind, TyKind};
55
use rustc_lint::LateContext;
66
use rustc_middle::hir::map::Map;
@@ -39,6 +39,11 @@ struct TypeComplexityVisitor {
3939
impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
4040
type Map = Map<'tcx>;
4141

42+
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
43+
self.score += 1;
44+
walk_inf(self, inf);
45+
}
46+
4247
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) {
4348
let (add_score, sub_nest) = match ty.kind {
4449
// _, &x and *x have only small overhead; don't mess with nesting level

src/tools/clippy/clippy_lints/src/use_self.rs

+54-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use rustc_hir::{
88
self as hir,
99
def::{CtorOf, DefKind, Res},
1010
def_id::LocalDefId,
11-
intravisit::{walk_ty, NestedVisitorMap, Visitor},
12-
Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind,
11+
intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor},
12+
Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Node, Path, PathSegment,
13+
QPath, TyKind,
1314
};
1415
use rustc_lint::{LateContext, LateLintPass, LintContext};
1516
use rustc_middle::hir::map::Map;
@@ -263,6 +264,11 @@ struct SkipTyCollector {
263264
impl<'tcx> Visitor<'tcx> for SkipTyCollector {
264265
type Map = Map<'tcx>;
265266

267+
fn visit_infer(&mut self, inf: &hir::InferArg) {
268+
self.types_to_skip.push(inf.hir_id);
269+
270+
walk_inf(self, inf)
271+
}
266272
fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) {
267273
self.types_to_skip.push(hir_ty.hir_id);
268274

@@ -274,6 +280,52 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
274280
}
275281
}
276282

283+
<<<<<<< HEAD
284+
=======
285+
struct LintTyCollector<'a, 'tcx> {
286+
cx: &'a LateContext<'tcx>,
287+
self_ty: Ty<'tcx>,
288+
types_to_lint: Vec<HirId>,
289+
types_to_skip: Vec<HirId>,
290+
}
291+
292+
impl<'a, 'tcx> Visitor<'tcx> for LintTyCollector<'a, 'tcx> {
293+
type Map = Map<'tcx>;
294+
295+
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'_>) {
296+
if_chain! {
297+
if let Some(ty) = self.cx.typeck_results().node_type_opt(hir_ty.hir_id);
298+
if should_lint_ty(hir_ty, ty, self.self_ty);
299+
then {
300+
self.types_to_lint.push(hir_ty.hir_id);
301+
} else {
302+
self.types_to_skip.push(hir_ty.hir_id);
303+
}
304+
}
305+
306+
walk_ty(self, hir_ty);
307+
}
308+
309+
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
310+
if_chain! {
311+
if let Some(ty) = self.cx.typeck_results().node_type_opt(inf.hir_id);
312+
if should_lint_ty(&inf.to_ty(), ty, self.self_ty);
313+
then {
314+
self.types_to_lint.push(inf.hir_id);
315+
} else {
316+
self.types_to_skip.push(inf.hir_id);
317+
}
318+
}
319+
320+
walk_inf(self, inf)
321+
}
322+
323+
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
324+
NestedVisitorMap::None
325+
}
326+
}
327+
328+
>>>>>>> Add inferred args to typeck
277329
fn span_lint(cx: &LateContext<'_>, span: Span) {
278330
span_lint_and_sugg(
279331
cx,

src/tools/clippy/clippy_utils/src/hir_utils.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ impl HirEqInterExpr<'_, '_, '_> {
288288
(GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body),
289289
(GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt),
290290
(GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty),
291+
(GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) =>
292+
self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()),
291293
_ => false,
292294
}
293295
}
@@ -888,10 +890,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
888890
self.hash_tykind(&ty.kind);
889891
}
890892

891-
pub fn hash_infer(&mut self) {
892-
"_".hash(&mut self.s);
893-
}
894-
895893
pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
896894
match ty {
897895
TyKind::Slice(ty) => {
@@ -957,7 +955,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
957955
GenericArg::Lifetime(l) => self.hash_lifetime(l),
958956
GenericArg::Type(ref ty) => self.hash_ty(ty),
959957
GenericArg::Const(ref ca) => self.hash_body(ca.value.body),
960-
GenericArg::Infer(ref _inf) => self.hash_infer(),
958+
GenericArg::Infer(ref inf) => self.hash_ty(&inf.to_ty()),
961959
}
962960
}
963961
}

src/tools/clippy/clippy_utils/src/ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
180180
}
181181

182182
// FIXME: Per https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.normalize
183-
// this function can be removed once the `normalizie` method does not panic when normalization does
183+
// this function can be removed once the `normalize` method does not panic when normalization does
184184
// not succeed
185185
/// Checks if `Ty` is normalizable. This function is useful
186186
/// to avoid crashes on `layout_of`.

src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&issue
4646
--> $DIR/transmute_ptr_to_ref.rs:32:32
4747
|
4848
LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<_>)`
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<u8>)`
5050

5151
error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<&u8>`)
5252
--> $DIR/transmute_ptr_to_ref.rs:34:33
5353
|
5454
LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<&_>)`
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<&u8>)`
5656

5757
error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)
5858
--> $DIR/transmute_ptr_to_ref.rs:38:14

0 commit comments

Comments
 (0)