Skip to content

Commit 7b4642f

Browse files
author
Gabriel Smith
committed
resolve: late: Check if type arg is really a const arg
A path type argument could be a generic const argument due to limitations as to what we can determine at parsing. We double check just to be sure by trying to resolve in the type namespace first, and if that fails we try again in the value namespace. If resolution in the value namespace succeeds, we have a generic const argument on our hands.
1 parent 128ca74 commit 7b4642f

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

src/librustc_resolve/late.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,52 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
546546
self.visit_where_predicate(p);
547547
}
548548
}
549+
550+
fn visit_generic_arg(&mut self, arg: &'tcx GenericArg) {
551+
debug!("visit_generic_arg({:?})", arg);
552+
match arg {
553+
GenericArg::Type(ref ty) => {
554+
// We parse const arguments as path types as we cannot distiguish them durring
555+
// parsing. We try to resolve that ambiguity by attempting resolution the type
556+
// namespace first, and if that fails we try again in the value namespace. If
557+
// resolution in the value namespace succeeds, we have an generic const argument on
558+
// our hands.
559+
if let TyKind::Path(ref qself, ref path) = ty.kind {
560+
// We cannot disambiguate multi-segment paths right now as that requires type
561+
// checking.
562+
if path.segments.len() == 1 && path.segments[0].args.is_none() {
563+
let mut check_ns = |ns| self.resolve_ident_in_lexical_scope(
564+
path.segments[0].ident, ns, None, path.span
565+
).is_some();
566+
567+
if !check_ns(TypeNS) && check_ns(ValueNS) {
568+
// This must be equivalent to `visit_anon_const`, but we cannot call it
569+
// directly due to visitor lifetimes so we have to copy-paste some code.
570+
self.with_constant_rib(|this| {
571+
this.smart_resolve_path(
572+
ty.id,
573+
qself.as_ref(),
574+
path,
575+
PathSource::Expr(None)
576+
);
577+
578+
if let Some(ref qself) = *qself {
579+
this.visit_ty(&qself.ty);
580+
}
581+
this.visit_path(path, ty.id);
582+
});
583+
584+
return;
585+
}
586+
}
587+
}
588+
589+
self.visit_ty(ty);
590+
}
591+
GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
592+
GenericArg::Const(ct) => self.visit_anon_const(ct),
593+
}
594+
}
549595
}
550596

551597
impl<'a, 'b> LateResolutionVisitor<'a, '_> {

0 commit comments

Comments
 (0)