Skip to content

Commit f93bb2a

Browse files
committed
Auto merge of rust-lang#72575 - Dylan-DPC:rollup-zo679hv, r=Dylan-DPC
Rollup of 4 pull requests Successful merges: - rust-lang#72153 (exhaustively check `ty::Kind` during structural match checking) - rust-lang#72308 (Emit a better diagnostic when function actually has a 'self' parameter) - rust-lang#72560 (Enable `glacier` command via triagebot) - rust-lang#72567 (Clean up E0608 explanation) Failed merges: r? @ghost
2 parents a0f06d1 + aa8d64b commit f93bb2a

File tree

12 files changed

+173
-11
lines changed

12 files changed

+173
-11
lines changed

src/librustc_error_codes/error_codes/E0608.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
An attempt to index into a type which doesn't implement the `std::ops::Index`
1+
An attempt to use index on a type which doesn't implement the `std::ops::Index`
22
trait was performed.
33

44
Erroneous code example:

src/librustc_mir_build/hair/pattern/const_to_pat.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,20 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
124124
traits::NonStructuralMatchTy::Dynamic => {
125125
"trait objects cannot be used in patterns".to_string()
126126
}
127+
traits::NonStructuralMatchTy::Opaque => {
128+
"opaque types cannot be used in patterns".to_string()
129+
}
130+
traits::NonStructuralMatchTy::Generator => {
131+
"generators cannot be used in patterns".to_string()
132+
}
127133
traits::NonStructuralMatchTy::Param => {
128-
bug!("use of constant whose type is a parameter inside a pattern")
134+
bug!("use of a constant whose type is a parameter inside a pattern")
135+
}
136+
traits::NonStructuralMatchTy::Projection => {
137+
bug!("use of a constant whose type is a projection inside a pattern")
138+
}
139+
traits::NonStructuralMatchTy::Foreign => {
140+
bug!("use of a value of a foreign type inside a pattern")
129141
}
130142
};
131143

src/librustc_resolve/late.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ struct DiagnosticMetadata<'ast> {
347347
currently_processing_generics: bool,
348348

349349
/// The current enclosing function (used for better errors).
350-
current_function: Option<Span>,
350+
current_function: Option<(FnKind<'ast>, Span)>,
351351

352352
/// A list of labels as of yet unused. Labels will be removed from this map when
353353
/// they are used (in a `break` or `continue` statement)
@@ -466,7 +466,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
466466
FnKind::Fn(FnCtxt::Free | FnCtxt::Foreign, ..) => FnItemRibKind,
467467
FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind,
468468
};
469-
let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));
469+
let previous_value =
470+
replace(&mut self.diagnostic_metadata.current_function, Some((fn_kind, sp)));
470471
debug!("(resolving function) entering function");
471472
let declaration = fn_kind.decl();
472473

src/librustc_resolve/late/diagnostics.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,15 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
195195
_ => "`self` value is a keyword only available in methods with a `self` parameter"
196196
.to_string(),
197197
});
198-
if let Some(span) = &self.diagnostic_metadata.current_function {
199-
err.span_label(*span, "this function doesn't have a `self` parameter");
198+
if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function {
199+
// The current function has a `self' parameter, but we were unable to resolve
200+
// a reference to `self`. This can only happen if the `self` identifier we
201+
// are resolving came from a different hygiene context.
202+
if fn_kind.decl().inputs.get(0).map(|p| p.is_self()).unwrap_or(false) {
203+
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
204+
} else {
205+
err.span_label(*span, "this function doesn't have a `self` parameter");
206+
}
200207
}
201208
return (err, Vec::new());
202209
}

src/librustc_trait_selection/traits/structural_match.rs

+48-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ pub enum NonStructuralMatchTy<'tcx> {
1313
Adt(&'tcx AdtDef),
1414
Param,
1515
Dynamic,
16+
Foreign,
17+
Opaque,
18+
Generator,
19+
Projection,
1620
}
1721

1822
/// This method traverses the structure of `ty`, trying to find an
@@ -143,6 +147,22 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
143147
self.found = Some(NonStructuralMatchTy::Dynamic);
144148
return true; // Stop visiting.
145149
}
150+
ty::Foreign(_) => {
151+
self.found = Some(NonStructuralMatchTy::Foreign);
152+
return true; // Stop visiting.
153+
}
154+
ty::Opaque(..) => {
155+
self.found = Some(NonStructuralMatchTy::Opaque);
156+
return true; // Stop visiting.
157+
}
158+
ty::Projection(..) => {
159+
self.found = Some(NonStructuralMatchTy::Projection);
160+
return true; // Stop visiting.
161+
}
162+
ty::Generator(..) | ty::GeneratorWitness(..) => {
163+
self.found = Some(NonStructuralMatchTy::Generator);
164+
return true; // Stop visiting.
165+
}
146166
ty::RawPtr(..) => {
147167
// structural-match ignores substructure of
148168
// `*const _`/`*mut _`, so skip `super_visit_with`.
@@ -159,32 +179,55 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
159179
// structural equality on `T` does not recur into the raw
160180
// pointer. Therefore, one can still use `C` in a pattern.
161181

162-
// (But still tell caller to continue search.)
182+
// (But still tell the caller to continue search.)
163183
return false;
164184
}
165185
ty::FnDef(..) | ty::FnPtr(..) => {
166-
// types of formals and return in `fn(_) -> _` are also irrelevant;
186+
// Types of formals and return in `fn(_) -> _` are also irrelevant;
167187
// so we do not recur into them via `super_visit_with`
168188
//
169-
// (But still tell caller to continue search.)
189+
// (But still tell the caller to continue search.)
170190
return false;
171191
}
172192
ty::Array(_, n)
173193
if { n.try_eval_usize(self.tcx(), ty::ParamEnv::reveal_all()) == Some(0) } =>
174194
{
175195
// rust-lang/rust#62336: ignore type of contents
176196
// for empty array.
197+
//
198+
// (But still tell the caller to continue search.)
177199
return false;
178200
}
179-
_ => {
201+
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => {
202+
// These primitive types are always structural match.
203+
//
204+
// `Never` is kind of special here, but as it is not inhabitable, this should be fine.
205+
//
206+
// (But still tell the caller to continue search.)
207+
return false;
208+
}
209+
210+
ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {
211+
// First check all contained types and then tell the caller to continue searching.
180212
ty.super_visit_with(self);
181213
return false;
182214
}
215+
ty::Closure(..) | ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => {
216+
bug!("unexpected type during structural-match checking: {:?}", ty);
217+
}
218+
ty::Error => {
219+
self.tcx().sess.delay_span_bug(self.span, "ty::Error in structural-match check");
220+
// We still want to check other types after encountering an error,
221+
// as this may still emit relevant errors.
222+
//
223+
// So we continue searching here.
224+
return false;
225+
}
183226
};
184227

185228
if !self.seen.insert(adt_def.did) {
186229
debug!("Search already seen adt_def: {:?}", adt_def);
187-
// let caller continue its search
230+
// Let caller continue its search.
188231
return false;
189232
}
190233

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Regression test for issue #66898
2+
// Tests that we don't emit a nonsensical error message
3+
// when a macro invocation tries to access `self` from a function
4+
// that has a 'self' parameter
5+
6+
pub struct Foo;
7+
8+
macro_rules! call_bar {
9+
() => {
10+
self.bar(); //~ ERROR expected value
11+
}
12+
}
13+
14+
impl Foo {
15+
pub fn foo(&self) {
16+
call_bar!();
17+
}
18+
19+
pub fn bar(&self) {
20+
}
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0424]: expected value, found module `self`
2+
--> $DIR/missing-self-diag.rs:10:9
3+
|
4+
LL | self.bar();
5+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
6+
...
7+
LL | / pub fn foo(&self) {
8+
LL | | call_bar!();
9+
| | ------------ in this macro invocation
10+
LL | | }
11+
| |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
12+
|
13+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0424`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![feature(const_fn, type_alias_impl_trait)]
2+
3+
type Bar = impl Send;
4+
5+
// While i32 is structural-match, we do not want to leak this information.
6+
// (See https://github.com/rust-lang/rust/issues/72156)
7+
const fn leak_free() -> Bar {
8+
7i32
9+
}
10+
const LEAK_FREE: Bar = leak_free();
11+
12+
fn leak_free_test() {
13+
match todo!() {
14+
LEAK_FREE => (),
15+
//~^ opaque types cannot be used in patterns
16+
_ => (),
17+
}
18+
}
19+
20+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: opaque types cannot be used in patterns
2+
--> $DIR/structural-match-no-leak.rs:14:9
3+
|
4+
LL | LEAK_FREE => (),
5+
| ^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(const_fn, type_alias_impl_trait)]
2+
3+
type Foo = impl Send;
4+
5+
// This is not structural-match
6+
struct A;
7+
8+
const fn value() -> Foo {
9+
A
10+
}
11+
const VALUE: Foo = value();
12+
13+
fn test() {
14+
match todo!() {
15+
VALUE => (),
16+
//~^ opaque types cannot be used in patterns
17+
_ => (),
18+
}
19+
}
20+
21+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: opaque types cannot be used in patterns
2+
--> $DIR/structural-match.rs:15:9
3+
|
4+
LL | VALUE => (),
5+
| ^^^^^
6+
7+
error: aborting due to previous error
8+

triagebot.toml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ allow-unauthenticated = [
1010

1111
[assign]
1212

13+
[glacier]
14+
1315
[ping.icebreakers-llvm]
1416
alias = ["llvm", "llvms"]
1517
message = """\

0 commit comments

Comments
 (0)