Skip to content

Commit 34d1352

Browse files
committed
rustc: encode the optionality of type parameters in HIR paths.
1 parent 9ca50bd commit 34d1352

File tree

6 files changed

+112
-106
lines changed

6 files changed

+112
-106
lines changed

src/librustc/hir/lowering.rs

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ pub fn lower_crate(sess: &Session,
101101
}.lower_crate(krate)
102102
}
103103

104+
#[derive(Copy, Clone, PartialEq, Eq)]
105+
enum ParamMode {
106+
/// Any path in a type context.
107+
Explicit,
108+
/// The `module::Type` in `module::Type::method` in an expression.
109+
Optional
110+
}
111+
104112
impl<'a> LoweringContext<'a> {
105113
fn lower_crate(&mut self, c: &Crate) -> hir::Crate {
106114
struct ItemLowerer<'lcx, 'interner: 'lcx> {
@@ -179,13 +187,14 @@ impl<'a> LoweringContext<'a> {
179187
P(Spanned {
180188
node: match view_path.node {
181189
ViewPathSimple(ident, ref path) => {
182-
hir::ViewPathSimple(ident.name, self.lower_path(path))
190+
hir::ViewPathSimple(ident.name,
191+
self.lower_path(path, None, ParamMode::Explicit))
183192
}
184193
ViewPathGlob(ref path) => {
185-
hir::ViewPathGlob(self.lower_path(path))
194+
hir::ViewPathGlob(self.lower_path(path, None, ParamMode::Explicit))
186195
}
187196
ViewPathList(ref path, ref path_list_idents) => {
188-
hir::ViewPathList(self.lower_path(path),
197+
hir::ViewPathList(self.lower_path(path, None, ParamMode::Explicit),
189198
path_list_idents.iter()
190199
.map(|item| self.lower_path_list_item(item))
191200
.collect())
@@ -256,7 +265,8 @@ impl<'a> LoweringContext<'a> {
256265
position: position,
257266
}
258267
});
259-
hir::TyPath(qself, self.lower_path(path))
268+
let path = self.lower_path(path, qself.as_ref(), ParamMode::Explicit);
269+
hir::TyPath(qself, path)
260270
}
261271
TyKind::ObjectSum(ref ty, ref bounds) => {
262272
hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
@@ -298,38 +308,56 @@ impl<'a> LoweringContext<'a> {
298308
}
299309
}
300310

301-
fn lower_path(&mut self, p: &Path) -> hir::Path {
311+
fn lower_path(&mut self,
312+
p: &Path,
313+
qself: Option<&hir::QSelf>,
314+
param_mode: ParamMode)
315+
-> hir::Path {
302316
hir::Path {
303317
global: p.global,
304-
segments: p.segments
305-
.iter()
306-
.map(|&PathSegment { identifier, ref parameters }| {
307-
hir::PathSegment {
308-
name: identifier.name,
309-
parameters: self.lower_path_parameters(parameters),
310-
}
311-
})
312-
.collect(),
318+
segments: p.segments.iter().enumerate().map(|(i, segment)| {
319+
let PathSegment { identifier, ref parameters } = *segment;
320+
let param_mode = match (qself, param_mode) {
321+
(Some(qself), ParamMode::Optional) if i < qself.position => {
322+
// This segment is part of the trait path in a
323+
// qualified path - one of `a`, `b` or `Trait`
324+
// in `<X as a::b::Trait>::T::U::method`.
325+
ParamMode::Explicit
326+
}
327+
_ => param_mode
328+
};
329+
hir::PathSegment {
330+
name: identifier.name,
331+
parameters: self.lower_path_parameters(parameters, param_mode),
332+
}
333+
}).collect(),
313334
span: p.span,
314335
}
315336
}
316337

317-
fn lower_path_parameters(&mut self, path_parameters: &PathParameters) -> hir::PathParameters {
338+
fn lower_path_parameters(&mut self,
339+
path_parameters: &PathParameters,
340+
param_mode: ParamMode)
341+
-> hir::PathParameters {
318342
match *path_parameters {
319-
PathParameters::AngleBracketed(ref data) =>
320-
hir::AngleBracketedParameters(self.lower_angle_bracketed_parameter_data(data)),
343+
PathParameters::AngleBracketed(ref data) => {
344+
let data = self.lower_angle_bracketed_parameter_data(data, param_mode);
345+
hir::AngleBracketedParameters(data)
346+
}
321347
PathParameters::Parenthesized(ref data) =>
322348
hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)),
323349
}
324350
}
325351

326352
fn lower_angle_bracketed_parameter_data(&mut self,
327-
data: &AngleBracketedParameterData)
353+
data: &AngleBracketedParameterData,
354+
param_mode: ParamMode)
328355
-> hir::AngleBracketedParameterData {
329356
let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
330357
hir::AngleBracketedParameterData {
331358
lifetimes: self.lower_lifetimes(lifetimes),
332359
types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
360+
infer_types: types.is_empty() && param_mode == ParamMode::Optional,
333361
bindings: bindings.iter().map(|b| self.lower_ty_binding(b)).collect(),
334362
}
335363
}
@@ -493,7 +521,7 @@ impl<'a> LoweringContext<'a> {
493521
span}) => {
494522
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
495523
id: id,
496-
path: self.lower_path(path),
524+
path: self.lower_path(path, None, ParamMode::Explicit),
497525
ty: self.lower_ty(ty),
498526
span: span,
499527
})
@@ -523,7 +551,7 @@ impl<'a> LoweringContext<'a> {
523551

524552
fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
525553
hir::TraitRef {
526-
path: self.lower_path(&p.path),
554+
path: self.lower_path(&p.path, None, ParamMode::Explicit),
527555
ref_id: p.ref_id,
528556
}
529557
}
@@ -887,17 +915,19 @@ impl<'a> LoweringContext<'a> {
887915
}
888916
PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
889917
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
890-
hir::PatKind::TupleStruct(self.lower_path(path),
891-
pats.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
918+
hir::PatKind::TupleStruct(self.lower_path(path, None, ParamMode::Optional),
919+
pats.iter().map(|x| self.lower_pat(x)).collect(),
920+
ddpos)
892921
}
893-
PatKind::Path(ref opt_qself, ref path) => {
894-
let opt_qself = opt_qself.as_ref().map(|qself| {
922+
PatKind::Path(ref qself, ref path) => {
923+
let qself = qself.as_ref().map(|qself| {
895924
hir::QSelf { ty: self.lower_ty(&qself.ty), position: qself.position }
896925
});
897-
hir::PatKind::Path(opt_qself, self.lower_path(path))
926+
let path = self.lower_path(path, qself.as_ref(), ParamMode::Optional);
927+
hir::PatKind::Path(qself, path)
898928
}
899929
PatKind::Struct(ref pth, ref fields, etc) => {
900-
let pth = self.lower_path(pth);
930+
let pth = self.lower_path(pth, None, ParamMode::Optional);
901931
let fs = fields.iter()
902932
.map(|f| {
903933
Spanned {
@@ -1236,13 +1266,14 @@ impl<'a> LoweringContext<'a> {
12361266
};
12371267
}
12381268
ExprKind::Path(ref qself, ref path) => {
1239-
let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
1269+
let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
12401270
hir::QSelf {
12411271
ty: self.lower_ty(ty),
12421272
position: position,
12431273
}
12441274
});
1245-
hir::ExprPath(hir_qself, self.lower_path(path))
1275+
let path = self.lower_path(path, qself.as_ref(), ParamMode::Optional);
1276+
hir::ExprPath(qself, path)
12461277
}
12471278
ExprKind::Break(opt_ident, ref opt_expr) => {
12481279
hir::ExprBreak(self.lower_opt_sp_ident(opt_ident),
@@ -1275,7 +1306,7 @@ impl<'a> LoweringContext<'a> {
12751306
hir::ExprInlineAsm(P(hir_asm), outputs, inputs)
12761307
}
12771308
ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
1278-
hir::ExprStruct(P(self.lower_path(path)),
1309+
hir::ExprStruct(P(self.lower_path(path, None, ParamMode::Optional)),
12791310
fields.iter().map(|x| self.lower_field(x)).collect(),
12801311
maybe_expr.as_ref().map(|x| P(self.lower_expr(x))))
12811312
}
@@ -1655,8 +1686,12 @@ impl<'a> LoweringContext<'a> {
16551686
match *v {
16561687
Visibility::Public => hir::Public,
16571688
Visibility::Crate(_) => hir::Visibility::Crate,
1658-
Visibility::Restricted { ref path, id } =>
1659-
hir::Visibility::Restricted { path: P(self.lower_path(path)), id: id },
1689+
Visibility::Restricted { ref path, id } => {
1690+
hir::Visibility::Restricted {
1691+
path: P(self.lower_path(path, None, ParamMode::Explicit)),
1692+
id: id
1693+
}
1694+
}
16601695
Visibility::Inherited => hir::Inherited,
16611696
}
16621697
}
@@ -1949,6 +1984,7 @@ impl<'a> LoweringContext<'a> {
19491984
parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
19501985
lifetimes: lifetimes,
19511986
types: types,
1987+
infer_types: true,
19521988
bindings: bindings,
19531989
}),
19541990
});

src/librustc/hir/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ impl PathParameters {
167167
AngleBracketedParameters(AngleBracketedParameterData {
168168
lifetimes: HirVec::new(),
169169
types: HirVec::new(),
170+
infer_types: true,
170171
bindings: HirVec::new(),
171172
})
172173
}
@@ -241,6 +242,11 @@ pub struct AngleBracketedParameterData {
241242
pub lifetimes: HirVec<Lifetime>,
242243
/// The type parameters for this path segment, if present.
243244
pub types: HirVec<P<Ty>>,
245+
/// Whether to infer remaining type parameters, if any.
246+
/// This only applies to expression and pattern paths, and
247+
/// out of those only the segments with no type parameters
248+
/// to begin with, e.g. `Vec::new` is `<Vec<..>>::new::<..>`.
249+
pub infer_types: bool,
244250
/// Bindings (equality constraints) on associated types, if present.
245251
/// E.g., `Foo<A=Bar>`.
246252
pub bindings: HirVec<TypeBinding>,

src/librustc/hir/print.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,16 @@ impl<'a> State<'a> {
16961696
comma = true;
16971697
}
16981698

1699+
// FIXME(eddyb) This would leak into error messages, e.g.:
1700+
// "non-exhaustive patterns: `Some::<..>(_)` not covered".
1701+
if data.infer_types && false {
1702+
if comma {
1703+
self.word_space(",")?
1704+
}
1705+
word(&mut self.s, "..")?;
1706+
comma = true;
1707+
}
1708+
16991709
for binding in data.bindings.iter() {
17001710
if comma {
17011711
self.word_space(",")?

src/librustc/infer/error_reporting.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
16091609
hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
16101610
lifetimes: new_lts.into(),
16111611
types: new_types,
1612+
infer_types: data.infer_types,
16121613
bindings: new_bindings,
16131614
})
16141615
}

0 commit comments

Comments
 (0)