Rollup merge of #70006 - petrochenkov:fresh, r=Centril
resolve: Fix two issues in fresh binding disambiguation Prevent fresh bindings from shadowing ambiguity items. Fixes https://github.com/rust-lang/rust/issues/46079 Correctly treat const generic parameters in fresh binding disambiguation. Fixes https://github.com/rust-lang/rust/issues/68853
This commit is contained in:
commit
d986a706bd
@ -87,6 +87,9 @@ impl PatCtxt<'_, '_> {
|
||||
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(
|
||||
|
@ -31,6 +31,7 @@ use std::fmt;
|
||||
#[derive(Clone, Debug)]
|
||||
crate enum PatternError {
|
||||
AssocConstInPattern(Span),
|
||||
ConstParamInPattern(Span),
|
||||
StaticInPattern(Span),
|
||||
FloatBug,
|
||||
NonConstPath(Span),
|
||||
@ -727,7 +728,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
| 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
|
||||
}
|
||||
};
|
||||
|
@ -1517,9 +1517,17 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
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
|
||||
@ -1527,11 +1535,15 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
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(..), _)
|
||||
@ -1547,23 +1559,20 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
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
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,13 +323,6 @@ enum LexicalScopeBinding<'a> {
|
||||
}
|
||||
|
||||
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(),
|
||||
|
@ -716,7 +716,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
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),
|
||||
}
|
||||
|
||||
|
18
src/test/ui/binding/ambiguity-item.rs
Normal file
18
src/test/ui/binding/ambiguity-item.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// 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
|
||||
}
|
||||
}
|
41
src/test/ui/binding/ambiguity-item.stderr
Normal file
41
src/test/ui/binding/ambiguity-item.stderr
Normal file
@ -0,0 +1,41 @@
|
||||
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`.
|
12
src/test/ui/binding/const-param.rs
Normal file
12
src/test/ui/binding/const-param.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// 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() {}
|
17
src/test/ui/binding/const-param.stderr
Normal file
17
src/test/ui/binding/const-param.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
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`.
|
Loading…
Reference in New Issue
Block a user