Skip to content

Commit d29dae8

Browse files
committed
Auto merge of #158218 - JonathanBrouwer:rollup-LwhDeTI, r=JonathanBrouwer
Rollup of 2 pull requests Successful merges: - #158187 (Avoid uploading package-version on forced-channel jobs) - #156750 (Improve E0637 suggestions for associated type bindings)
2 parents ff64732 + 2447fc7 commit d29dae8

5 files changed

Lines changed: 138 additions & 19 deletions

File tree

compiler/rustc_resolve/src/late.rs

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,9 @@ pub(crate) struct DiagMetadata<'ast> {
768768
/// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
769769
current_where_predicate: Option<&'ast WherePredicate>,
770770

771+
/// Whether we are visiting an associated type equality binding like `Trait<Assoc = &T>`.
772+
in_assoc_ty_binding: bool,
773+
771774
current_type_path: Option<&'ast Ty>,
772775

773776
/// The current impl items (used to suggest).
@@ -1327,7 +1330,11 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
13271330
}
13281331
match constraint.kind {
13291332
AssocItemConstraintKind::Equality { ref term } => match term {
1330-
Term::Ty(ty) => self.visit_ty(ty),
1333+
Term::Ty(ty) => {
1334+
let prev = replace(&mut self.diag_metadata.in_assoc_ty_binding, true);
1335+
self.visit_ty(ty);
1336+
self.diag_metadata.in_assoc_ty_binding = prev;
1337+
}
13311338
Term::Const(c) => {
13321339
self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
13331340
}
@@ -1927,21 +1934,35 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19271934
}
19281935
LifetimeRibKind::AnonymousReportError => {
19291936
let guar = if elided {
1930-
let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| {
1931-
if let LifetimeRibKind::Generics {
1932-
span,
1933-
kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound,
1934-
..
1935-
} = rib.kind
1936-
{
1937-
Some(crate::diagnostics::ElidedAnonymousLifetimeReportErrorSuggestion {
1938-
lo: span.shrink_to_lo(),
1939-
hi: lifetime.ident.span.shrink_to_hi(),
1940-
})
1941-
} else {
1942-
None
1943-
}
1944-
});
1937+
let suggestion = if self.diag_metadata.in_assoc_ty_binding {
1938+
// In an associated type binding like `I: IntoIterator<Item = &T>`,
1939+
// introducing the lifetime on the trait ref would produce
1940+
// `I: for<'a> IntoIterator<Item = &'a T>`. Prefer a named lifetime
1941+
// from an enclosing item instead, so the assoc-ty-binding-specific path
1942+
// below builds that suggestion.
1943+
None
1944+
} else {
1945+
self.lifetime_ribs[i..].iter().rev().find_map(|rib| {
1946+
// Look for a `Generics` rib that represents a trait or where-bound
1947+
// binder (`T: Trait<&U>` or `where T: Trait<&U>`), since that is
1948+
// where the generic E0637 diagnostic can insert `for<'a>`.
1949+
if let LifetimeRibKind::Generics {
1950+
span,
1951+
kind:
1952+
LifetimeBinderKind::PolyTrait
1953+
| LifetimeBinderKind::WhereBound,
1954+
..
1955+
} = rib.kind
1956+
{
1957+
Some(crate::diagnostics::ElidedAnonymousLifetimeReportErrorSuggestion {
1958+
lo: span.shrink_to_lo(),
1959+
hi: lifetime.ident.span.shrink_to_hi(),
1960+
})
1961+
} else {
1962+
None
1963+
}
1964+
})
1965+
};
19451966
// are we trying to use an anonymous lifetime
19461967
// on a non GAT associated trait type?
19471968
if !self.in_func_body
@@ -1993,6 +2014,22 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19932014
self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span);
19942015
err.emit()
19952016
}
2017+
} else if self.diag_metadata.in_assoc_ty_binding {
2018+
// For associated type bindings, e.g.
2019+
// `fn f<I: IntoIterator<Item = &T>>()`, introduce a named lifetime
2020+
// on an enclosing generics binder instead:
2021+
// `fn f<'a, I: IntoIterator<Item = &'a T>>()`.
2022+
let mut err = self.r.dcx().create_err(
2023+
crate::diagnostics::ElidedAnonymousLifetimeReportError {
2024+
span: lifetime.ident.span,
2025+
suggestion,
2026+
},
2027+
);
2028+
self.suggest_introducing_lifetime_for_assoc_ty_binding(
2029+
&mut err,
2030+
lifetime.ident.span,
2031+
);
2032+
err.emit()
19962033
} else {
19972034
self.r.dcx().emit_err(
19982035
crate::diagnostics::ElidedAnonymousLifetimeReportError {

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3762,6 +3762,50 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
37623762
String,
37633763
Vec<(Span, String)>,
37643764
) -> bool,
3765+
) {
3766+
self.suggest_introducing_lifetime_filtered(err, name, |_| true, suggest);
3767+
}
3768+
3769+
pub(crate) fn suggest_introducing_lifetime_for_assoc_ty_binding(
3770+
&self,
3771+
err: &mut Diag<'_>,
3772+
lifetime: Span,
3773+
) {
3774+
self.suggest_introducing_lifetime_filtered(
3775+
err,
3776+
None,
3777+
|kind| {
3778+
!matches!(
3779+
kind,
3780+
LifetimeBinderKind::FnPtrType
3781+
| LifetimeBinderKind::PolyTrait
3782+
| LifetimeBinderKind::WhereBound
3783+
)
3784+
},
3785+
|err, _higher_ranked, span, message, intro_sugg, _| {
3786+
err.multipart_suggestion(
3787+
message,
3788+
vec![(span, intro_sugg), (lifetime.shrink_to_hi(), "'a ".to_string())],
3789+
Applicability::MaybeIncorrect,
3790+
);
3791+
false
3792+
},
3793+
);
3794+
}
3795+
3796+
fn suggest_introducing_lifetime_filtered(
3797+
&self,
3798+
err: &mut Diag<'_>,
3799+
name: Option<Ident>,
3800+
mut consider: impl FnMut(LifetimeBinderKind) -> bool,
3801+
suggest: impl Fn(
3802+
&mut Diag<'_>,
3803+
bool,
3804+
Span,
3805+
Cow<'static, str>,
3806+
String,
3807+
Vec<(Span, String)>,
3808+
) -> bool,
37653809
) {
37663810
let mut suggest_note = true;
37673811
for rib in self.lifetime_ribs.iter().rev() {
@@ -3775,7 +3819,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
37753819
{
37763820
continue;
37773821
}
3778-
if let LifetimeBinderKind::ImplAssocType = kind {
3822+
if matches!(kind, LifetimeBinderKind::ImplAssocType) || !consider(kind) {
37793823
continue;
37803824
}
37813825

src/ci/scripts/upload-artifacts.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ fi
3030
# For nightly and beta this isn't strictly necessary as just trying both is
3131
# enough, but stable builds produce artifacts with a version (e.g.,
3232
# rust-src-1.92.0.tar.xz) which can't be easily guessed otherwise.
33-
channel=$(releaseChannel)
33+
#
34+
# This intentionally does not respect RUST_CI_OVERRIDE_RELEASE_CHANNEL because
35+
# we want a single channel across all runners; otherwise depending on which
36+
# finishes first we might have different output artifacts.
37+
channel=$(cat "${ci_dir}/channel")
3438
if [[ "$channel" = "stable" ]]; then
3539
# On stable, artifacts use the version number. See rust_package_vers in
3640
# src/bootstrap/src/lib.rs.

tests/ui/error-codes/E0637.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,16 @@ where
1414
{
1515
}
1616

17+
// Regression test for https://github.com/rust-lang/rust/issues/156456.
18+
fn associated_type_binding<I: IntoIterator<Item = &String>>() {}
19+
//~^ ERROR: `&` without an explicit lifetime name cannot be used here [E0637]
20+
21+
trait T {
22+
type Assoc;
23+
}
24+
25+
// Regression test for https://github.com/rust-lang/rust/issues/122025.
26+
fn foo<F>(t: F) where F: T<Assoc=&str> {}
27+
//~^ ERROR: `&` without an explicit lifetime name cannot be used here [E0637]
28+
1729
fn main() {}

tests/ui/error-codes/E0637.stderr

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,29 @@ help: consider introducing a higher-ranked lifetime here
3030
LL | T: for<'a> Into<&'a u32>,
3131
| +++++++ ++
3232

33-
error: aborting due to 3 previous errors
33+
error[E0637]: `&` without an explicit lifetime name cannot be used here
34+
--> $DIR/E0637.rs:18:51
35+
|
36+
LL | fn associated_type_binding<I: IntoIterator<Item = &String>>() {}
37+
| ^ explicit lifetime name needed here
38+
|
39+
help: consider introducing a named lifetime parameter
40+
|
41+
LL | fn associated_type_binding<'a, I: IntoIterator<Item = &'a String>>() {}
42+
| +++ ++
43+
44+
error[E0637]: `&` without an explicit lifetime name cannot be used here
45+
--> $DIR/E0637.rs:26:34
46+
|
47+
LL | fn foo<F>(t: F) where F: T<Assoc=&str> {}
48+
| ^ explicit lifetime name needed here
49+
|
50+
help: consider introducing a named lifetime parameter
51+
|
52+
LL | fn foo<'a, F>(t: F) where F: T<Assoc=&'a str> {}
53+
| +++ ++
54+
55+
error: aborting due to 5 previous errors
3456

3557
Some errors have detailed explanations: E0106, E0637.
3658
For more information about an error, try `rustc --explain E0106`.

0 commit comments

Comments
 (0)