diff --git a/src/librustc/middle/typeck/check/method/probe.rs b/src/librustc/middle/typeck/check/method/probe.rs index affbb2ebc1f26..b2ef9356c4786 100644 --- a/src/librustc/middle/typeck/check/method/probe.rs +++ b/src/librustc/middle/typeck/check/method/probe.rs @@ -816,6 +816,32 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { method.fty.sig.inputs[0].repr(self.tcx()), substs.repr(self.tcx())); + // It is possible for type parameters or early-bound lifetimes + // to appear in the signature of `self`. The substitutions we + // are given do not include type/lifetime parameters for the + // method yet. So create fresh variables here for those too, + // if there are any. + assert_eq!(substs.types.len(subst::FnSpace), 0); + assert_eq!(substs.regions().len(subst::FnSpace), 0); + let mut substs = substs; + let placeholder; + if + !method.generics.types.is_empty_in(subst::FnSpace) || + !method.generics.regions.is_empty_in(subst::FnSpace) + { + let method_types = + self.infcx().next_ty_vars( + method.generics.types.len(subst::FnSpace)); + + let method_regions = + self.infcx().region_vars_for_defs( + self.span, + method.generics.regions.get_slice(subst::FnSpace)); + + placeholder = (*substs).clone().with_method(method_types, method_regions); + substs = &placeholder; + } + let xform_self_ty = method.fty.sig.inputs[0].subst(self.tcx(), substs); self.infcx().replace_late_bound_regions_with_fresh_var(method.fty.sig.binder_id, self.span, diff --git a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs new file mode 100644 index 0000000000000..25ce0d774ebc1 --- /dev/null +++ b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs @@ -0,0 +1,34 @@ +// Copyright 2012 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. + +// Check that we successfully handle methods where the `self` type has +// an early-bound lifetime. Issue #18208. + +#![allow(dead_code)] + +struct Cursor<'a>; + +trait CursorNavigator { + fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; +} + +struct SimpleNavigator; + +impl CursorNavigator for SimpleNavigator { + fn init_cursor<'a, 'b: 'a>(&'a self, _cursor: &mut Cursor<'b>) -> bool { + false + } +} + +fn main() { + let mut c = Cursor; + let n = SimpleNavigator; + n.init_cursor(&mut c); +}