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).

This commit is contained in:
Niko Matsakis 2014-12-10 19:11:15 -05:00
parent 1b24602ca0
commit b3dcb85404
2 changed files with 50 additions and 2 deletions

View File

@ -18,6 +18,7 @@
use metadata::csearch::{each_impl, get_impl_trait};
use metadata::csearch;
use middle::region;
use middle::subst::{mod, Subst};
use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
@ -26,8 +27,6 @@ use middle::ty::{ty_param, Polytype, ty_ptr};
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn};
use middle::ty::{ty_closure};
use middle::subst::Subst;
use middle::ty;
use CrateCtxt;
use middle::infer::combine::Combine;
@ -472,6 +471,17 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
impl_did.node);
let self_type = self_type.ty.subst(tcx, &param_env.free_substs);
// the self-type may have late-bound regions bound in the
// impl; liberate them.
let item_scope = region::CodeExtent::from_node_id(impl_did.node);
let self_type =
ty::liberate_late_bound_regions(tcx,
item_scope,
&ty::bind(self_type)).value;
debug!("can_type_implement_copy(self_type={})",
self_type.repr(tcx));
match ty::can_type_implement_copy(tcx, self_type, &param_env) {
Ok(()) => {}
Err(ty::FieldDoesNotImplementCopy(name)) => {

View File

@ -0,0 +1,38 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that we handle binder levels correctly when checking whether a
// type can implement `Copy`. In particular, we had a bug where we failed to
// liberate the late-bound regions from the impl, and thus wound up
// searching 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
// did not consider that a match (something I would like to revise in
// a later PR).
#![allow(dead_code)]
use std::kinds::marker;
#[deriving(Copy)]
struct Foo<T> { x: T }
type Ty<'tcx> = &'tcx TyS<'tcx>;
enum TyS<'tcx> {
Boop(marker::InvariantLifetime<'tcx>)
}
enum Bar<'tcx> {
Baz(Foo<Ty<'tcx>>)
}
impl<'tcx> Copy for Bar<'tcx> { }
fn main() { }