-
Notifications
You must be signed in to change notification settings - Fork 13.4k
fix let _: ty = expr
subtyping error
#93856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3fb1f68
7edcec0
be012c7
5ee4525
c7f5216
c3a91a8
368caf8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -365,7 +365,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { | |
if let Some(annotation_index) = constant.user_ty { | ||
if let Err(terr) = self.cx.relate_type_and_user_type( | ||
constant.literal.ty(), | ||
ty::Variance::Invariant, | ||
&UserTypeProjection { base: annotation_index, projs: vec![] }, | ||
location.to_locations(), | ||
ConstraintCategory::Boring, | ||
|
@@ -425,6 +424,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { | |
ConstraintCategory::Boring, | ||
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( | ||
constant.literal.ty(), | ||
ty::Variance::Invariant, | ||
uv.def.did, | ||
UserSubsts { substs: uv.substs, user_self_ty: None }, | ||
)), | ||
|
@@ -492,7 +492,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { | |
|
||
if let Err(terr) = self.cx.relate_type_and_user_type( | ||
ty, | ||
ty::Variance::Invariant, | ||
user_ty, | ||
Locations::All(*span), | ||
ConstraintCategory::TypeAnnotation, | ||
|
@@ -1068,15 +1067,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | |
self.user_type_annotations | ||
); | ||
for user_annotation in self.user_type_annotations { | ||
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; | ||
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty, variance } = | ||
*user_annotation; | ||
let inferred_ty = self.normalize(inferred_ty, Locations::All(span)); | ||
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty); | ||
match annotation { | ||
UserType::Ty(mut ty) => { | ||
ty = self.normalize(ty, Locations::All(span)); | ||
|
||
if let Err(terr) = self.eq_types( | ||
// `ty` and `inferred_ty` are swapped for | ||
// better diagnostics. | ||
if let Err(terr) = self.relate_types( | ||
lcnr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ty, | ||
variance.xform(ty::Variance::Contravariant), | ||
inferred_ty, | ||
Locations::All(span), | ||
ConstraintCategory::BoringNoLocation, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm trying to remember why we chose to use "type equality" here. I have a vague memory that there was a reason, but it seems there aren't any failing tests, at least. |
||
|
@@ -1104,6 +1107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | |
ConstraintCategory::BoringNoLocation, | ||
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( | ||
inferred_ty, | ||
variance, | ||
def_id, | ||
user_substs, | ||
)), | ||
|
@@ -1174,7 +1178,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | |
fn relate_type_and_user_type( | ||
&mut self, | ||
a: Ty<'tcx>, | ||
v: ty::Variance, | ||
user_ty: &UserTypeProjection, | ||
locations: Locations, | ||
category: ConstraintCategory, | ||
|
@@ -1202,7 +1205,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | |
); | ||
|
||
let ty = curr_projected_ty.ty; | ||
self.relate_types(ty, v.xform(ty::Variance::Contravariant), a, locations, category)?; | ||
self.relate_types(ty, ty::Variance::Invariant, a, locations, category)?; | ||
|
||
Ok(()) | ||
} | ||
|
@@ -1397,7 +1400,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | |
if let Some(annotation_index) = self.rvalue_user_ty(rv) { | ||
if let Err(terr) = self.relate_type_and_user_type( | ||
rv_ty, | ||
ty::Variance::Invariant, | ||
&UserTypeProjection { base: annotation_index, projs: vec![] }, | ||
location.to_locations(), | ||
ConstraintCategory::Boring, | ||
|
@@ -1449,11 +1451,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | |
); | ||
}; | ||
} | ||
StatementKind::AscribeUserType(box (ref place, ref projection), variance) => { | ||
StatementKind::AscribeUserType(box (ref place, ref projection)) => { | ||
let place_ty = place.ty(body, tcx).ty; | ||
if let Err(terr) = self.relate_type_and_user_type( | ||
place_ty, | ||
variance, | ||
projection, | ||
Locations::All(stmt.source_info.span), | ||
ConstraintCategory::TypeAnnotation, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ use crate::ty::{ | |
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, | ||
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, | ||
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, | ||
Variance, | ||
}; | ||
use rustc_ast as ast; | ||
use rustc_attr as attr; | ||
|
@@ -833,6 +834,13 @@ pub struct CanonicalUserTypeAnnotation<'tcx> { | |
pub user_ty: CanonicalUserType<'tcx>, | ||
pub span: Span, | ||
pub inferred_ty: Ty<'tcx>, | ||
/// The variance relation inferred type and the user type. | ||
/// | ||
/// If this is covariant, then `inferred_ty` has to be a subtype of `user_ty`. | ||
/// | ||
/// As the variance is already applied from `user_ty` to `inferred_ty`, all | ||
/// other uses of `inferred_ty` should be invariant. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to have a comment explaining: let x: T = ...; // invariant
let _: T = ...; // covariant |
||
pub variance: Variance, | ||
nikomatsakis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/// Canonicalized user type annotation. | ||
|
Uh oh!
There was an error while loading. Please reload this page.