about summary refs log tree commit diff
path: root/compiler/rustc_infer
AgeCommit message (Collapse)AuthorLines
2024-03-07improve debug loggingLukas Markeffsky-1/+1
2024-03-06Auto merge of #121679 - lcnr:opaque-wf-check-2, r=oli-obkbors-1/+18
stricter hidden type wf-check [based on #115008] Original work by `@aliemjay` in #115008. A huge thanks to them for originally figuring out this approach :heart: Fixes https://github.com/rust-lang/rust/issues/114728 Fixes https://github.com/rust-lang/rust/issues/114572 Instead of adding the `WellFormed` obligations when relating opaque types, we now always emit such an obligation when defining the hidden type. This causes nested opaque types which aren't wf to error, see the comment below for the described impact. I believe this change to be desirable as it significantly reduces complexity by removing special-cases. It also caused an issue with RPITIT: in defaulted trait methods, we add a `Projection(synthetic_assoc, rpit_of_trait_method)` clause to the `param_env`. This clause is not added to the `ParamEnv` of the nested coroutines. This caused a normalization failure in `fn check_coroutine_obligations` with the new solver. I fixed that by using the env of the typeck root instead. r? `@oli-obk`
2024-03-06Auto merge of #122045 - matthiaskrgr:rollup-5l3vpn7, r=matthiaskrgrbors-2/+13
Rollup of 9 pull requests Successful merges: - #121065 (Add basic i18n guidance for `Display`) - #121744 (Stop using Bubble in coherence and instead emulate it with an intercrate check) - #121829 (Dummy tweaks (attempt 2)) - #121857 (Implement async closure signature deduction) - #121894 (const_eval_select: make it safe but be careful with what we expose on stable for now) - #122014 (Change some attributes to only_local.) - #122016 (will_wake tests fail on Miri and that is expected) - #122018 (only set noalias on Box with the global allocator) - #122028 (Remove some dead code) r? `@ghost` `@rustbot` modify labels: rollup
2024-03-05Use `ControlFlow` in HIR visitorsJason Newcomb-94/+85
2024-03-05Convert `TypeVisitor` and `DefIdVisitor` to use `VisitorResult`Jason Newcomb-50/+23
2024-03-05Stop using Bubble in coherence and instead emulate it with an intercrate checkOli Scherer-2/+13
2024-03-05Rename `SubdiagnosticMessageOp` as `SubdiagMessageOp`.Nicholas Nethercote-14/+12
2024-03-05Rename `DiagnosticMessage` as `DiagMessage`.Nicholas Nethercote-5/+5
2024-03-03Remove unused fluent messagesr0cky-8/+0
2024-03-02Auto merge of #121864 - compiler-errors:type-relating-variances, r=aliemjaybors-1/+21
Don't grab variances in `TypeRelating` relation if we're invariant Since `Invariant.xform(var) = Invariant` always, so just copy what the generalizer relation does. Fixes #110106
2024-03-01Rollup merge of #121497 - lcnr:coherence-suggest-increasing-recursion-limit, ↵Matthias Krüger-6/+10
r=compiler-errors `-Znext-solver=coherence`: suggest increasing recursion limit r? `@compiler-errors`
2024-03-01Rollup merge of #121153 - chenyukang:yukang-fix-105431-type-mismatch, r=estebankMatthias Krüger-0/+97
Suggest removing superfluous semicolon when statements used as expression Fixes #105431 - it's not a pure recursive visitor, so I guess there may be some more complex scenarios not covered. - moved `consider_removing_semicolon` to `compiler/rustc_infer` for reusing this helper function.
2024-03-01Don't grab variances if we're invariantMichael Goulet-1/+21
2024-03-01Rollup merge of #121416 - veera-sivarajan:bugfix-120785, r=nnethercoteMatthias Krüger-4/+17
Improve error messages for generics with default parameters Fixes #120785 Issue: Previously, all type parameters with default types were deliberately ignored to simplify error messages. For example, an error message for Box type would display `Box<T>` instead of `Box<T, _>`. But, this resulted in unclear error message when a concrete type was used instead of the default type. Fix: This PR fixes it by checking if a concrete type is specified after a default type to display the entire type name or the simplified type name.
2024-03-01Rebase fallout from TypeRelating::binders, inline higher_ranked_subMichael Goulet-66/+51
2024-03-01Fallout from removing a_is_expectedMichael Goulet-62/+18
2024-03-01Remove a_is_expected from combine relationsMichael Goulet-127/+71
2024-03-01Get rid of some sub_exp and eq_expMichael Goulet-9/+9
2024-03-01Remove causeMichael Goulet-24/+2
2024-03-01Combine sub and eqMichael Goulet-485/+350
2024-03-01Preserve variance on error in generalizerMichael Goulet-2/+2
2024-02-29Auto merge of #118247 - spastorino:type-equality-subtyping, r=lcnrbors-6/+29
change equate for binders to not rely on subtyping *summary by `@spastorino` and `@lcnr*` ### Context The following code: ```rust type One = for<'a> fn(&'a (), &'a ()); type Two = for<'a, 'b> fn(&'a (), &'b ()); mod my_api { use std::any::Any; use std::marker::PhantomData; pub struct Foo<T: 'static> { a: &'static dyn Any, _p: PhantomData<*mut T>, // invariant, the type of the `dyn Any` } impl<T: 'static> Foo<T> { pub fn deref(&self) -> &'static T { match self.a.downcast_ref::<T>() { None => unsafe { std::hint::unreachable_unchecked() }, Some(a) => a, } } pub fn new(a: T) -> Foo<T> { Foo::<T> { a: Box::leak(Box::new(a)), _p: PhantomData, } } } } use my_api::*; fn main() { let foo = Foo::<One>::new((|_, _| ()) as One); foo.deref(); let foo: Foo<Two> = foo; foo.deref(); } ``` has UB from hitting the `unreachable_unchecked`. This happens because `TypeId::of::<One>()` is not the same as `TypeId::of::<Two>()` despite them being considered the same types by the type checker. Currently the type checker considers binders to be equal if subtyping succeeds in both directions: `for<'a> T<'a> eq for<'b> U<'b>` holds if `for<'a> exists<'b> T<'b> <: T'<a> AND for<'b> exists<'a> T<'a> <: T<'b>` holds. This results in `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` being equal in the type system. `TypeId` is computed by looking at the *structure* of a type. Even though these types are semantically equal, they have a different *structure* resulting in them having different `TypeId`. This can break invariants of unsafe code at runtime and is unsound when happening at compile time, e.g. when using const generics. So as seen in `main`, we can assign a value of type `Foo::<One>` to a binding of type `Foo<Two>` given those are considered the same type but then when we call `deref`, it calls `downcast_ref` that relies on `TypeId` and we would hit the `None` arm as these have different `TypeId`s. As stated in https://github.com/rust-lang/rust/issues/97156#issuecomment-1879030033, this causes the API of existing crates to be unsound. ## What should we do about this The same type resulting in different `TypeId`s is a significant footgun, breaking a very reasonable assumptions by authors of unsafe code. It will also be unsound by itself once they are usable in generic contexts with const generics. There are two options going forward here: - change how the *structure* of a type is computed before relying on it. i.e. continue considering `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` to be equal, but normalize them to a common representation so that their `TypeId` are also the same. - change how the semantic equality of binders to match the way we compute the structure of types. i.e. `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` still have different `TypeId`s but are now also considered to not be semantically equal. --- Advantages of the first approach: - with the second approach some higher ranked types stop being equal, even though they are subtypes of each other General thoughts: - changing the approach in the future will be breaking - going from first to second may break ordinary type checking, as types which were previously equal are now distinct - going from second to first may break coherence, because previously disjoint impls overlap as the used types are now equal - both of these are quite unlikely. This PR did not result in any crater failures, so this should not matter too much Advantages of the second approach: - the soundness of the first approach requires more non-local reasoning. We have to make sure that changes to subtyping do not cause the representative computation to diverge from semantic equality - e.g. we intend to consider higher ranked implied bounds when subtyping to [fix] https://github.com/rust-lang/rust/issues/25860, I don't know how this will interact and don't feel confident making any prediction here. - computing a representative type is non-trivial and soundness critical, therefore adding complexity to the "core type system" --- This PR goes with the second approach. A crater run did not result in any regressions. I am personally very hesitant about trying the first approach due to the above reasons. It feels like there are more unknowns when going that route. ### Changing the way we equate binders Relating bound variables from different depths already results in a universe error in equate. We therefore only need to make sure that there is 1-to-1 correspondence between bound variables when relating binders. This results in concrete types being structurally equal after anonymizing their bound variables. We implement this by instantiating one of the binder with placeholders and the other with inference variables and then equating the instantiated types. We do so in both directions. More formally, we change the typing rules as follows: ``` for<'r0, .., 'rn> exists<'l0, .., 'ln> LHS<'l0, .., 'ln> <: RHS<'r0, .., 'rn> for<'l0, .., 'ln> exists<'r0, .., 'rn> RHS<'r0, .., 'rn> <: LHS<'l0, .., 'ln> -------------------------------------------------------------------------- for<'l0, .., 'ln> LHS<'l0, .., 'ln> eq for<'r0, .., 'rn> RHS<'r0, .., 'rn> ``` to ``` for<'r0, .., 'rn> exists<'l0, .., 'ln> LHS<'l0, .., 'ln> eq RHS<'r0, .., 'rn> for<'l0, .., 'ln> exists<'r0, .., 'rn> RHS<'r0, .., 'rn> eq LHS<'l0, .., 'ln> -------------------------------------------------------------------------- for<'l0, .., 'ln> LHS<'l0, .., 'ln> eq for<'r0, .., 'rn> RHS<'r0, .., 'rn> ``` --- Fixes #97156 r? `@lcnr`
2024-02-29Change condition in binders to one that is more readableSantiago Pastorino-5/+5
2024-02-29Make infer higher ranked equate use bidirectional subtyping in invariant contextSantiago Pastorino-2/+25
2024-02-29Rollup merge of #121669 - nnethercote:count-stashed-errs-again, r=estebankGuillaume Gomez-16/+0
Count stashed errors again Stashed diagnostics are such a pain. Their "might be emitted, might not" semantics messes with lots of things. #120828 and #121206 made some big changes to how they work, improving some things, but still leaving some problems, as seen by the issues caused by #121206. This PR aims to fix all of them by restricting them in a way that eliminates the "might be emitted, might not" semantics while still allowing 98% of their benefit. Details in the individual commit logs. r? `@oli-obk`
2024-02-29distinguish recursion limit based overflow for diagnosticslcnr-6/+10
also change the number of allowed fixpoint steps to be fixed instead of using the `log` of the total recursion depth.
2024-02-29renaming test casesyukang-6/+6
2024-02-28Improve error messages for generics with default parametersVeera-4/+17
Fixes #120785
2024-02-29Suggest removing superfluous semicolos when statements used as expressionsyukang-0/+97
2024-02-29Overhaul how stashed diagnostics work, again.Nicholas Nethercote-16/+0
Stashed errors used to be counted as errors, but could then be cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed that, closing the soundness hole. But it introduced other difficulties because you sometimes have to account for pending stashed errors when making decisions about whether errors have occured/will occur and it's easy to overlook these. This commit aims for a middle ground. - Stashed errors (not warnings) are counted immediately as emitted errors, avoiding the possibility of forgetting to consider them. - The ability to cancel (or downgrade) stashed errors is eliminated, by disallowing the use of `steal_diagnostic` with errors, and introducing the more restrictive methods `try_steal_{modify,replace}_and_emit_err` that can be used instead. Other things: - `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both return `Option<ErrorGuaranteed>`, which enables the removal of two `delayed_bug` calls and one `Ty::new_error_with_message` call. This is possible because we store error guarantees in `DiagCtxt::stashed_diagnostics`. - Storing the guarantees also saves us having to maintain a counter. - Calls to the `stashed_err_count` method are no longer necessary alongside calls to `has_errors`, which is a nice simplification, and eliminates two more `span_delayed_bug` calls and one FIXME comment. - Tests are added for three of the four fixed PRs mentioned below. - `issue-121108.rs`'s output improved slightly, omitting a non-useful error message. Fixes #121451. Fixes #121477. Fixes #121504. Fixes #121508.
2024-02-29Rollup merge of #121743 - compiler-errors:opportunistically-resolve-regions, ↵Matthias Krüger-1/+9
r=jackh726 Opportunistically resolve regions when processing region outlives obligations Due to the matching in `TypeOutlives` being structural, we should attempt to opportunistically resolve regions before processing region obligations. Thanks ``@lcnr`` for finding this. r? lcnr
2024-02-28Opportunistically resolve regions when processing region outlives obligationsMichael Goulet-1/+9
2024-02-28Rename `DiagnosticStyledString` as `DiagStyledString`.Nicholas Nethercote-42/+35
2024-02-28Rename `DiagnosticArg{,Map,Name,Value}` as `DiagArg{,Map,Name,Value}`.Nicholas Nethercote-11/+11
2024-02-28Rename `DiagnosticBuilder` as `Diag`.Nicholas Nethercote-103/+86
Much better! Note that this involves renaming (and updating the value of) `DIAGNOSTIC_BUILDER` in clippy.
2024-02-27when defining opaques, require the hidden type to be well-formedlcnr-1/+18
2024-02-27Avoid a `span_delayed_bug` in `TypeErrCtxt::report_region_errors`.Nicholas Nethercote-31/+31
By returning error guarantees from a few functions it relies on.
2024-02-26always emit `AliasRelate` goals when relating aliaseslcnr-31/+151
Add `StructurallyRelateAliases` to allow instantiating infer vars with rigid aliases. Change `instantiate_query_response` to be infallible in the new solver. This requires canonicalization to not hide any information used by the query, so weaken universe compression. It also modifies `term_is_fully_unconstrained` to allow region inference variables in a higher universe.
2024-02-24Auto merge of #121549 - matthiaskrgr:rollup-1hvu3lb, r=matthiaskrgrbors-0/+8
Rollup of 7 pull requests Successful merges: - #121435 (Account for RPITIT in E0310 explicit lifetime constraint suggestion) - #121490 (Rustdoc: include crate name in links for local primitives) - #121520 (delay cloning of iterator items) - #121522 (check that simd_insert/extract indices are in-bounds) - #121531 (Ignore less tests in debug builds) - #121539 (compiler/rustc_target/src/spec/base/apple/tests.rs: Avoid unnecessary large move) - #121542 (update stdarch) r? `@ghost` `@rustbot` modify labels: rollup
2024-02-24Rollup merge of #121435 - estebank:rpitit-static-119773, r=compiler-errorsMatthias Krüger-0/+8
Account for RPITIT in E0310 explicit lifetime constraint suggestion When given ```rust trait Original { fn f() -> impl Fn(); } trait Erased { fn f(&self) -> Box<dyn Fn()>; } impl<T: Original> Erased for T { fn f(&self) -> Box<dyn Fn()> { Box::new(<T as Original>::f()) } } ``` emit do not emit an invalid suggestion restricting the `Trait::{opaque}` type in a `where` clause: ``` error[E0310]: the associated type `<T as Original>::{opaque#0}` may not live long enough --> $DIR/missing-static-bound-from-impl.rs:11:9 | LL | Box::new(<T as Original>::f()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the associated type `<T as Original>::{opaque#0}` must be valid for the static lifetime... | ...so that the type `impl Fn()` will meet its required lifetime bounds ``` Partially address #119773. Ideally we'd suggest modifying `Erased::f` instead. r? `@compiler-errors`
2024-02-23compiler: clippy::complexity fixesMatthias Krüger-1/+1
2024-02-23Auto merge of #121491 - matthiaskrgr:rollup-wkzqawy, r=matthiaskrgrbors-18/+24
Rollup of 8 pull requests Successful merges: - #121434 (Fix #121208 fallout) - #121471 (When encountering `<&T as Clone>::clone(x)` because `T: Clone`, suggest `#[derive(Clone)]`) - #121476 (remove `llvm.assertions=true` in compiler profile) - #121479 (fix generalizer unsoundness) - #121480 (Fix more #121208 fallout) - #121482 (Allow for a missing `adt_def` in `NamePrivacyVisitor`.) - #121484 (coverage: Use variable name `this` in `CoverageGraph::from_mir`) - #121487 (Explicitly call `emit_stashed_diagnostics`.) r? `@ghost` `@rustbot` modify labels: rollup
2024-02-23Auto merge of #121442 - lcnr:region-var-universe-uwu, r=compiler-errorsbors-52/+85
region unification: update universe of region vars necessary for #119106. see inline comment for why this is necessary r? `@compiler-errors` `@BoxyUwU`
2024-02-23Rollup merge of #121479 - lcnr:fix-generalize, r=compiler-errorsMatthias Krüger-18/+24
fix generalizer unsoundness I ended up getting confused while trying to flip the variances when flipping the order. Should be all right now. This is only exploitable when generalizing if the `ambient_variance` of the relation is `Contravariant`. This can currently only be the case in the NLL generalizer which only rarely generalizes, causing us to miss this regression. Very much an issue with #121462 however.
2024-02-22fix CIlcnr-2/+2
2024-02-22woops, soundly generalizing is hardlcnr-18/+24
I ended up getting confused while trying to flip the variances when flipping the order. Should be all right now
2024-02-22Account for RPITIT in E0310 explicit lifetime constraint suggestionEsteban Küber-0/+8
When given ```rust trait Original { fn f() -> impl Fn(); } trait Erased { fn f(&self) -> Box<dyn Fn()>; } impl<T: Original> Erased for T { fn f(&self) -> Box<dyn Fn()> { Box::new(<T as Original>::f()) } } ``` avoid suggestion to restrict the `Trait::{opaque}` type in a `where` clause: ``` error[E0310]: the associated type `<T as Original>::{opaque#0}` may not live long enough --> $DIR/missing-static-bound-from-impl.rs:11:9 | LL | Box::new(<T as Original>::f()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the associated type `<T as Original>::{opaque#0}` must be valid for the static lifetime... | ...so that the type `impl Fn()` will meet its required lifetime bounds ``` CC #119773.
2024-02-22region unification update universe of region varslcnr-52/+85
2024-02-22freshen: resolve root varslcnr-67/+69
Without doing so we use the same candidate cache entry for `?0: Trait<?1>` and `?0: Trait<?0>`. These goals are different and we must not use the same entry for them.
2024-02-22remove `sub_relations` from infcx, recompute in diagnosticslcnr-144/+115
we don't track them when canonicalizing or when freshening, resulting in instable caching in the old solver, and issues when instantiating query responses in the new one.