Skip to content

Commit 867fd0a

Browse files
arielb1Ariel Ben-Yehuda
authored and
Ariel Ben-Yehuda
committed
project: add a recursion limit to "tail-recursive" projections
Fixes #21946 Fixes #23992 Fixes #25945
1 parent 0152a93 commit 867fd0a

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

src/librustc/middle/traits/project.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ pub fn normalize_projection_type<'a,'b,'tcx>(
343343
projection_ty: projection_ty,
344344
ty: ty_var
345345
});
346-
let obligation = Obligation::with_depth(cause, depth+1, projection.to_predicate());
346+
let obligation = Obligation::with_depth(
347+
cause, depth + 1, projection.to_predicate());
347348
Normalized {
348349
value: ty_var,
349350
obligations: vec!(obligation)
@@ -382,7 +383,7 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
382383
obligations);
383384

384385
if projected_ty.has_projection_types() {
385-
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
386+
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth+1);
386387
let normalized_ty = normalizer.fold(&projected_ty);
387388

388389
debug!("normalize_projection_type: normalized_ty={:?} depth={}",

src/test/compile-fail/issue-21946.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Foo {
12+
type A;
13+
}
14+
15+
struct FooStruct;
16+
17+
impl Foo for FooStruct {
18+
//~^ ERROR overflow evaluating the requirement `<FooStruct as Foo>::A`
19+
type A = <FooStruct as Foo>::A;
20+
}
21+
22+
fn main() {}

src/test/run-pass/issue-23992.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub struct Outer<T: Trait>(T);
12+
pub struct Inner<'a> { value: &'a bool }
13+
14+
pub trait Trait {
15+
type Error;
16+
fn ready(self) -> Self::Error;
17+
}
18+
19+
impl<'a> Trait for Inner<'a> {
20+
type Error = Outer<Inner<'a>>;
21+
fn ready(self) -> Outer<Inner<'a>> { Outer(self) }
22+
}
23+
24+
fn main() {
25+
let value = true;
26+
let inner = Inner { value: &value };
27+
assert_eq!(inner.ready().0.value, &value);
28+
}

0 commit comments

Comments
 (0)