mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Resolve const parameters with modern hygiene
Declarations were already modernized, resulting in cases where a macro couldn't resolve it's own identifier.
This commit is contained in:
parent
3dca17e62d
commit
8876b3b9b0
@ -872,8 +872,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||
debug!("(resolving function) entering function");
|
||||
let rib_kind = match function_kind {
|
||||
FnKind::ItemFn(..) => FnItemRibKind,
|
||||
FnKind::Method(..) => AssocItemRibKind,
|
||||
FnKind::Closure(_) => NormalRibKind,
|
||||
FnKind::Method(..) | FnKind::Closure(_) => NormalRibKind,
|
||||
};
|
||||
|
||||
// Create a value rib for the function.
|
||||
@ -2310,21 +2309,32 @@ impl<'a> Resolver<'a> {
|
||||
if ident.name == kw::Invalid {
|
||||
return Some(LexicalScopeBinding::Res(Res::Err));
|
||||
}
|
||||
ident.span = if ident.name == kw::SelfUpper {
|
||||
let (general_span, modern_span) = if ident.name == kw::SelfUpper {
|
||||
// FIXME(jseyfried) improve `Self` hygiene
|
||||
ident.span.with_ctxt(SyntaxContext::empty())
|
||||
let empty_span = ident.span.with_ctxt(SyntaxContext::empty());
|
||||
(empty_span, empty_span)
|
||||
} else if ns == TypeNS {
|
||||
ident.span.modern()
|
||||
let modern_span = ident.span.modern();
|
||||
(modern_span, modern_span)
|
||||
} else {
|
||||
ident.span.modern_and_legacy()
|
||||
(ident.span.modern_and_legacy(), ident.span.modern())
|
||||
};
|
||||
ident.span = general_span;
|
||||
let modern_ident = Ident { span: modern_span, ..ident };
|
||||
|
||||
// Walk backwards up the ribs in scope.
|
||||
let record_used = record_used_id.is_some();
|
||||
let mut module = self.graph_root;
|
||||
for i in (0 .. self.ribs[ns].len()).rev() {
|
||||
debug!("walk rib\n{:?}", self.ribs[ns][i].bindings);
|
||||
if let Some(res) = self.ribs[ns][i].bindings.get(&ident).cloned() {
|
||||
// Use the rib kind to determine whether we are resolving parameters
|
||||
// (modern hygiene) or local variables (legacy hygiene).
|
||||
let rib_ident = if let AssocItemRibKind | ItemRibKind = self.ribs[ns][i].kind {
|
||||
modern_ident
|
||||
} else {
|
||||
ident
|
||||
};
|
||||
if let Some(res) = self.ribs[ns][i].bindings.get(&rib_ident).cloned() {
|
||||
// The ident resolves to a type parameter or local variable.
|
||||
return Some(LexicalScopeBinding::Res(
|
||||
self.validate_res_from_ribs(ns, i, res, record_used, path_span),
|
||||
@ -2360,7 +2370,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
ident.span = ident.span.modern();
|
||||
ident = modern_ident;
|
||||
let mut poisoned = None;
|
||||
loop {
|
||||
let opt_module = if let Some(node_id) = record_used_id {
|
||||
|
104
src/test/ui/hygiene/generic_params.rs
Normal file
104
src/test/ui/hygiene/generic_params.rs
Normal file
@ -0,0 +1,104 @@
|
||||
// Ensure that generic parameters always have modern hygiene.
|
||||
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro, rustc_attrs, const_generics)]
|
||||
|
||||
mod type_params {
|
||||
macro m($T:ident) {
|
||||
fn f<$T: Clone, T: PartialEq>(t1: $T, t2: T) -> ($T, bool) {
|
||||
(t1.clone(), t2 == t2)
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
macro n($T:ident) {
|
||||
fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) {
|
||||
(t1.clone(), t2.clone())
|
||||
}
|
||||
fn h<T: Clone>(t1: $T, t2: T) -> (T, $T) {
|
||||
(t1.clone(), t2.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro p($T:ident) {
|
||||
fn j<$T: Clone>(t1: $T, t2: T) -> (T, $T) {
|
||||
(t1.clone(), t2.clone())
|
||||
}
|
||||
fn k<T: Clone>(t1: $T, t2: T) -> (T, $T) {
|
||||
(t1.clone(), t2.clone())
|
||||
}
|
||||
}
|
||||
|
||||
m!(T);
|
||||
n!(T);
|
||||
p!(T);
|
||||
}
|
||||
|
||||
mod lifetime_params {
|
||||
macro m($a:lifetime) {
|
||||
fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) {
|
||||
(t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
macro n($a:lifetime) {
|
||||
fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
|
||||
(t1, t2)
|
||||
}
|
||||
fn h<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
|
||||
(t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro p($a:lifetime) {
|
||||
fn j<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
|
||||
(t1, t2)
|
||||
}
|
||||
fn k<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
|
||||
(t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
m!('a);
|
||||
n!('a);
|
||||
p!('a);
|
||||
}
|
||||
|
||||
mod const_params {
|
||||
macro m($C:ident) {
|
||||
fn f<const $C: usize, const C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); $C], [(); C]) {
|
||||
(t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
macro n($C:ident) {
|
||||
fn g<const $C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
|
||||
(t1, t2)
|
||||
}
|
||||
fn h<const C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
|
||||
(t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro p($C:ident) {
|
||||
fn j<const $C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
|
||||
(t1, t2)
|
||||
}
|
||||
fn k<const C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
|
||||
(t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
m!(C);
|
||||
n!(C);
|
||||
p!(C);
|
||||
}
|
||||
|
||||
fn main() {}
|
6
src/test/ui/hygiene/generic_params.stderr
Normal file
6
src/test/ui/hygiene/generic_params.stderr
Normal file
@ -0,0 +1,6 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/generic_params.rs:6:37
|
||||
|
|
||||
LL | #![feature(decl_macro, rustc_attrs, const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,14 +0,0 @@
|
||||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
macro m($T:ident) {
|
||||
fn f<T, $T>(t: T, t2: $T) -> (T, $T) {
|
||||
(t, t2)
|
||||
}
|
||||
}
|
||||
|
||||
m!(T);
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user