Skip to content

Commit

Permalink
Account for late-bound vars from parent arg-position impl trait
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jun 26, 2023
1 parent 6f8c27a commit 26cd548
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 0 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ hir_analysis_invalid_union_field =
hir_analysis_invalid_union_field_sugg =
wrap the field type in `ManuallyDrop<...>`
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
.label = const parameter declared here
hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl
.label = type parameter declared here
hir_analysis_lifetimes_or_bounds_mismatch_on_trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
Expand Down
45 changes: 45 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,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, .. } => {
Expand Down Expand Up @@ -1446,6 +1447,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:?}"),
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,3 +875,21 @@ pub(crate) enum ReturnTypeNotationIllegalParam {
param_span: Span,
},
}

#[derive(Diagnostic)]
pub(crate) enum LateBoundInApit {
#[diag(hir_analysis_late_bound_type_in_apit)]
Type {
#[primary_span]
span: Span,
#[label]
param_span: Span,
},
#[diag(hir_analysis_late_bound_const_in_apit)]
Const {
#[primary_span]
span: Span,
#[label]
param_span: Span,
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(non_lifetime_binders)]
//~^ WARN the feature `non_lifetime_binders` is incomplete

trait Trait<Input> {
type Assoc;
}

fn uwu(_: impl for<T> Trait<(), Assoc = impl Trait<T>>) {}
//~^ ERROR `impl Trait` can only mention type parameters from an fn or impl

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/nested-apit-mentioning-outer-bound-var.rs:1:12
|
LL | #![feature(non_lifetime_binders)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
= note: `#[warn(incomplete_features)]` on by default

error: `impl Trait` can only mention type parameters from an fn or impl
--> $DIR/nested-apit-mentioning-outer-bound-var.rs:8:52
|
LL | fn uwu(_: impl for<T> Trait<(), Assoc = impl Trait<T>>) {}
| - type parameter declared here ^

error: aborting due to previous error; 1 warning emitted

0 comments on commit 26cd548

Please sign in to comment.