summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs73
1 files changed, 63 insertions, 10 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 794812a5c..acd0bcd8e 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
use std::fmt;
use crate::errors;
@@ -338,7 +338,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
Scope::TraitRefBoundary { .. } => {
// We should only see super trait lifetimes if there is a `Binder` above
- assert!(supertrait_bound_vars.is_empty());
+ // though this may happen when we call `poly_trait_ref_binder_info` with
+ // an (erroneous, #113423) associated return type bound in an impl header.
+ if !supertrait_bound_vars.is_empty() {
+ self.tcx.sess.delay_span_bug(
+ DUMMY_SP,
+ format!(
+ "found supertrait lifetimes without a binder to append \
+ them to: {supertrait_bound_vars:?}"
+ ),
+ );
+ }
break (vec![], BinderScopeType::Normal);
}
@@ -556,7 +566,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
});
}
}
- hir::ItemKind::OpaqueTy(hir::OpaqueTy {
+ hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
generics,
..
@@ -1344,12 +1354,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
Scope::Binder {
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
} => {
- let mut err = self.tcx.sess.struct_span_err(
- lifetime_ref.ident.span,
- "`impl Trait` can only mention lifetimes bound at the fn or impl level",
- );
- err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
- err.emit();
+ self.tcx.sess.emit_err(errors::LateBoundInApit::Lifetime {
+ span: lifetime_ref.ident.span,
+ param_span: self.tcx.def_span(region_def_id),
+ });
return;
}
Scope::Root { .. } => break,
@@ -1379,6 +1387,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
let mut late_depth = 0;
let mut scope = self.scope;
let mut crossed_anon_const = false;
+
let result = loop {
match *scope {
Scope::Body { s, .. } => {
@@ -1446,6 +1455,50 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
return;
}
+ // We may fail to resolve higher-ranked ty/const vars that are mentioned by APIT.
+ // AST-based resolution does not care for impl-trait desugaring, which are the
+ // responsibility of lowering. This may create a mismatch between the resolution
+ // AST found (`param_def_id`) which points to HRTB, and what HIR allows.
+ // ```
+ // fn foo(x: impl for<T> Trait<Assoc = impl Trait2<T>>) {}
+ // ```
+ //
+ // In such case, walk back the binders to diagnose it properly.
+ let mut scope = self.scope;
+ loop {
+ match *scope {
+ Scope::Binder {
+ where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
+ } => {
+ let guar = self.tcx.sess.emit_err(match self.tcx.def_kind(param_def_id) {
+ DefKind::TyParam => errors::LateBoundInApit::Type {
+ span: self.tcx.hir().span(hir_id),
+ param_span: self.tcx.def_span(param_def_id),
+ },
+ DefKind::ConstParam => errors::LateBoundInApit::Const {
+ span: self.tcx.hir().span(hir_id),
+ param_span: self.tcx.def_span(param_def_id),
+ },
+ kind => {
+ bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id()))
+ }
+ });
+ self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
+ return;
+ }
+ Scope::Root { .. } => break,
+ Scope::Binder { s, .. }
+ | Scope::Body { s, .. }
+ | Scope::Elision { s, .. }
+ | Scope::ObjectLifetimeDefault { s, .. }
+ | Scope::Supertrait { s, .. }
+ | Scope::TraitRefBoundary { s, .. }
+ | Scope::AnonConstBoundary { s } => {
+ scope = s;
+ }
+ }
+ }
+
self.tcx.sess.delay_span_bug(
self.tcx.hir().span(hir_id),
format!("could not resolve {param_def_id:?}"),
@@ -1761,7 +1814,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
+ ty::ClauseKind::Trait(data) => {
// The order here needs to match what we would get from `subst_supertrait`
let pred_bound_vars = bound_predicate.bound_vars();
let mut all_bound_vars = bound_vars.clone();