Skip to content

Commit 692d942

Browse files
committed
rollup merge of #21107: nikomatsakis/assoc-type-ice-hunt-take-1
Fixes for #20831 and #21010 r? @nick29581
2 parents d7009e6 + 2479dfc commit 692d942

File tree

9 files changed

+226
-108
lines changed

9 files changed

+226
-108
lines changed

src/librustc/middle/ty.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2605,12 +2605,17 @@ impl FlagComputation {
26052605

26062606
&ty_projection(ref data) => {
26072607
self.add_flags(HAS_PROJECTION);
2608-
self.add_substs(data.trait_ref.substs);
2608+
self.add_projection_ty(data);
26092609
}
26102610

26112611
&ty_trait(box TyTrait { ref principal, ref bounds }) => {
26122612
let mut computation = FlagComputation::new();
26132613
computation.add_substs(principal.0.substs);
2614+
for projection_bound in bounds.projection_bounds.iter() {
2615+
let mut proj_computation = FlagComputation::new();
2616+
proj_computation.add_projection_predicate(&projection_bound.0);
2617+
computation.add_bound_computation(&proj_computation);
2618+
}
26142619
self.add_bound_computation(&computation);
26152620

26162621
self.add_bounds(bounds);
@@ -2674,6 +2679,15 @@ impl FlagComputation {
26742679
}
26752680
}
26762681

2682+
fn add_projection_predicate(&mut self, projection_predicate: &ProjectionPredicate) {
2683+
self.add_projection_ty(&projection_predicate.projection_ty);
2684+
self.add_ty(projection_predicate.ty);
2685+
}
2686+
2687+
fn add_projection_ty(&mut self, projection_ty: &ProjectionTy) {
2688+
self.add_substs(projection_ty.trait_ref.substs);
2689+
}
2690+
26772691
fn add_substs(&mut self, substs: &Substs) {
26782692
self.add_tys(substs.types.as_slice());
26792693
match substs.regions {

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1430,7 +1430,7 @@ impl<'tcx> UserString<'tcx> for ty::ProjectionPredicate<'tcx> {
14301430
impl<'tcx> Repr<'tcx> for ty::ProjectionTy<'tcx> {
14311431
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
14321432
format!("<{} as {}>::{}",
1433-
self.trait_ref.self_ty().repr(tcx),
1433+
self.trait_ref.substs.self_ty().repr(tcx),
14341434
self.trait_ref.repr(tcx),
14351435
self.item_name.repr(tcx))
14361436
}

src/librustc_trans/trans/common.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,15 @@ pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>,
217217
ty::type_contents(cx, ty).needs_drop(cx)
218218
}
219219

220-
fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
221-
ty: Ty<'tcx>) -> bool {
220+
fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
222221
match ty.sty {
223222
ty::ty_struct(def_id, substs) => {
224-
let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
225-
fields.len() == 1 && type_is_immediate(ccx, fields[0].mt.ty)
223+
let fields = ty::lookup_struct_fields(ccx.tcx(), def_id);
224+
fields.len() == 1 && {
225+
let ty = ty::lookup_field_type(ccx.tcx(), def_id, fields[0].id, substs);
226+
let ty = monomorphize::normalize_associated_type(ccx.tcx(), &ty);
227+
type_is_immediate(ccx, ty)
228+
}
226229
}
227230
_ => false
228231
}

src/librustc_trans/trans/debuginfo.rs

Lines changed: 22 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -323,28 +323,26 @@ impl<'tcx> TypeMap<'tcx> {
323323
fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
324324
type_: Ty<'tcx>) -> UniqueTypeId {
325325

326-
// basic type -> {:name of the type:}
327-
// tuple -> {tuple_(:param-uid:)*}
328-
// struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
329-
// enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
330-
// enum variant -> {variant_:variant-name:_:enum-uid:}
331-
// reference (&) -> {& :pointee-uid:}
332-
// mut reference (&mut) -> {&mut :pointee-uid:}
333-
// ptr (*) -> {* :pointee-uid:}
334-
// mut ptr (*mut) -> {*mut :pointee-uid:}
335-
// unique ptr (~) -> {~ :pointee-uid:}
336-
// @-ptr (@) -> {@ :pointee-uid:}
337-
// sized vec ([T; x]) -> {[:size:] :element-uid:}
338-
// unsized vec ([T]) -> {[] :element-uid:}
339-
// trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
340-
// closure -> {<unsafe_> <once_> :store-sigil:
341-
// |(:param-uid:),* <,_...>| -> \
342-
// :return-type-uid: : (:bounds:)*}
343-
// function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
344-
// :return-type-uid:}
345-
// unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
346-
// gc box -> {GC_BOX<:pointee-uid:>}
347-
// projection (<T as U>::V) -> {<:ty-uid: as :trait-uid:> :: :name-uid: }
326+
// basic type -> {:name of the type:}
327+
// tuple -> {tuple_(:param-uid:)*}
328+
// struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
329+
// enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
330+
// enum variant -> {variant_:variant-name:_:enum-uid:}
331+
// reference (&) -> {& :pointee-uid:}
332+
// mut reference (&mut) -> {&mut :pointee-uid:}
333+
// ptr (*) -> {* :pointee-uid:}
334+
// mut ptr (*mut) -> {*mut :pointee-uid:}
335+
// unique ptr (~) -> {~ :pointee-uid:}
336+
// @-ptr (@) -> {@ :pointee-uid:}
337+
// sized vec ([T; x]) -> {[:size:] :element-uid:}
338+
// unsized vec ([T]) -> {[] :element-uid:}
339+
// trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
340+
// closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
341+
// :return-type-uid: : (:bounds:)*}
342+
// function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
343+
// :return-type-uid:}
344+
// unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
345+
// gc box -> {GC_BOX<:pointee-uid:>}
348346

349347
match self.type_to_unique_id.get(&type_).cloned() {
350348
Some(unique_type_id) => return unique_type_id,
@@ -437,25 +435,6 @@ impl<'tcx> TypeMap<'tcx> {
437435
principal.substs,
438436
&mut unique_type_id);
439437
},
440-
ty::ty_projection(ref projection) => {
441-
unique_type_id.push_str("<");
442-
443-
let self_ty = projection.trait_ref.self_ty();
444-
let self_type_id = self.get_unique_type_id_of_type(cx, self_ty);
445-
let self_type_id = self.get_unique_type_id_as_string(self_type_id);
446-
unique_type_id.push_str(&self_type_id[]);
447-
448-
unique_type_id.push_str(" as ");
449-
450-
from_def_id_and_substs(self,
451-
cx,
452-
projection.trait_ref.def_id,
453-
projection.trait_ref.substs,
454-
&mut unique_type_id);
455-
456-
unique_type_id.push_str(">::");
457-
unique_type_id.push_str(token::get_name(projection.item_name).get());
458-
},
459438
ty::ty_bare_fn(_, &ty::BareFnTy{ unsafety, abi, ref sig } ) => {
460439
if unsafety == ast::Unsafety::Unsafe {
461440
unique_type_id.push_str("unsafe ");
@@ -499,10 +478,7 @@ impl<'tcx> TypeMap<'tcx> {
499478
closure_ty,
500479
&mut unique_type_id);
501480
},
502-
ty::ty_err |
503-
ty::ty_infer(_) |
504-
ty::ty_open(_) |
505-
ty::ty_param(_) => {
481+
_ => {
506482
cx.sess().bug(&format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
507483
&ppaux::ty_to_string(cx.tcx(), type_)[],
508484
type_.sty)[])
@@ -3880,22 +3856,10 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
38803856
ty::ty_unboxed_closure(..) => {
38813857
output.push_str("closure");
38823858
}
3883-
ty::ty_projection(ref projection) => {
3884-
output.push_str("<");
3885-
let self_ty = projection.trait_ref.self_ty();
3886-
push_debuginfo_type_name(cx, self_ty, true, output);
3887-
3888-
output.push_str(" as ");
3889-
3890-
push_item_name(cx, projection.trait_ref.def_id, false, output);
3891-
push_type_params(cx, projection.trait_ref.substs, output);
3892-
3893-
output.push_str(">::");
3894-
output.push_str(token::get_name(projection.item_name).get());
3895-
}
38963859
ty::ty_err |
38973860
ty::ty_infer(_) |
38983861
ty::ty_open(_) |
3862+
ty::ty_projection(..) |
38993863
ty::ty_param(_) => {
39003864
cx.sess().bug(&format!("debuginfo: Trying to create type name for \
39013865
unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t))[]);

src/librustc_typeck/astconv.rs

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,15 @@ pub fn instantiate_poly_trait_ref<'tcx>(
516516
{
517517
let mut projections = Vec::new();
518518

519+
// the trait reference introduces a binding level here, so
520+
// we need to shift the `rscope`. It'd be nice if we could
521+
// do away with this rscope stuff and work this knowledge
522+
// into resolve_lifetimes, as we do with non-omitted
523+
// lifetimes. Oh well, not there yet.
524+
let shifted_rscope = ShiftedRscope::new(rscope);
525+
519526
let trait_ref =
520-
instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref,
527+
instantiate_trait_ref(this, &shifted_rscope, &ast_trait_ref.trait_ref,
521528
self_ty, Some(&mut projections));
522529

523530
for projection in projections.into_iter() {
@@ -561,6 +568,29 @@ pub fn instantiate_trait_ref<'tcx>(
561568
}
562569
}
563570

571+
fn object_path_to_poly_trait_ref<'a,'tcx>(
572+
this: &AstConv<'tcx>,
573+
rscope: &RegionScope,
574+
trait_def_id: ast::DefId,
575+
path: &ast::Path,
576+
mut projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
577+
-> ty::PolyTraitRef<'tcx>
578+
{
579+
// we are introducing a binder here, so shift the
580+
// anonymous regions depth to account for that
581+
let shifted_rscope = ShiftedRscope::new(rscope);
582+
583+
let mut tmp = Vec::new();
584+
let trait_ref = ty::Binder(ast_path_to_trait_ref(this,
585+
&shifted_rscope,
586+
trait_def_id,
587+
None,
588+
path,
589+
Some(&mut tmp)));
590+
projections.extend(tmp.into_iter().map(ty::Binder));
591+
trait_ref
592+
}
593+
564594
fn ast_path_to_trait_ref<'a,'tcx>(
565595
this: &AstConv<'tcx>,
566596
rscope: &RegionScope,
@@ -573,13 +603,6 @@ fn ast_path_to_trait_ref<'a,'tcx>(
573603
debug!("ast_path_to_trait_ref {:?}", path);
574604
let trait_def = this.get_trait_def(trait_def_id);
575605

576-
// the trait reference introduces a binding level here, so
577-
// we need to shift the `rscope`. It'd be nice if we could
578-
// do away with this rscope stuff and work this knowledge
579-
// into resolve_lifetimes, as we do with non-omitted
580-
// lifetimes. Oh well, not there yet.
581-
let shifted_rscope = ShiftedRscope::new(rscope);
582-
583606
let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
584607
ast::AngleBracketedParameters(ref data) => {
585608
// For now, require that parenthetical notation be used
@@ -595,7 +618,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
595618
the crate attributes to enable");
596619
}
597620

598-
convert_angle_bracketed_parameters(this, &shifted_rscope, data)
621+
convert_angle_bracketed_parameters(this, rscope, data)
599622
}
600623
ast::ParenthesizedParameters(ref data) => {
601624
// For now, require that parenthetical notation be used
@@ -616,7 +639,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
616639
};
617640

618641
let substs = create_substs_for_ast_path(this,
619-
&shifted_rscope,
642+
rscope,
620643
path.span,
621644
&trait_def.generics,
622645
self_ty,
@@ -851,15 +874,11 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
851874
match this.tcx().def_map.borrow().get(&id) {
852875
Some(&def::DefTrait(trait_def_id)) => {
853876
let mut projection_bounds = Vec::new();
854-
let trait_ref = ty::Binder(ast_path_to_trait_ref(this,
855-
rscope,
856-
trait_def_id,
857-
None,
858-
path,
859-
Some(&mut projection_bounds)));
860-
let projection_bounds = projection_bounds.into_iter()
861-
.map(ty::Binder)
862-
.collect();
877+
let trait_ref = object_path_to_poly_trait_ref(this,
878+
rscope,
879+
trait_def_id,
880+
path,
881+
&mut projection_bounds);
863882
Ok((trait_ref, projection_bounds))
864883
}
865884
_ => {
@@ -1098,16 +1117,13 @@ pub fn ast_ty_to_ty<'tcx>(
10981117
// N.B. this case overlaps somewhat with
10991118
// TyObjectSum, see that fn for details
11001119
let mut projection_bounds = Vec::new();
1101-
let trait_ref = ast_path_to_trait_ref(this,
1102-
rscope,
1103-
trait_def_id,
1104-
None,
1105-
path,
1106-
Some(&mut projection_bounds));
1107-
let trait_ref = ty::Binder(trait_ref);
1108-
let projection_bounds = projection_bounds.into_iter()
1109-
.map(ty::Binder)
1110-
.collect();
1120+
1121+
let trait_ref = object_path_to_poly_trait_ref(this,
1122+
rscope,
1123+
trait_def_id,
1124+
path,
1125+
&mut projection_bounds);
1126+
11111127
trait_ref_to_object_type(this, rscope, path.span,
11121128
trait_ref, projection_bounds, &[])
11131129
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
// Regression test for #20831: debruijn index account was thrown off
12+
// by the (anonymous) lifetime in `<Self as Publisher>::Output`
13+
// below. Note that changing to a named lifetime made the problem go
14+
// away.
15+
16+
use std::ops::{Shl, Shr};
17+
use std::cell::RefCell;
18+
19+
pub trait Subscriber {
20+
type Input;
21+
}
22+
23+
pub trait Publisher<'a> {
24+
type Output;
25+
fn subscribe(&mut self, Box<Subscriber<Input=Self::Output> + 'a>);
26+
}
27+
28+
pub trait Processor<'a> : Subscriber + Publisher<'a> { }
29+
30+
impl<'a, P> Processor<'a> for P where P : Subscriber + Publisher<'a> { }
31+
32+
struct MyStruct<'a> {
33+
sub: Box<Subscriber<Input=u64> + 'a>
34+
}
35+
36+
impl<'a> Publisher<'a> for MyStruct<'a> {
37+
type Output = u64;
38+
fn subscribe(&mut self, t : Box<Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
39+
// Not obvious, but there is an implicit lifetime here -------^
40+
//~^^ ERROR cannot infer
41+
//
42+
// The fact that `Publisher` is using an implicit lifetime is
43+
// what was causing the debruijn accounting to be off, so
44+
// leave it that way!
45+
self.sub = t;
46+
}
47+
}
48+
49+
fn main() {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
// Regression test for issue #21010: Normalize associated types in
12+
// various special paths in the `type_is_immediate` function.
13+
14+
#![allow(unstable)]
15+
16+
pub trait OffsetState: Sized {}
17+
pub trait Offset { type State: OffsetState; }
18+
19+
#[derive(Copy)] pub struct X;
20+
impl Offset for X { type State = Y; }
21+
22+
#[derive(Copy)] pub struct Y;
23+
impl OffsetState for Y {}
24+
25+
pub fn now() -> DateTime<X> { from_utc(Y) }
26+
27+
pub struct DateTime<Off: Offset> { pub offset: Off::State }
28+
pub fn from_utc<Off: Offset>(offset: Off::State) -> DateTime<Off> { DateTime { offset: offset } }
29+
30+
pub fn main() {
31+
let _x = now();
32+
}

0 commit comments

Comments
 (0)