Skip to content

Commit 911bf89

Browse files
authored
Rollup merge of #71801 - matthewjasper:operator-subtyping, r=varkor
Correctly check comparison operator in MIR typeck The subtyping for comparisons between pointers was reversed in MIR typeck. There also wasn't a check that comparisons between numeric types had matching types.
2 parents ccc123a + 9e19f3a commit 911bf89

File tree

3 files changed

+50
-44
lines changed

3 files changed

+50
-44
lines changed

src/librustc_mir/borrow_check/type_check/mod.rs

+45-27
Original file line numberDiff line numberDiff line change
@@ -2290,36 +2290,54 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22902290
right,
22912291
) => {
22922292
let ty_left = left.ty(body, tcx);
2293-
if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.kind {
2294-
let ty_right = right.ty(body, tcx);
2295-
let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
2296-
kind: TypeVariableOriginKind::MiscVariable,
2297-
span: body.source_info(location).span,
2298-
});
2299-
self.sub_types(
2300-
common_ty,
2301-
ty_left,
2302-
location.to_locations(),
2303-
ConstraintCategory::Boring,
2304-
)
2305-
.unwrap_or_else(|err| {
2306-
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
2307-
});
2308-
if let Err(terr) = self.sub_types(
2309-
common_ty,
2310-
ty_right,
2311-
location.to_locations(),
2312-
ConstraintCategory::Boring,
2313-
) {
2314-
span_mirbug!(
2315-
self,
2316-
rvalue,
2317-
"unexpected comparison types {:?} and {:?} yields {:?}",
2293+
match ty_left.kind {
2294+
// Types with regions are comparable if they have a common super-type.
2295+
ty::RawPtr(_) | ty::FnPtr(_) => {
2296+
let ty_right = right.ty(body, tcx);
2297+
let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
2298+
kind: TypeVariableOriginKind::MiscVariable,
2299+
span: body.source_info(location).span,
2300+
});
2301+
self.relate_types(
2302+
common_ty,
2303+
ty::Variance::Contravariant,
23182304
ty_left,
2319-
ty_right,
2320-
terr
2305+
location.to_locations(),
2306+
ConstraintCategory::Boring,
23212307
)
2308+
.unwrap_or_else(|err| {
2309+
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
2310+
});
2311+
if let Err(terr) = self.relate_types(
2312+
common_ty,
2313+
ty::Variance::Contravariant,
2314+
ty_right,
2315+
location.to_locations(),
2316+
ConstraintCategory::Boring,
2317+
) {
2318+
span_mirbug!(
2319+
self,
2320+
rvalue,
2321+
"unexpected comparison types {:?} and {:?} yields {:?}",
2322+
ty_left,
2323+
ty_right,
2324+
terr
2325+
)
2326+
}
23222327
}
2328+
// For types with no regions we can just check that the
2329+
// both operands have the same type.
2330+
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_)
2331+
if ty_left == right.ty(body, tcx) => {}
2332+
// Other types are compared by trait methods, not by
2333+
// `Rvalue::BinaryOp`.
2334+
_ => span_mirbug!(
2335+
self,
2336+
rvalue,
2337+
"unexpected comparison types {:?} and {:?}",
2338+
ty_left,
2339+
right.ty(body, tcx)
2340+
),
23232341
}
23242342
}
23252343

src/test/ui/nll/type-check-pointer-comparisons.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
2121
}
2222

2323
fn compare_hr_fn_ptr<'a>(f: fn(&'a i32), g: fn(&i32)) {
24-
f == g;
25-
//~^ ERROR higher-ranked subtype error
24+
// Ideally this should compile with the operands swapped as well, but HIR
25+
// type checking prevents it (and stops compilation) for now.
26+
f == g; // OK
2627
}
2728

2829
fn compare_const_fn_ptr<'a>(f: *const fn(&'a i32), g: *const fn(&i32)) {
29-
f == g;
30-
//~^ ERROR higher-ranked subtype error
30+
f == g; // OK
3131
}
3232

3333
fn main() {}

src/test/ui/nll/type-check-pointer-comparisons.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,5 @@ LL | f == g;
7676

7777
help: `'a` and `'b` must be the same: replace one with the other
7878

79-
error: higher-ranked subtype error
80-
--> $DIR/type-check-pointer-comparisons.rs:24:5
81-
|
82-
LL | f == g;
83-
| ^^^^^^
84-
85-
error: higher-ranked subtype error
86-
--> $DIR/type-check-pointer-comparisons.rs:29:5
87-
|
88-
LL | f == g;
89-
| ^^^^^^
90-
91-
error: aborting due to 8 previous errors
79+
error: aborting due to 6 previous errors
9280

0 commit comments

Comments
 (0)