diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 8809abdd70e62..4ca426cc783b6 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -322,7 +322,17 @@ pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, // anyhow). let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID); - fulfill_cx.register_builtin_bound(infcx, ty, bound, cause); + // Relax region constraints that result from trait selection by + // inserting an inference variable. This mimics the behavior + // of method confirmation where fresh inference variables are + // substituted into the method self type, which is then unified + // with the adjusted receiver type and handed to trait selection. + let relax_ty = infcx.next_ty_var(); + try!(infcx.sub_types(false, infer::Misc(span), ty, relax_ty).map_err(|_| Unimplemented)); + let relax_ty = infcx.resolve_type_vars_if_possible(&relax_ty); + debug!("relax_ty: {}", relax_ty.repr(infcx.tcx)); + + fulfill_cx.register_builtin_bound(infcx, relax_ty, bound, cause); // Note: we only assume something is `Copy` if we can // *definitively* show that it implements `Copy`. Otherwise, diff --git a/src/test/run-pass/traits-issue-24085.rs b/src/test/run-pass/traits-issue-24085.rs new file mode 100644 index 0000000000000..78bd378ba0add --- /dev/null +++ b/src/test/run-pass/traits-issue-24085.rs @@ -0,0 +1,29 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that trait selection for Copy does not introduce +// bad region constraints. Issue #24085. + +#[derive(Clone, Copy)] +enum Path<'a:'b, 'b> { + Data(&'a i32), + Link(&'a i32, &'b Path<'a, 'b>) +} + +fn foo<'a,'b,F>(_p: Path<'a, 'b>, _f: F) + where F: for<'c> FnMut(&Path<'a, 'c>) { +} + +fn main() { + let y = 0; + let p = Path::Data(&y); + + foo(p, |x| {*x;}); +}