Skip to content

Commit 33c42bd

Browse files
authored
Unrolled build for rust-lang#125622
Rollup merge of rust-lang#125622 - oli-obk:define_opaque_types15, r=compiler-errors Winnow private method candidates instead of assuming any candidate of the right name will apply partially reverts rust-lang#60721 My original motivation was just to avoid the `delay_span_bug` (by attempting to thread the `ErrorGuaranteed` through to here). But then I realized that the error message is wrong. It refers to the `Foo<A>::foo` instead of `Foo<B>::foo`. This is almost invisible, because both functions are the same, but on different lines, so `-Zui-testing` makes it so the test is the same no matter which of these two functions is referenced. But there's a much more obvious bug: If `Foo<B>` does not have a `foo` method at all, but `Foo<A>` has a private `foo` method, then we'll refer to that one. This has now been fixed, and we report a normal `method not found` error. The way this is done is by creating a list of all possible private functions (just like we create a list of the public functions that can actually be called), and then winnowing it by analyzing where bounds and `Self` types to see if any of the found methods can actually apply (again, just like with the list of public functions). I wonder if there is room for doing the same thing with unstable functions instead of running all of method resolution twice. r? ``@compiler-errors`` for method resolution stuff
2 parents 7ebd2bd + ffb1b2c commit 33c42bd

File tree

8 files changed

+72
-31
lines changed

8 files changed

+72
-31
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10661066
ty::ImplContainer => {
10671067
if segments.len() == 1 {
10681068
// `<T>::assoc` will end up here, and so
1069-
// can `T::assoc`. It this came from an
1069+
// can `T::assoc`. If this came from an
10701070
// inherent impl, we need to record the
10711071
// `T` for posterity (see `UserSelfTy` for
10721072
// details).
@@ -1416,11 +1416,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14161416
) {
14171417
Ok(ok) => self.register_infer_ok_obligations(ok),
14181418
Err(_) => {
1419-
self.dcx().span_delayed_bug(
1419+
self.dcx().span_bug(
14201420
span,
14211421
format!(
1422-
"instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
1423-
),
1422+
"instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
1423+
),
14241424
);
14251425
}
14261426
}

compiler/rustc_hir_typeck/src/method/probe.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{
4141
use rustc_trait_selection::traits::query::CanonicalTyGoal;
4242
use rustc_trait_selection::traits::ObligationCtxt;
4343
use rustc_trait_selection::traits::{self, ObligationCause};
44+
use std::cell::Cell;
4445
use std::cell::RefCell;
4546
use std::cmp::max;
4647
use std::iter;
@@ -76,8 +77,12 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
7677
/// requested name (by edit distance)
7778
allow_similar_names: bool,
7879

80+
/// List of potential private candidates. Will be trimmed to ones that
81+
/// actually apply and then the result inserted into `private_candidate`
82+
private_candidates: Vec<Candidate<'tcx>>,
83+
7984
/// Some(candidate) if there is a private candidate
80-
private_candidate: Option<(DefKind, DefId)>,
85+
private_candidate: Cell<Option<(DefKind, DefId)>>,
8186

8287
/// Collects near misses when the candidate functions are missing a `self` keyword and is only
8388
/// used for error reporting
@@ -581,7 +586,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
581586
orig_steps_var_values,
582587
steps,
583588
allow_similar_names: false,
584-
private_candidate: None,
589+
private_candidates: Vec::new(),
590+
private_candidate: Cell::new(None),
585591
static_candidates: RefCell::new(Vec::new()),
586592
unsatisfied_predicates: RefCell::new(Vec::new()),
587593
scope_expr_id,
@@ -593,7 +599,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
593599
self.inherent_candidates.clear();
594600
self.extension_candidates.clear();
595601
self.impl_dups.clear();
596-
self.private_candidate = None;
602+
self.private_candidates.clear();
603+
self.private_candidate.set(None);
597604
self.static_candidates.borrow_mut().clear();
598605
self.unsatisfied_predicates.borrow_mut().clear();
599606
}
@@ -617,9 +624,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
617624
} else {
618625
self.extension_candidates.push(candidate);
619626
}
620-
} else if self.private_candidate.is_none() {
621-
self.private_candidate =
622-
Some((candidate.item.kind.as_def_kind(), candidate.item.def_id));
627+
} else {
628+
self.private_candidates.push(candidate);
623629
}
624630
}
625631

@@ -1171,7 +1177,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11711177
let mut possibly_unsatisfied_predicates = Vec::new();
11721178

11731179
for (kind, candidates) in
1174-
&[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
1180+
[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
11751181
{
11761182
debug!("searching {} candidates", kind);
11771183
let res = self.consider_candidates(
@@ -1185,6 +1191,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11851191
}
11861192
}
11871193

1194+
if self.private_candidate.get().is_none() {
1195+
if let Some(Ok(pick)) =
1196+
self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], None)
1197+
{
1198+
self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id)));
1199+
}
1200+
}
1201+
11881202
// `pick_method` may be called twice for the same self_ty if no stable methods
11891203
// match. Only extend once.
11901204
if unstable_candidates.is_some() {

src/tools/tidy/src/issues.txt

-1
Original file line numberDiff line numberDiff line change
@@ -2445,7 +2445,6 @@ ui/issues/issue-53300.rs
24452445
ui/issues/issue-53333.rs
24462446
ui/issues/issue-53348.rs
24472447
ui/issues/issue-53419.rs
2448-
ui/issues/issue-53498.rs
24492448
ui/issues/issue-53568.rs
24502449
ui/issues/issue-5358-1.rs
24512450
ui/issues/issue-53728.rs

src/tools/tidy/src/ui_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
1515
const ENTRY_LIMIT: u32 = 900;
1616
// FIXME: The following limits should be reduced eventually.
1717

18-
const ISSUES_ENTRY_LIMIT: u32 = 1674;
18+
const ISSUES_ENTRY_LIMIT: u32 = 1672;
1919

2020
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
2121
"rs", // test source files

tests/ui/issues/issue-53498.rs

-17
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0599]: no function or associated item named `foo` found for struct `Foo<B>` in the current scope
2+
--> $DIR/ufc-method-call.rs:27:27
3+
|
4+
LL | pub struct Foo<T>(T);
5+
| ----------------- function or associated item `foo` not found for this struct
6+
...
7+
LL | test::Foo::<test::B>::foo();
8+
| ^^^ function or associated item not found in `Foo<B>`
9+
|
10+
= note: the function or associated item was found for
11+
- `Foo<A>`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0599`.

tests/ui/privacy/ufc-method-call.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! This test used to report that the method call cannot
2+
//! call the private method `Foo<A>::foo`, even though the user
3+
//! explicitly selected `Foo<B>::foo`. This is because we only
4+
//! looked for methods of the right name, without properly checking
5+
//! the `Self` type
6+
7+
//@ revisions: same_name different_name
8+
9+
pub mod test {
10+
pub struct A;
11+
pub struct B;
12+
pub struct Foo<T>(T);
13+
14+
impl Foo<A> {
15+
fn foo() {}
16+
}
17+
18+
impl Foo<B> {
19+
#[cfg(same_name)]
20+
fn foo() {}
21+
#[cfg(different_name)]
22+
fn bar() {}
23+
}
24+
}
25+
26+
fn main() {
27+
test::Foo::<test::B>::foo();
28+
//[same_name]~^ ERROR associated function `foo` is private
29+
//[different_name]~^^ ERROR no function or associated item named `foo` found for struct `Foo<B>`
30+
}

tests/ui/issues/issue-53498.stderr tests/ui/privacy/ufc-method-call.same_name.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0624]: associated function `foo` is private
2-
--> $DIR/issue-53498.rs:16:27
2+
--> $DIR/ufc-method-call.rs:27:27
33
|
44
LL | fn foo() {}
55
| -------- private associated function defined here

0 commit comments

Comments
 (0)