Skip to content

Commit 417b098

Browse files
committed
Add generic arg infer
1 parent 71a6c7c commit 417b098

File tree

28 files changed

+270
-94
lines changed

28 files changed

+270
-94
lines changed

compiler/rustc_ast/src/ast.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -336,14 +336,15 @@ pub enum ParamKindOrd {
336336
// is active. Specifically, if it's only `min_const_generics`, it will still require
337337
// ordering consts after types.
338338
Const { unordered: bool },
339+
Infer,
339340
}
340341

341342
impl Ord for ParamKindOrd {
342343
fn cmp(&self, other: &Self) -> Ordering {
343344
use ParamKindOrd::*;
344345
let to_int = |v| match v {
345346
Lifetime => 0,
346-
Type | Const { unordered: true } => 1,
347+
Infer | Type | Const { unordered: true } => 1,
347348
// technically both consts should be ordered equally,
348349
// but only one is ever encountered at a time, so this is
349350
// fine.
@@ -371,6 +372,7 @@ impl fmt::Display for ParamKindOrd {
371372
ParamKindOrd::Lifetime => "lifetime".fmt(f),
372373
ParamKindOrd::Type => "type".fmt(f),
373374
ParamKindOrd::Const { .. } => "const".fmt(f),
375+
ParamKindOrd::Infer => "infer".fmt(f),
374376
}
375377
}
376378
}

compiler/rustc_ast_lowering/src/lib.rs

+47-40
Original file line numberDiff line numberDiff line change
@@ -1218,48 +1218,55 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12181218
match arg {
12191219
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
12201220
ast::GenericArg::Type(ty) => {
1221-
// We parse const arguments as path types as we cannot distinguish them during
1222-
// parsing. We try to resolve that ambiguity by attempting resolution in both the
1223-
// type and value namespaces. If we resolved the path in the value namespace, we
1224-
// transform it into a generic const argument.
1225-
if let TyKind::Path(ref qself, ref path) = ty.kind {
1226-
if let Some(partial_res) = self.resolver.get_partial_res(ty.id) {
1227-
let res = partial_res.base_res();
1228-
if !res.matches_ns(Namespace::TypeNS) {
1229-
debug!(
1230-
"lower_generic_arg: Lowering type argument as const argument: {:?}",
1231-
ty,
1232-
);
1233-
1234-
// Construct a AnonConst where the expr is the "ty"'s path.
1235-
1236-
let parent_def_id = self.current_hir_id_owner.0;
1237-
let node_id = self.resolver.next_node_id();
1238-
1239-
// Add a definition for the in-band const def.
1240-
self.resolver.create_def(
1241-
parent_def_id,
1242-
node_id,
1243-
DefPathData::AnonConst,
1244-
ExpnId::root(),
1245-
ty.span,
1246-
);
1247-
1248-
let path_expr = Expr {
1249-
id: ty.id,
1250-
kind: ExprKind::Path(qself.clone(), path.clone()),
1251-
span: ty.span,
1252-
attrs: AttrVec::new(),
1253-
tokens: None,
1254-
};
1255-
1256-
let ct = self.with_new_scopes(|this| hir::AnonConst {
1257-
hir_id: this.lower_node_id(node_id),
1258-
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
1259-
});
1260-
return GenericArg::Const(ConstArg { value: ct, span: ty.span });
1221+
match ty.kind {
1222+
TyKind::Infer => {
1223+
let hir_id = self.lower_node_id(ty.id);
1224+
return GenericArg::Infer(hir::InferArg { hir_id, span: ty.span });
1225+
}
1226+
// We parse const arguments as path types as we cannot distinguish them during
1227+
// parsing. We try to resolve that ambiguity by attempting resolution in both the
1228+
// type and value namespaces. If we resolved the path in the value namespace, we
1229+
// transform it into a generic const argument.
1230+
TyKind::Path(ref qself, ref path) => {
1231+
if let Some(partial_res) = self.resolver.get_partial_res(ty.id) {
1232+
let res = partial_res.base_res();
1233+
if !res.matches_ns(Namespace::TypeNS) {
1234+
debug!(
1235+
"lower_generic_arg: Lowering type argument as const argument: {:?}",
1236+
ty,
1237+
);
1238+
1239+
// Construct a AnonConst where the expr is the "ty"'s path.
1240+
1241+
let parent_def_id = self.current_hir_id_owner.0;
1242+
let node_id = self.resolver.next_node_id();
1243+
1244+
// Add a definition for the in-band const def.
1245+
self.resolver.create_def(
1246+
parent_def_id,
1247+
node_id,
1248+
DefPathData::AnonConst,
1249+
ExpnId::root(),
1250+
ty.span,
1251+
);
1252+
1253+
let path_expr = Expr {
1254+
id: ty.id,
1255+
kind: ExprKind::Path(qself.clone(), path.clone()),
1256+
span: ty.span,
1257+
attrs: AttrVec::new(),
1258+
tokens: None,
1259+
};
1260+
1261+
let ct = self.with_new_scopes(|this| hir::AnonConst {
1262+
hir_id: this.lower_node_id(node_id),
1263+
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
1264+
});
1265+
return GenericArg::Const(ConstArg { value: ct, span: ty.span });
1266+
}
12611267
}
12621268
}
1269+
_ => {}
12631270
}
12641271
GenericArg::Type(self.lower_ty_direct(&ty, itctx))
12651272
}

compiler/rustc_hir/src/hir.rs

+23
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,24 @@ pub struct ConstArg {
253253
pub span: Span,
254254
}
255255

256+
#[derive(Encodable, Debug, HashStable_Generic)]
257+
pub struct InferArg {
258+
pub hir_id: HirId,
259+
pub span: Span,
260+
}
261+
262+
impl InferArg {
263+
pub fn to_ty(&self) -> Ty<'_> {
264+
Ty { kind: TyKind::Infer, span: self.span, hir_id: self.hir_id }
265+
}
266+
}
267+
256268
#[derive(Debug, HashStable_Generic)]
257269
pub enum GenericArg<'hir> {
258270
Lifetime(Lifetime),
259271
Type(Ty<'hir>),
260272
Const(ConstArg),
273+
Infer(InferArg),
261274
}
262275

263276
impl GenericArg<'_> {
@@ -266,6 +279,7 @@ impl GenericArg<'_> {
266279
GenericArg::Lifetime(l) => l.span,
267280
GenericArg::Type(t) => t.span,
268281
GenericArg::Const(c) => c.span,
282+
GenericArg::Infer(i) => i.span,
269283
}
270284
}
271285

@@ -274,6 +288,7 @@ impl GenericArg<'_> {
274288
GenericArg::Lifetime(l) => l.hir_id,
275289
GenericArg::Type(t) => t.hir_id,
276290
GenericArg::Const(c) => c.value.hir_id,
291+
GenericArg::Infer(i) => i.hir_id,
277292
}
278293
}
279294

@@ -290,6 +305,7 @@ impl GenericArg<'_> {
290305
GenericArg::Lifetime(_) => "lifetime",
291306
GenericArg::Type(_) => "type",
292307
GenericArg::Const(_) => "constant",
308+
GenericArg::Infer(_) => "inferred",
293309
}
294310
}
295311

@@ -300,6 +316,7 @@ impl GenericArg<'_> {
300316
GenericArg::Const(_) => {
301317
ast::ParamKindOrd::Const { unordered: feats.unordered_const_ty_params() }
302318
}
319+
GenericArg::Infer(_) => ast::ParamKindOrd::Infer,
303320
}
304321
}
305322
}
@@ -341,6 +358,7 @@ impl GenericArgs<'_> {
341358
break;
342359
}
343360
GenericArg::Const(_) => {}
361+
GenericArg::Infer(_) => {}
344362
}
345363
}
346364
}
@@ -358,6 +376,7 @@ impl GenericArgs<'_> {
358376
GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
359377
GenericArg::Type(_) => own_counts.types += 1,
360378
GenericArg::Const(_) => own_counts.consts += 1,
379+
GenericArg::Infer(_) => own_counts.infer += 1,
361380
};
362381
}
363382

@@ -484,6 +503,7 @@ pub struct GenericParamCount {
484503
pub lifetimes: usize,
485504
pub types: usize,
486505
pub consts: usize,
506+
pub infer: usize,
487507
}
488508

489509
/// Represents lifetimes and type parameters attached to a declaration
@@ -2987,6 +3007,8 @@ pub enum Node<'hir> {
29873007
Visibility(&'hir Visibility<'hir>),
29883008

29893009
Crate(&'hir Mod<'hir>),
3010+
3011+
Infer(&'hir InferArg),
29903012
}
29913013

29923014
impl<'hir> Node<'hir> {
@@ -3055,6 +3077,7 @@ impl<'hir> Node<'hir> {
30553077
| Node::Local(Local { hir_id, .. })
30563078
| Node::Lifetime(Lifetime { hir_id, .. })
30573079
| Node::Param(Param { hir_id, .. })
3080+
| Node::Infer(InferArg { hir_id, .. })
30583081
| Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
30593082
Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
30603083
Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,

compiler/rustc_hir/src/intravisit.rs

+13
Original file line numberDiff line numberDiff line change
@@ -436,13 +436,22 @@ pub trait Visitor<'v>: Sized {
436436
fn visit_label(&mut self, label: &'v Label) {
437437
walk_label(self, label)
438438
}
439+
fn visit_infer(&mut self, inf: &'v InferArg) {
440+
self.visit_id(inf.hir_id);
441+
}
439442
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
440443
match generic_arg {
441444
GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
442445
GenericArg::Type(ty) => self.visit_ty(ty),
443446
GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
447+
GenericArg::Infer(inf) => self.visit_infer(inf),
444448
}
445449
}
450+
/*
451+
fn tcx(&self) -> Option<&TyCtxt<'tcx>> {
452+
None
453+
}
454+
*/
446455
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
447456
walk_lifetime(self, lifetime)
448457
}
@@ -746,6 +755,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
746755
}
747756
}
748757

758+
pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) {
759+
visitor.visit_id(inf.hir_id);
760+
}
761+
749762
pub fn walk_qpath<'v, V: Visitor<'v>>(
750763
visitor: &mut V,
751764
qpath: &'v QPath<'v>,

compiler/rustc_hir_pretty/src/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ impl<'a> State<'a> {
103103
Node::TraitRef(a) => self.print_trait_ref(&a),
104104
Node::Binding(a) | Node::Pat(a) => self.print_pat(&a),
105105
Node::Arm(a) => self.print_arm(&a),
106+
Node::Infer(_) => self.print_string("_", ast::StrStyle::Cooked),
106107
Node::Block(a) => {
107108
// Containing cbox, will be closed by print-block at `}`.
108109
self.cbox(INDENT_UNIT);
@@ -437,14 +438,14 @@ impl<'a> State<'a> {
437438
self.print_anon_const(e);
438439
self.s.word(")");
439440
}
440-
hir::TyKind::Infer => {
441-
self.s.word("_");
442-
}
443441
hir::TyKind::Err => {
444442
self.popen();
445443
self.s.word("/*ERROR*/");
446444
self.pclose();
447445
}
446+
hir::TyKind::Infer => {
447+
self.s.word("_");
448+
}
448449
}
449450
self.end()
450451
}
@@ -1851,6 +1852,7 @@ impl<'a> State<'a> {
18511852
GenericArg::Lifetime(_) => {}
18521853
GenericArg::Type(ty) => s.print_type(ty),
18531854
GenericArg::Const(ct) => s.print_anon_const(&ct.value),
1855+
GenericArg::Infer(_inf) => s.word("_"),
18541856
},
18551857
);
18561858
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
404404
});
405405
}
406406

407+
fn visit_infer(&mut self, inf: &'hir InferArg) {
408+
self.insert(inf.span, inf.hir_id, Node::Infer(inf));
409+
410+
self.with_parent(inf.hir_id, |this| {
411+
intravisit::walk_inf(this, inf);
412+
});
413+
}
414+
407415
fn visit_trait_ref(&mut self, tr: &'hir TraitRef<'hir>) {
408416
self.insert(tr.path.span, tr.hir_ref_id, Node::TraitRef(tr));
409417

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

+3
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ impl<'hir> Map<'hir> {
272272
GenericParamKind::Type { .. } => DefKind::TyParam,
273273
GenericParamKind::Const { .. } => DefKind::ConstParam,
274274
},
275+
Node::Infer(_) => todo!(),
275276
Node::Crate(_) => DefKind::Mod,
276277
Node::Stmt(_)
277278
| Node::PathSegment(_)
@@ -882,6 +883,7 @@ impl<'hir> Map<'hir> {
882883
node: VisibilityKind::Restricted { ref path, .. },
883884
..
884885
}) => path.span,
886+
Node::Infer(i) => i.span,
885887
Node::Visibility(v) => bug!("unexpected Visibility {:?}", v),
886888
Node::Local(local) => local.span,
887889
Node::MacroDef(macro_def) => macro_def.span,
@@ -1129,6 +1131,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {
11291131
Some(Node::Param(_)) => node_str("param"),
11301132
Some(Node::Arm(_)) => node_str("arm"),
11311133
Some(Node::Block(_)) => node_str("block"),
1134+
Some(Node::Infer(_)) => node_str("infer"),
11321135
Some(Node::Local(_)) => node_str("local"),
11331136
Some(Node::Ctor(..)) => format!("ctor {}{}", path_str(), id_str),
11341137
Some(Node::Lifetime(_)) => node_str("lifetime"),

compiler/rustc_middle/src/query/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ 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+
136141
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
137142
/// predicates (where-clauses) that must be proven true in order
138143
/// to reference it. This is almost always the "predicates query"

compiler/rustc_privacy/src/lib.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,23 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
11881188
self.maybe_typeck_results = old_maybe_typeck_results;
11891189
}
11901190

1191+
fn visit_generic_arg(&mut self, generic_arg: &'tcx hir::GenericArg<'tcx>) {
1192+
match generic_arg {
1193+
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+
}
1204+
hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
1205+
}
1206+
}
1207+
11911208
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {
11921209
self.span = hir_ty.span;
11931210
if let Some(typeck_results) = self.maybe_typeck_results {
@@ -1443,6 +1460,14 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a
14431460
NestedVisitorMap::None
14441461
}
14451462

1463+
fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) {
1464+
match generic_arg {
1465+
hir::GenericArg::Type(t) => self.visit_ty(t),
1466+
hir::GenericArg::Infer(inf) => self.visit_ty(&inf.to_ty()),
1467+
hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
1468+
}
1469+
}
1470+
14461471
fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
14471472
if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = ty.kind {
14481473
if self.inner.path_is_private_type(path) {

compiler/rustc_resolve/src/late/lifetimes.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2557,6 +2557,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
25572557
GenericArg::Const(ct) => {
25582558
self.visit_anon_const(&ct.value);
25592559
}
2560+
GenericArg::Infer(inf) => {
2561+
self.visit_id(inf.hir_id);
2562+
i += 1;
2563+
}
25602564
}
25612565
}
25622566

0 commit comments

Comments
 (0)