Skip to content

Commit 7edcec0

Browse files
committed
keep variance for CanonicalUserTypeAnnotation
1 parent 3fb1f68 commit 7edcec0

File tree

10 files changed

+110
-8
lines changed

10 files changed

+110
-8
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1068,15 +1068,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10681068
self.user_type_annotations
10691069
);
10701070
for user_annotation in self.user_type_annotations {
1071-
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
1071+
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty, variance } =
1072+
*user_annotation;
10721073
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
10731074
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
10741075
match annotation {
10751076
UserType::Ty(mut ty) => {
10761077
ty = self.normalize(ty, Locations::All(span));
10771078

1078-
if let Err(terr) = self.eq_types(
1079+
// `ty` and `inferred_ty` are swapped for
1080+
// better diagnostics.
1081+
if let Err(terr) = self.relate_types(
10791082
ty,
1083+
variance.xform(ty::Variance::Contravariant),
10801084
inferred_ty,
10811085
Locations::All(span),
10821086
ConstraintCategory::BoringNoLocation,

compiler/rustc_middle/src/thir.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -552,14 +552,16 @@ impl<'tcx> PatTyProj<'tcx> {
552552
pub fn user_ty(
553553
self,
554554
annotations: &mut CanonicalUserTypeAnnotations<'tcx>,
555-
inferred_ty: Ty<'tcx>,
556555
span: Span,
556+
inferred_ty: Ty<'tcx>,
557+
variance: ty::Variance,
557558
) -> UserTypeProjection {
558559
UserTypeProjection {
559560
base: annotations.push(CanonicalUserTypeAnnotation {
560561
span,
561562
user_ty: self.user_ty,
562563
inferred_ty,
564+
variance,
563565
}),
564566
projs: Vec::new(),
565567
}

compiler/rustc_middle/src/ty/context.rs

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::ty::{
2222
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
2323
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
2424
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
25+
Variance,
2526
};
2627
use rustc_ast as ast;
2728
use rustc_attr as attr;
@@ -833,6 +834,7 @@ pub struct CanonicalUserTypeAnnotation<'tcx> {
833834
pub user_ty: CanonicalUserType<'tcx>,
834835
pub span: Span,
835836
pub inferred_ty: Ty<'tcx>,
837+
pub variance: Variance,
836838
}
837839

838840
/// Canonicalized user type annotation.

compiler/rustc_mir_build/src/build/expr/as_constant.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::build::Builder;
44
use rustc_middle::mir::interpret::{ConstValue, Scalar};
55
use rustc_middle::mir::*;
66
use rustc_middle::thir::*;
7-
use rustc_middle::ty::CanonicalUserTypeAnnotation;
7+
use rustc_middle::ty::{CanonicalUserTypeAnnotation, Variance};
88

99
impl<'a, 'tcx> Builder<'a, 'tcx> {
1010
/// Compile `expr`, yielding a compile-time constant. Assumes that
@@ -22,6 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2222
span,
2323
user_ty,
2424
inferred_ty: ty,
25+
variance: Variance::Invariant,
2526
})
2627
});
2728
assert_eq!(literal.ty(), ty);

compiler/rustc_mir_build/src/build/expr/as_place.rs

+2
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
493493
span: source_info.span,
494494
user_ty,
495495
inferred_ty: expr.ty,
496+
variance: Variance::Invariant,
496497
});
497498

498499
let place = place_builder.clone().into_place(this.tcx, this.typeck_results);
@@ -522,6 +523,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
522523
span: source_info.span,
523524
user_ty,
524525
inferred_ty: expr.ty,
526+
variance: Variance::Invariant,
525527
});
526528
this.cfg.push(
527529
block,

compiler/rustc_mir_build/src/build/expr/into.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_hir as hir;
99
use rustc_index::vec::Idx;
1010
use rustc_middle::mir::*;
1111
use rustc_middle::thir::*;
12-
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
12+
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Variance};
1313
use std::iter;
1414

1515
impl<'a, 'tcx> Builder<'a, 'tcx> {
@@ -364,6 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
364364
span: source_info.span,
365365
user_ty: ty,
366366
inferred_ty,
367+
variance: Variance::Invariant,
367368
})
368369
});
369370
let adt = Box::new(AggregateKind::Adt(

compiler/rustc_mir_build/src/build/matches/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_index::bit_set::BitSet;
1919
use rustc_middle::middle::region;
2020
use rustc_middle::mir::*;
2121
use rustc_middle::thir::{self, *};
22-
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
22+
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance};
2323
use rustc_span::symbol::Symbol;
2424
use rustc_span::{BytePos, Pos, Span};
2525
use rustc_target::abi::VariantIdx;
@@ -538,8 +538,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
538538
let ty_source_info = self.source_info(user_ty_span);
539539
let user_ty = pat_ascription_ty.user_ty(
540540
&mut self.canonical_user_type_annotations,
541-
place.ty(&self.local_decls, self.tcx).ty,
542541
ty_source_info.span,
542+
place.ty(&self.local_decls, self.tcx).ty,
543+
Variance::Invariant,
543544
);
544545
self.cfg.push(
545546
block,
@@ -796,6 +797,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
796797
span: user_ty_span,
797798
user_ty: user_ty.user_ty,
798799
inferred_ty: subpattern.ty,
800+
variance: Variance::Invariant,
799801
};
800802
let projection = UserTypeProjection {
801803
base: self.canonical_user_type_annotations.push(annotation),
@@ -2076,8 +2078,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20762078

20772079
let user_ty = ascription.user_ty.user_ty(
20782080
&mut self.canonical_user_type_annotations,
2079-
ascription.source.ty(&self.local_decls, self.tcx).ty,
20802081
source_info.span,
2082+
ascription.source.ty(&self.local_decls, self.tcx).ty,
2083+
ascription.variance,
20812084
);
20822085
self.cfg.push(
20832086
block,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Check that incorrect higher ranked subtyping
2+
// causes an error.
3+
struct Inv<'a>(fn(&'a ()) -> &'a ());
4+
fn hr_subtype<'c>(f: for<'a, 'b> fn(Inv<'a>, Inv<'a>)) {
5+
// ok
6+
let _: for<'a> fn(Inv<'a>, Inv<'a>) = f;
7+
let sub: for<'a> fn(Inv<'a>, Inv<'a>) = f;
8+
// no
9+
let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub;
10+
//~^ ERROR mismatched types
11+
}
12+
13+
fn simple1<'c>(x: (&'c i32,)) {
14+
let _x: (&'static i32,) = x;
15+
//~^ ERROR mismatched types
16+
}
17+
18+
fn simple2<'c>(x: (&'c i32,)) {
19+
let _: (&'static i32,) = x;
20+
//~^ ERROR mismatched types
21+
}
22+
23+
fn main() {
24+
hr_subtype(|_, _| {});
25+
simple1((&3,));
26+
simple2((&3,));
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/placeholder-pattern-fail.rs:8:47
3+
|
4+
LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub;
5+
| ^^^ one type is more general than the other
6+
|
7+
= note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)`
8+
found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)`
9+
10+
error[E0308]: mismatched types
11+
--> $DIR/placeholder-pattern-fail.rs:13:31
12+
|
13+
LL | let _x: (&'static i32,) = x;
14+
| ^ lifetime mismatch
15+
|
16+
= note: expected tuple `(&'static i32,)`
17+
found tuple `(&'c i32,)`
18+
note: the lifetime `'c` as defined here...
19+
--> $DIR/placeholder-pattern-fail.rs:12:12
20+
|
21+
LL | fn simple1<'c>(x: (&'c i32,)) {
22+
| ^^
23+
= note: ...does not necessarily outlive the static lifetime
24+
25+
error[E0308]: mismatched types
26+
--> $DIR/placeholder-pattern-fail.rs:18:30
27+
|
28+
LL | let _: (&'static i32,) = x;
29+
| ^ lifetime mismatch
30+
|
31+
= note: expected tuple `(&'static i32,)`
32+
found tuple `(&'c i32,)`
33+
note: the lifetime `'c` as defined here...
34+
--> $DIR/placeholder-pattern-fail.rs:17:12
35+
|
36+
LL | fn simple2<'c>(x: (&'c i32,)) {
37+
| ^^
38+
= note: ...does not necessarily outlive the static lifetime
39+
40+
error: aborting due to 3 previous errors
41+
42+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
// Check that higher ranked subtyping correctly works when using
3+
// placeholder patterns.
4+
fn hr_subtype<'c>(f: for<'a, 'b> fn(&'a (), &'b ())) {
5+
let _: for<'a> fn(&'a (), &'a ()) = f;
6+
let _: for<'a, 'b> fn(&'a (), &'b ()) = f;
7+
let _: for<'a> fn(&'a (), &'c ()) = f;
8+
let _: fn(&'c (), &'c ()) = f;
9+
}
10+
11+
fn simple<'c>(x: (&'static i32,)) {
12+
let _: (&'c i32,) = x;
13+
}
14+
15+
fn main() {
16+
hr_subtype(|_, _| {});
17+
simple((&3,));
18+
}

0 commit comments

Comments
 (0)