Skip to content

Commit 518263d

Browse files
committed
Auto merge of #102896 - matthiaskrgr:rollup-jg5xawz, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #101360 (Point out incompatible closure bounds) - #101789 (`let`'s not needed in struct field definitions) - #102846 (update to syn-1.0.102) - #102871 (rustdoc: clean up overly complex `.trait-impl` CSS selectors) - #102876 (suggest candidates for unresolved import) - #102888 (Improve rustdoc-gui search-color test) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 36c8e29 + a52eba4 commit 518263d

File tree

23 files changed

+538
-743
lines changed

23 files changed

+538
-743
lines changed

Cargo.lock

+12-6
Original file line numberDiff line numberDiff line change
@@ -2721,11 +2721,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
27212721

27222722
[[package]]
27232723
name = "proc-macro2"
2724-
version = "1.0.37"
2724+
version = "1.0.46"
27252725
source = "registry+https://github.com/rust-lang/crates.io-index"
2726-
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
2726+
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
27272727
dependencies = [
2728-
"unicode-xid",
2728+
"unicode-ident",
27292729
]
27302730

27312731
[[package]]
@@ -4719,13 +4719,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
47194719

47204720
[[package]]
47214721
name = "syn"
4722-
version = "1.0.91"
4722+
version = "1.0.102"
47234723
source = "registry+https://github.com/rust-lang/crates.io-index"
4724-
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
4724+
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
47254725
dependencies = [
47264726
"proc-macro2",
47274727
"quote",
4728-
"unicode-xid",
4728+
"unicode-ident",
47294729
]
47304730

47314731
[[package]]
@@ -5215,6 +5215,12 @@ dependencies = [
52155215
"matches",
52165216
]
52175217

5218+
[[package]]
5219+
name = "unicode-ident"
5220+
version = "1.0.5"
5221+
source = "registry+https://github.com/rust-lang/crates.io-index"
5222+
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
5223+
52185224
[[package]]
52195225
name = "unicode-normalization"
52205226
version = "0.1.22"

compiler/rustc_parse/src/parser/item.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1788,7 +1788,23 @@ impl<'a> Parser<'a> {
17881788
}
17891789
}
17901790
} else {
1791-
self.expected_ident_found()
1791+
let mut err = self.expected_ident_found();
1792+
if let Some((ident, _)) = self.token.ident() && ident.as_str() == "let" {
1793+
self.bump(); // `let`
1794+
let span = self.prev_token.span.until(self.token.span);
1795+
err.span_suggestion(
1796+
span,
1797+
"remove the let, the `let` keyword is not allowed in struct field definitions",
1798+
String::new(),
1799+
Applicability::MachineApplicable,
1800+
);
1801+
err.note("the `let` keyword is not allowed in `struct` fields");
1802+
err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
1803+
err.emit();
1804+
self.bump();
1805+
return Ok(ident);
1806+
}
1807+
err
17921808
};
17931809
return Err(err);
17941810
}

compiler/rustc_resolve/src/diagnostics.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ impl TypoSuggestion {
7070
}
7171

7272
/// A free importable items suggested in case of resolution failure.
73+
#[derive(Debug, Clone)]
7374
pub(crate) struct ImportSuggestion {
7475
pub did: Option<DefId>,
7576
pub descr: &'static str,
@@ -139,6 +140,7 @@ impl<'a> Resolver<'a> {
139140
if instead { Instead::Yes } else { Instead::No },
140141
found_use,
141142
IsPattern::No,
143+
IsImport::No,
142144
path,
143145
);
144146
err.emit();
@@ -698,6 +700,7 @@ impl<'a> Resolver<'a> {
698700
Instead::No,
699701
FoundUse::Yes,
700702
IsPattern::Yes,
703+
IsImport::No,
701704
vec![],
702705
);
703706
}
@@ -1481,6 +1484,7 @@ impl<'a> Resolver<'a> {
14811484
Instead::No,
14821485
FoundUse::Yes,
14831486
IsPattern::No,
1487+
IsImport::No,
14841488
vec![],
14851489
);
14861490

@@ -2449,6 +2453,34 @@ enum IsPattern {
24492453
No,
24502454
}
24512455

2456+
/// Whether a binding is part of a use statement. Used for diagnostics.
2457+
enum IsImport {
2458+
Yes,
2459+
No,
2460+
}
2461+
2462+
pub(crate) fn import_candidates(
2463+
session: &Session,
2464+
source_span: &IndexVec<LocalDefId, Span>,
2465+
err: &mut Diagnostic,
2466+
// This is `None` if all placement locations are inside expansions
2467+
use_placement_span: Option<Span>,
2468+
candidates: &[ImportSuggestion],
2469+
) {
2470+
show_candidates(
2471+
session,
2472+
source_span,
2473+
err,
2474+
use_placement_span,
2475+
candidates,
2476+
Instead::Yes,
2477+
FoundUse::Yes,
2478+
IsPattern::No,
2479+
IsImport::Yes,
2480+
vec![],
2481+
);
2482+
}
2483+
24522484
/// When an entity with a given name is not available in scope, we search for
24532485
/// entities with that name in all crates. This method allows outputting the
24542486
/// results of this search in a programmer-friendly way
@@ -2462,6 +2494,7 @@ fn show_candidates(
24622494
instead: Instead,
24632495
found_use: FoundUse,
24642496
is_pattern: IsPattern,
2497+
is_import: IsImport,
24652498
path: Vec<Segment>,
24662499
) {
24672500
if candidates.is_empty() {
@@ -2521,7 +2554,8 @@ fn show_candidates(
25212554
// produce an additional newline to separate the new use statement
25222555
// from the directly following item.
25232556
let additional_newline = if let FoundUse::Yes = found_use { "" } else { "\n" };
2524-
candidate.0 = format!("use {};\n{}", &candidate.0, additional_newline);
2557+
let add_use = if let IsImport::Yes = is_import { "" } else { "use " };
2558+
candidate.0 = format!("{}{};\n{}", add_use, &candidate.0, additional_newline);
25252559
}
25262560

25272561
err.span_suggestions(
@@ -2551,7 +2585,7 @@ fn show_candidates(
25512585

25522586
err.note(&msg);
25532587
}
2554-
} else {
2588+
} else if matches!(is_import, IsImport::No) {
25552589
assert!(!inaccessible_path_strings.is_empty());
25562590

25572591
let prefix =

compiler/rustc_resolve/src/imports.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! A bunch of methods and structures more or less related to resolving imports.
22
3-
use crate::diagnostics::Suggestion;
3+
use crate::diagnostics::{import_candidates, Suggestion};
44
use crate::Determinacy::{self, *};
55
use crate::Namespace::{self, *};
6-
use crate::{module_to_string, names_to_string};
6+
use crate::{module_to_string, names_to_string, ImportSuggestion};
77
use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
88
use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
99
use crate::{NameBinding, NameBindingKind, PathResult};
@@ -406,6 +406,7 @@ struct UnresolvedImportError {
406406
label: Option<String>,
407407
note: Option<String>,
408408
suggestion: Option<Suggestion>,
409+
candidate: Option<Vec<ImportSuggestion>>,
409410
}
410411

411412
pub struct ImportResolver<'a, 'b> {
@@ -497,6 +498,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
497498
label: None,
498499
note: None,
499500
suggestion: None,
501+
candidate: None,
500502
};
501503
if path.contains("::") {
502504
errors.push((path, err))
@@ -547,6 +549,16 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
547549
}
548550
diag.multipart_suggestion(&msg, suggestions, applicability);
549551
}
552+
553+
if let Some(candidate) = &err.candidate {
554+
import_candidates(
555+
self.r.session,
556+
&self.r.source_span,
557+
&mut diag,
558+
Some(err.span),
559+
&candidate,
560+
)
561+
}
550562
}
551563

552564
diag.emit();
@@ -664,6 +676,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
664676
Some(finalize),
665677
ignore_binding,
666678
);
679+
667680
let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
668681
import.vis.set(orig_vis);
669682
let module = match path_res {
@@ -706,12 +719,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
706719
String::from("a similar path exists"),
707720
Applicability::MaybeIncorrect,
708721
)),
722+
candidate: None,
709723
},
710724
None => UnresolvedImportError {
711725
span,
712726
label: Some(label),
713727
note: None,
714728
suggestion,
729+
candidate: None,
715730
},
716731
};
717732
return Some(err);
@@ -754,6 +769,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
754769
label: Some(String::from("cannot glob-import a module into itself")),
755770
note: None,
756771
suggestion: None,
772+
candidate: None,
757773
});
758774
}
759775
}
@@ -919,11 +935,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
919935
}
920936
};
921937

938+
let parent_suggestion =
939+
self.r.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
940+
922941
Some(UnresolvedImportError {
923942
span: import.span,
924943
label: Some(label),
925944
note,
926945
suggestion,
946+
candidate: if !parent_suggestion.is_empty() {
947+
Some(parent_suggestion)
948+
} else {
949+
None
950+
},
927951
})
928952
} else {
929953
// `resolve_ident_in_module` reported a privacy error.

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
12551255
found_span,
12561256
found_trait_ref,
12571257
expected_trait_ref,
1258+
obligation.cause.code(),
12581259
)
12591260
} else {
12601261
let (closure_span, found) = found_did

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+67
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,15 @@ pub trait TypeErrCtxtExt<'tcx> {
254254
found_span: Option<Span>,
255255
found: ty::PolyTraitRef<'tcx>,
256256
expected: ty::PolyTraitRef<'tcx>,
257+
cause: &ObligationCauseCode<'tcx>,
257258
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
258259

260+
fn note_conflicting_closure_bounds(
261+
&self,
262+
cause: &ObligationCauseCode<'tcx>,
263+
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
264+
);
265+
259266
fn suggest_fully_qualified_path(
260267
&self,
261268
err: &mut Diagnostic,
@@ -1584,6 +1591,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15841591
found_span: Option<Span>,
15851592
found: ty::PolyTraitRef<'tcx>,
15861593
expected: ty::PolyTraitRef<'tcx>,
1594+
cause: &ObligationCauseCode<'tcx>,
15871595
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
15881596
pub(crate) fn build_fn_sig_ty<'tcx>(
15891597
infcx: &InferCtxt<'tcx>,
@@ -1645,9 +1653,68 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16451653
let signature_kind = format!("{argument_kind} signature");
16461654
err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
16471655

1656+
self.note_conflicting_closure_bounds(cause, &mut err);
1657+
16481658
err
16491659
}
16501660

1661+
// Add a note if there are two `Fn`-family bounds that have conflicting argument
1662+
// requirements, which will always cause a closure to have a type error.
1663+
fn note_conflicting_closure_bounds(
1664+
&self,
1665+
cause: &ObligationCauseCode<'tcx>,
1666+
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
1667+
) {
1668+
// First, look for an `ExprBindingObligation`, which means we can get
1669+
// the unsubstituted predicate list of the called function. And check
1670+
// that the predicate that we failed to satisfy is a `Fn`-like trait.
1671+
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause
1672+
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
1673+
&& let Some(pred) = predicates.predicates.get(*idx)
1674+
&& let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder()
1675+
&& ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id()).is_some()
1676+
{
1677+
let expected_self =
1678+
self.tcx.anonymize_late_bound_regions(pred.kind().rebind(trait_pred.self_ty()));
1679+
let expected_substs = self
1680+
.tcx
1681+
.anonymize_late_bound_regions(pred.kind().rebind(trait_pred.trait_ref.substs));
1682+
1683+
// Find another predicate whose self-type is equal to the expected self type,
1684+
// but whose substs don't match.
1685+
let other_pred = std::iter::zip(&predicates.predicates, &predicates.spans)
1686+
.enumerate()
1687+
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
1688+
ty::PredicateKind::Trait(trait_pred)
1689+
if ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id())
1690+
.is_some()
1691+
&& other_idx != idx
1692+
// Make sure that the self type matches
1693+
// (i.e. constraining this closure)
1694+
&& expected_self
1695+
== self.tcx.anonymize_late_bound_regions(
1696+
pred.kind().rebind(trait_pred.self_ty()),
1697+
)
1698+
// But the substs don't match (i.e. incompatible args)
1699+
&& expected_substs
1700+
!= self.tcx.anonymize_late_bound_regions(
1701+
pred.kind().rebind(trait_pred.trait_ref.substs),
1702+
) =>
1703+
{
1704+
true
1705+
}
1706+
_ => false,
1707+
});
1708+
// If we found one, then it's very likely the cause of the error.
1709+
if let Some((_, (_, other_pred_span))) = other_pred {
1710+
err.span_note(
1711+
*other_pred_span,
1712+
"closure inferred to have a different signature due to this bound",
1713+
);
1714+
}
1715+
}
1716+
}
1717+
16511718
fn suggest_fully_qualified_path(
16521719
&self,
16531720
err: &mut Diagnostic,

src/bootstrap/Cargo.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,9 @@ dependencies = [
445445

446446
[[package]]
447447
name = "proc-macro2"
448-
version = "1.0.39"
448+
version = "1.0.46"
449449
source = "registry+https://github.com/rust-lang/crates.io-index"
450-
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
450+
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
451451
dependencies = [
452452
"unicode-ident",
453453
]
@@ -596,9 +596,9 @@ dependencies = [
596596

597597
[[package]]
598598
name = "syn"
599-
version = "1.0.95"
599+
version = "1.0.102"
600600
source = "registry+https://github.com/rust-lang/crates.io-index"
601-
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
601+
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
602602
dependencies = [
603603
"proc-macro2",
604604
"quote",
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.12.0
1+
0.12.2

0 commit comments

Comments
 (0)