Skip to content

Commit b3dcb85

Browse files
committed
Fix a bug in the opt-in-copy work: it was failing to liberate the regions bound in the impl before searching for Copy implements for all fields, leading to problems in the "copyability check". Basically the copyability check would wind up looking for an impl of for<'tcx> Foo<&'tcx T>. The impl that exists however is impl<T> Copy for Foo<T> and the current rules do not consider that a match (something I would like to revise in a later PR).
1 parent 1b24602 commit b3dcb85

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/librustc_typeck/coherence/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
use metadata::csearch::{each_impl, get_impl_trait};
2020
use metadata::csearch;
21+
use middle::region;
2122
use middle::subst::{mod, Subst};
2223
use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
2324
use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
@@ -26,8 +27,6 @@ use middle::ty::{ty_param, Polytype, ty_ptr};
2627
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
2728
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
2829
use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn};
29-
use middle::ty::{ty_closure};
30-
use middle::subst::Subst;
3130
use middle::ty;
3231
use CrateCtxt;
3332
use middle::infer::combine::Combine;
@@ -472,6 +471,17 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
472471
impl_did.node);
473472
let self_type = self_type.ty.subst(tcx, &param_env.free_substs);
474473

474+
// the self-type may have late-bound regions bound in the
475+
// impl; liberate them.
476+
let item_scope = region::CodeExtent::from_node_id(impl_did.node);
477+
let self_type =
478+
ty::liberate_late_bound_regions(tcx,
479+
item_scope,
480+
&ty::bind(self_type)).value;
481+
482+
debug!("can_type_implement_copy(self_type={})",
483+
self_type.repr(tcx));
484+
475485
match ty::can_type_implement_copy(tcx, self_type, &param_env) {
476486
Ok(()) => {}
477487
Err(ty::FieldDoesNotImplementCopy(name)) => {

src/test/run-pass/hrtb-opt-in-copy.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2014 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+
// Test that we handle binder levels correctly when checking whether a
12+
// type can implement `Copy`. In particular, we had a bug where we failed to
13+
// liberate the late-bound regions from the impl, and thus wound up
14+
// searching for an impl of `for<'tcx> Foo<&'tcx T>`. The impl that
15+
// exists however is `impl<T> Copy for Foo<T>` and the current rules
16+
// did not consider that a match (something I would like to revise in
17+
// a later PR).
18+
19+
#![allow(dead_code)]
20+
21+
use std::kinds::marker;
22+
23+
#[deriving(Copy)]
24+
struct Foo<T> { x: T }
25+
26+
type Ty<'tcx> = &'tcx TyS<'tcx>;
27+
28+
enum TyS<'tcx> {
29+
Boop(marker::InvariantLifetime<'tcx>)
30+
}
31+
32+
enum Bar<'tcx> {
33+
Baz(Foo<Ty<'tcx>>)
34+
}
35+
36+
impl<'tcx> Copy for Bar<'tcx> { }
37+
38+
fn main() { }

0 commit comments

Comments
 (0)