PatternError::AssocConstInPattern(span) => {
self.span_e0158(span, "associated consts cannot be referenced in patterns")
}
+ PatternError::ConstParamInPattern(span) => {
+ self.span_e0158(span, "const parameters cannot be referenced in patterns")
+ }
PatternError::FloatBug => {
// FIXME(#31407) this is only necessary because float parsing is buggy
::rustc::mir::interpret::struct_error(
#[derive(Clone, Debug)]
crate enum PatternError {
AssocConstInPattern(Span),
+ ConstParamInPattern(Span),
StaticInPattern(Span),
FloatBug,
NonConstPath(Span),
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
_ => {
- self.errors.push(PatternError::NonConstPath(span));
+ let pattern_error = match res {
+ Res::Def(DefKind::ConstParam, _) => PatternError::ConstParamInPattern(span),
+ _ => PatternError::NonConstPath(span),
+ };
+ self.errors.push(pattern_error);
PatKind::Wild
}
};
ident: Ident,
has_sub: bool,
) -> Option<Res> {
- let binding =
- self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?.item()?;
- let res = binding.res();
+ let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?;
+ let (res, binding) = match ls_binding {
+ LexicalScopeBinding::Item(binding) if binding.is_ambiguity() => {
+ // For ambiguous bindings we don't know all their definitions and cannot check
+ // whether they can be shadowed by fresh bindings or not, so force an error.
+ self.r.record_use(ident, ValueNS, binding, false);
+ return None;
+ }
+ LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)),
+ LexicalScopeBinding::Res(res) => (res, None),
+ };
// An immutable (no `mut`) by-value (no `ref`) binding pattern without
// a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
match res {
- Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::Def(DefKind::Const, _)
+ Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
+ | Res::Def(DefKind::Const, _)
+ | Res::Def(DefKind::ConstParam, _)
if is_syntactic_ambiguity =>
{
// Disambiguate in favor of a unit struct/variant or constant pattern.
- self.r.record_use(ident, ValueNS, binding, false);
+ if let Some(binding) = binding {
+ self.r.record_use(ident, ValueNS, binding, false);
+ }
Some(res)
}
Res::Def(DefKind::Ctor(..), _)
ResolutionError::BindingShadowsSomethingUnacceptable(
pat_src.descr(),
ident.name,
- binding,
+ binding.expect("no binding for a ctor or static"),
),
);
None
}
- Res::Def(DefKind::Fn, _) | Res::Err => {
+ Res::Def(DefKind::Fn, _) | Res::Local(..) | Res::Err => {
// These entities are explicitly allowed to be shadowed by fresh bindings.
None
}
- res => {
- span_bug!(
- ident.span,
- "unexpected resolution for an \
- identifier in pattern: {:?}",
- res
- );
- }
+ _ => span_bug!(
+ ident.span,
+ "unexpected resolution for an identifier in pattern: {:?}",
+ res
+ ),
}
}
}
impl<'a> LexicalScopeBinding<'a> {
- fn item(self) -> Option<&'a NameBinding<'a>> {
- match self {
- LexicalScopeBinding::Item(binding) => Some(binding),
- _ => None,
- }
- }
-
fn res(self) -> Res {
match self {
LexicalScopeBinding::Item(binding) => binding.res(),
Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
| Res::SelfCtor(..)
| Res::Def(DefKind::Const, _)
- | Res::Def(DefKind::AssocConst, _) => {} // OK
+ | Res::Def(DefKind::AssocConst, _)
+ | Res::Def(DefKind::ConstParam, _) => {} // OK
_ => bug!("unexpected pattern resolution: {:?}", res),
}
--- /dev/null
+// Identifier pattern referring to an ambiguity item is an error (issue #46079).
+
+mod m {
+ pub fn f() {}
+}
+use m::*;
+
+mod n {
+ pub fn f() {}
+}
+use n::*; // OK, no conflict with `use m::*;`
+
+fn main() {
+ let v = f; //~ ERROR `f` is ambiguous
+ match v {
+ f => {} //~ ERROR `f` is ambiguous
+ }
+}
--- /dev/null
+error[E0659]: `f` is ambiguous (glob import vs glob import in the same module)
+ --> $DIR/ambiguity-item.rs:14:13
+ |
+LL | let v = f;
+ | ^ ambiguous name
+ |
+note: `f` could refer to the function imported here
+ --> $DIR/ambiguity-item.rs:6:5
+ |
+LL | use m::*;
+ | ^^^^
+ = help: consider adding an explicit import of `f` to disambiguate
+note: `f` could also refer to the function imported here
+ --> $DIR/ambiguity-item.rs:11:5
+ |
+LL | use n::*; // OK, no conflict with `use m::*;`
+ | ^^^^
+ = help: consider adding an explicit import of `f` to disambiguate
+
+error[E0659]: `f` is ambiguous (glob import vs glob import in the same module)
+ --> $DIR/ambiguity-item.rs:16:9
+ |
+LL | f => {}
+ | ^ ambiguous name
+ |
+note: `f` could refer to the function imported here
+ --> $DIR/ambiguity-item.rs:6:5
+ |
+LL | use m::*;
+ | ^^^^
+ = help: consider adding an explicit import of `f` to disambiguate
+note: `f` could also refer to the function imported here
+ --> $DIR/ambiguity-item.rs:11:5
+ |
+LL | use n::*; // OK, no conflict with `use m::*;`
+ | ^^^^
+ = help: consider adding an explicit import of `f` to disambiguate
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0659`.
--- /dev/null
+// Identifier pattern referring to a const generic parameter is an error (issue #68853).
+
+#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
+
+fn check<const N: usize>() {
+ match 1 {
+ N => {} //~ ERROR const parameters cannot be referenced in patterns
+ _ => {}
+ }
+}
+
+fn main() {}
--- /dev/null
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/const-param.rs:3:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0158]: const parameters cannot be referenced in patterns
+ --> $DIR/const-param.rs:7:9
+ |
+LL | N => {}
+ | ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0158`.