Skip to content

Commit

Permalink
Rollup merge of rust-lang#95085 - ouz-a:master5, r=jackh726
Browse files Browse the repository at this point in the history
Return err instead of ICE

Having `escaping_bound_vars` results in ICE when trying to create `ty::Binder::dummy`, to avoid it we return err like the line above. I think this requires a more sophisticated fix, I would love to investigate if mentorship is available 🤓

Fixes rust-lang#95023 and rust-lang#85350
  • Loading branch information
matthiaskrgr authored Mar 21, 2022
2 parents e3557e2 + be566f1 commit e41e510
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
25 changes: 23 additions & 2 deletions compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ignore-tidy-filelength
//! Name resolution for lifetimes.
//!
//! Name resolution for lifetimes follows *much* simpler rules than the
Expand Down Expand Up @@ -230,6 +231,10 @@ enum Scope<'a> {
hir_id: hir::HirId,

s: ScopeRef<'a>,

/// In some cases not allowing late bounds allows us to avoid ICEs.
/// This is almost ways set to true.
allow_late_bound: bool,
},

/// Lifetimes introduced by a fn are scoped to the call-site for that fn,
Expand Down Expand Up @@ -302,6 +307,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
scope_type,
hir_id,
s: _,
allow_late_bound,
} => f
.debug_struct("Binder")
.field("lifetimes", lifetimes)
Expand All @@ -311,6 +317,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
.field("scope_type", scope_type)
.field("hir_id", hir_id)
.field("s", &"..")
.field("allow_late_bound", allow_late_bound)
.finish(),
Scope::Body { id, s: _ } => {
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
Expand Down Expand Up @@ -703,6 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
};
self.with(scope, move |_old_scope, this| {
intravisit::walk_fn(this, fk, fd, b, s, hir_id)
Expand Down Expand Up @@ -828,6 +836,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses,
scope_type: BinderScopeType::Normal,
s: ROOT_SCOPE,
allow_late_bound: false,
};
self.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &generics.params);
Expand Down Expand Up @@ -896,6 +905,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
};
self.with(scope, |old_scope, this| {
// a bare fn has no bounds, so everything
Expand Down Expand Up @@ -1077,6 +1087,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: false,
};
this.with(scope, |_old_scope, this| {
this.visit_generics(generics);
Expand All @@ -1097,6 +1108,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: false,
};
self.with(scope, |_old_scope, this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
Expand Down Expand Up @@ -1156,6 +1168,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
allow_late_bound: false,
};
self.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &generics.params);
Expand Down Expand Up @@ -1225,6 +1238,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
};
self.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &generics.params);
Expand Down Expand Up @@ -1378,6 +1392,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
};
this.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &bound_generic_params);
Expand Down Expand Up @@ -1425,6 +1440,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type,
allow_late_bound: true,
};
self.with(scope, |_, this| {
intravisit::walk_param_bound(this, bound);
Expand Down Expand Up @@ -1477,6 +1493,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
track_lifetime_uses: true,
opaque_type_parent: false,
scope_type,
allow_late_bound: true,
};
self.with(scope, |old_scope, this| {
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
Expand Down Expand Up @@ -2180,6 +2197,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
opaque_type_parent: true,
track_lifetime_uses: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
};
self.with(scope, move |old_scope, this| {
this.check_lifetime_params(old_scope, &generics.params);
Expand Down Expand Up @@ -2602,7 +2620,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let mut scope = &*self.scope;
let hir_id = loop {
match scope {
Scope::Binder { hir_id, .. } => {
Scope::Binder { hir_id, allow_late_bound: true, .. } => {
break *hir_id;
}
Scope::ObjectLifetimeDefault { ref s, .. }
Expand All @@ -2611,8 +2629,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
| Scope::TraitRefBoundary { ref s, .. } => {
scope = *s;
}
Scope::Root | Scope::Body { .. } => {
Scope::Root
| Scope::Body { .. }
| Scope::Binder { allow_late_bound: false, .. } => {
// See issues #83907 and #83693. Just bail out from looking inside.
// See the issue #95023 for not allowing late bound
self.tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"In fn_like_elision without appropriate scope above",
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/lifetimes/issue-95023.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
struct ErrorKind;
struct Error(ErrorKind);
impl Fn(&isize) for Error {
//~^ ERROR manual implementations of `Fn` are experimental [E0183]
//~^^ ERROR associated type bindings are not allowed here [E0229]
fn foo<const N: usize>(&self) -> Self::B<{N}>;
//~^ ERROR associated function in `impl` without body
//~^^ ERROR method `foo` is not a member of trait `Fn` [E0407]
//~^^^ ERROR associated type `B` not found for `Self` [E0220]
}
fn main() {}
38 changes: 38 additions & 0 deletions src/test/ui/lifetimes/issue-95023.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error: associated function in `impl` without body
--> $DIR/issue-95023.rs:6:5
|
LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: provide a definition for the function: `{ <body> }`

error[E0407]: method `foo` is not a member of trait `Fn`
--> $DIR/issue-95023.rs:6:5
|
LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Fn`

error[E0183]: manual implementations of `Fn` are experimental
--> $DIR/issue-95023.rs:3:6
|
LL | impl Fn(&isize) for Error {
| ^^^^^^^^^^ manual implementations of `Fn` are experimental
|
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable

error[E0229]: associated type bindings are not allowed here
--> $DIR/issue-95023.rs:3:6
|
LL | impl Fn(&isize) for Error {
| ^^^^^^^^^^ associated type not allowed here

error[E0220]: associated type `B` not found for `Self`
--> $DIR/issue-95023.rs:6:44
|
LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
| ^ associated type `B` not found

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0183, E0220, E0229, E0407.
For more information about an error, try `rustc --explain E0183`.
2 changes: 1 addition & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::Path;

const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
const ROOT_ENTRY_LIMIT: usize = 984;
const ROOT_ENTRY_LIMIT: usize = 985;
const ISSUES_ENTRY_LIMIT: usize = 2310;

fn check_entries(path: &Path, bad: &mut bool) {
Expand Down

0 comments on commit e41e510

Please sign in to comment.