Rollup merge of #117416 - compiler-errors:tait-in-bad-body, r=oli-obk

Also consider TAIT to be uncomputable if the MIR body is tainted

Not totally sure if this is the best solution. We could, alternatively, look at the hir typeck results and try to take a type from there instead of just falling back to type error, inferring `u8` instead of `{type error}`. Not certain it really matters, though.

Happy to iterate on this.

Fixes #117413

r? ``@oli-obk`` cc ``@Nadrieril``
This commit is contained in:
Matthias Krüger 2023-10-31 12:55:09 +01:00 committed by GitHub
commit 8daa317a4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 3 deletions

View File

@ -183,9 +183,17 @@ fn check(&mut self, item_def_id: LocalDefId) {
};
// Use borrowck to get the type with unerased regions.
let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types;
debug!(?concrete_opaque_types);
if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) {
let borrowck_results = &self.tcx.mir_borrowck(item_def_id);
// If the body was tainted, then assume the opaque may have been constrained and just set it to error.
if let Some(guar) = borrowck_results.tainted_by_errors {
self.found =
Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) });
return;
}
debug!(?borrowck_results.concrete_opaque_types);
if let Some(&concrete_type) = borrowck_results.concrete_opaque_types.get(&self.def_id) {
debug!(?concrete_type, "found constraint");
if let Some(prev) = &mut self.found {
if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {

View File

@ -0,0 +1,14 @@
#![feature(type_alias_impl_trait)]
type Tait = impl Copy;
// Make sure that this TAIT isn't considered unconstrained...
fn empty_opaque() -> Tait {
if false {
match empty_opaque() {}
//~^ ERROR non-empty
}
0u8
}
fn main() {}

View File

@ -0,0 +1,17 @@
error[E0004]: non-exhaustive patterns: type `Tait` is non-empty
--> $DIR/unconstrained-due-to-bad-pattern.rs:8:15
|
LL | match empty_opaque() {}
| ^^^^^^^^^^^^^^
|
= note: the matched value is of type `Tait`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match empty_opaque() {
LL + _ => todo!(),
LL + }
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0004`.