Skip to content

Commit d986a70

Browse files
authored
Rollup merge of #70006 - petrochenkov:fresh, r=Centril
resolve: Fix two issues in fresh binding disambiguation Prevent fresh bindings from shadowing ambiguity items. Fixes #46079 Correctly treat const generic parameters in fresh binding disambiguation. Fixes #68853
2 parents 8bca839 + 78f01ec commit d986a70

File tree

9 files changed

+123
-24
lines changed

9 files changed

+123
-24
lines changed

src/librustc_mir_build/hair/pattern/check_match.rs

+3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ impl PatCtxt<'_, '_> {
8787
PatternError::AssocConstInPattern(span) => {
8888
self.span_e0158(span, "associated consts cannot be referenced in patterns")
8989
}
90+
PatternError::ConstParamInPattern(span) => {
91+
self.span_e0158(span, "const parameters cannot be referenced in patterns")
92+
}
9093
PatternError::FloatBug => {
9194
// FIXME(#31407) this is only necessary because float parsing is buggy
9295
::rustc::mir::interpret::struct_error(

src/librustc_mir_build/hair/pattern/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use std::fmt;
3131
#[derive(Clone, Debug)]
3232
crate enum PatternError {
3333
AssocConstInPattern(Span),
34+
ConstParamInPattern(Span),
3435
StaticInPattern(Span),
3536
FloatBug,
3637
NonConstPath(Span),
@@ -727,7 +728,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
727728
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
728729

729730
_ => {
730-
self.errors.push(PatternError::NonConstPath(span));
731+
let pattern_error = match res {
732+
Res::Def(DefKind::ConstParam, _) => PatternError::ConstParamInPattern(span),
733+
_ => PatternError::NonConstPath(span),
734+
};
735+
self.errors.push(pattern_error);
731736
PatKind::Wild
732737
}
733738
};

src/librustc_resolve/late.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -1517,21 +1517,33 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15171517
ident: Ident,
15181518
has_sub: bool,
15191519
) -> Option<Res> {
1520-
let binding =
1521-
self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?.item()?;
1522-
let res = binding.res();
1520+
let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?;
1521+
let (res, binding) = match ls_binding {
1522+
LexicalScopeBinding::Item(binding) if binding.is_ambiguity() => {
1523+
// For ambiguous bindings we don't know all their definitions and cannot check
1524+
// whether they can be shadowed by fresh bindings or not, so force an error.
1525+
self.r.record_use(ident, ValueNS, binding, false);
1526+
return None;
1527+
}
1528+
LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)),
1529+
LexicalScopeBinding::Res(res) => (res, None),
1530+
};
15231531

15241532
// An immutable (no `mut`) by-value (no `ref`) binding pattern without
15251533
// a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
15261534
// also be interpreted as a path to e.g. a constant, variant, etc.
15271535
let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
15281536

15291537
match res {
1530-
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::Def(DefKind::Const, _)
1538+
Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
1539+
| Res::Def(DefKind::Const, _)
1540+
| Res::Def(DefKind::ConstParam, _)
15311541
if is_syntactic_ambiguity =>
15321542
{
15331543
// Disambiguate in favor of a unit struct/variant or constant pattern.
1534-
self.r.record_use(ident, ValueNS, binding, false);
1544+
if let Some(binding) = binding {
1545+
self.r.record_use(ident, ValueNS, binding, false);
1546+
}
15351547
Some(res)
15361548
}
15371549
Res::Def(DefKind::Ctor(..), _)
@@ -1547,23 +1559,20 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15471559
ResolutionError::BindingShadowsSomethingUnacceptable(
15481560
pat_src.descr(),
15491561
ident.name,
1550-
binding,
1562+
binding.expect("no binding for a ctor or static"),
15511563
),
15521564
);
15531565
None
15541566
}
1555-
Res::Def(DefKind::Fn, _) | Res::Err => {
1567+
Res::Def(DefKind::Fn, _) | Res::Local(..) | Res::Err => {
15561568
// These entities are explicitly allowed to be shadowed by fresh bindings.
15571569
None
15581570
}
1559-
res => {
1560-
span_bug!(
1561-
ident.span,
1562-
"unexpected resolution for an \
1563-
identifier in pattern: {:?}",
1564-
res
1565-
);
1566-
}
1571+
_ => span_bug!(
1572+
ident.span,
1573+
"unexpected resolution for an identifier in pattern: {:?}",
1574+
res
1575+
),
15671576
}
15681577
}
15691578

src/librustc_resolve/lib.rs

-7
Original file line numberDiff line numberDiff line change
@@ -323,13 +323,6 @@ enum LexicalScopeBinding<'a> {
323323
}
324324

325325
impl<'a> LexicalScopeBinding<'a> {
326-
fn item(self) -> Option<&'a NameBinding<'a>> {
327-
match self {
328-
LexicalScopeBinding::Item(binding) => Some(binding),
329-
_ => None,
330-
}
331-
}
332-
333326
fn res(self) -> Res {
334327
match self {
335328
LexicalScopeBinding::Item(binding) => binding.res(),

src/librustc_typeck/check/pat.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
716716
Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
717717
| Res::SelfCtor(..)
718718
| Res::Def(DefKind::Const, _)
719-
| Res::Def(DefKind::AssocConst, _) => {} // OK
719+
| Res::Def(DefKind::AssocConst, _)
720+
| Res::Def(DefKind::ConstParam, _) => {} // OK
720721
_ => bug!("unexpected pattern resolution: {:?}", res),
721722
}
722723

src/test/ui/binding/ambiguity-item.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Identifier pattern referring to an ambiguity item is an error (issue #46079).
2+
3+
mod m {
4+
pub fn f() {}
5+
}
6+
use m::*;
7+
8+
mod n {
9+
pub fn f() {}
10+
}
11+
use n::*; // OK, no conflict with `use m::*;`
12+
13+
fn main() {
14+
let v = f; //~ ERROR `f` is ambiguous
15+
match v {
16+
f => {} //~ ERROR `f` is ambiguous
17+
}
18+
}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0659]: `f` is ambiguous (glob import vs glob import in the same module)
2+
--> $DIR/ambiguity-item.rs:14:13
3+
|
4+
LL | let v = f;
5+
| ^ ambiguous name
6+
|
7+
note: `f` could refer to the function imported here
8+
--> $DIR/ambiguity-item.rs:6:5
9+
|
10+
LL | use m::*;
11+
| ^^^^
12+
= help: consider adding an explicit import of `f` to disambiguate
13+
note: `f` could also refer to the function imported here
14+
--> $DIR/ambiguity-item.rs:11:5
15+
|
16+
LL | use n::*; // OK, no conflict with `use m::*;`
17+
| ^^^^
18+
= help: consider adding an explicit import of `f` to disambiguate
19+
20+
error[E0659]: `f` is ambiguous (glob import vs glob import in the same module)
21+
--> $DIR/ambiguity-item.rs:16:9
22+
|
23+
LL | f => {}
24+
| ^ ambiguous name
25+
|
26+
note: `f` could refer to the function imported here
27+
--> $DIR/ambiguity-item.rs:6:5
28+
|
29+
LL | use m::*;
30+
| ^^^^
31+
= help: consider adding an explicit import of `f` to disambiguate
32+
note: `f` could also refer to the function imported here
33+
--> $DIR/ambiguity-item.rs:11:5
34+
|
35+
LL | use n::*; // OK, no conflict with `use m::*;`
36+
| ^^^^
37+
= help: consider adding an explicit import of `f` to disambiguate
38+
39+
error: aborting due to 2 previous errors
40+
41+
For more information about this error, try `rustc --explain E0659`.

src/test/ui/binding/const-param.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Identifier pattern referring to a const generic parameter is an error (issue #68853).
2+
3+
#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
4+
5+
fn check<const N: usize>() {
6+
match 1 {
7+
N => {} //~ ERROR const parameters cannot be referenced in patterns
8+
_ => {}
9+
}
10+
}
11+
12+
fn main() {}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/const-param.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0158]: const parameters cannot be referenced in patterns
10+
--> $DIR/const-param.rs:7:9
11+
|
12+
LL | N => {}
13+
| ^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0158`.

0 commit comments

Comments
 (0)