Auto merge of #141292 - matthiaskrgr:rollup-9nhhk7k, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #139419 (Error on recursive opaque ty in HIR typeck)
 - #141236 (Resolved issue with mismatched types triggering ICE in certain scenarios)
 - #141253 (Warning added when dependency crate has async drop types, and the feature is disabled)
 - #141269 (rustc-dev-guide subtree update)
 - #141275 (`gather_locals`: only visit guard pattern guards when checking the guard)
 - #141279 (`lower_to_hir` cleanups)
 - #141285 (Add tick to `RePlaceholder` debug output)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-05-20 15:48:56 +00:00
commit 444a62712a
40 changed files with 279 additions and 303 deletions

View File

@ -70,24 +70,13 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
}
}
pub(super) fn lower_node(&mut self, def_id: LocalDefId) -> hir::MaybeOwner<'hir> {
pub(super) fn lower_node(&mut self, def_id: LocalDefId) {
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
if let hir::MaybeOwner::Phantom = owner {
let node = self.ast_index[def_id];
match node {
AstOwner::NonOwner => {}
AstOwner::Crate(c) => self.lower_crate(c),
AstOwner::Item(item) => self.lower_item(item),
AstOwner::AssocItem(item, ctxt) => self.lower_assoc_item(item, ctxt),
AstOwner::ForeignItem(item) => self.lower_foreign_item(item),
}
}
self.owners[def_id]
}
#[instrument(level = "debug", skip(self, c))]
fn lower_crate(&mut self, c: &Crate) {
AstOwner::Crate(c) => {
debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
self.with_lctx(CRATE_NODE_ID, |lctx| {
let module = lctx.lower_mod(&c.items, &c.spans);
@ -96,18 +85,17 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
hir::OwnerNode::Crate(module)
})
}
#[instrument(level = "debug", skip(self))]
fn lower_item(&mut self, item: &Item) {
AstOwner::Item(item) => {
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
}
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
AstOwner::AssocItem(item, ctxt) => {
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
}
fn lower_foreign_item(&mut self, item: &ForeignItem) {
self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
}),
}
}
}
}

View File

@ -444,14 +444,14 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
tcx.definitions_untracked().def_index_count(),
);
for def_id in ast_index.indices() {
item::ItemLowerer {
let mut lowerer = item::ItemLowerer {
tcx,
resolver: &mut resolver,
ast_index: &ast_index,
owners: &mut owners,
}
.lower_node(def_id);
};
for def_id in ast_index.indices() {
lowerer.lower_node(def_id);
}
drop(ast_index);

View File

@ -84,7 +84,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.annotate_expected_due_to_let_ty(err, expr, error);
self.annotate_loop_expected_due_to_inference(err, expr, error);
if self.annotate_mut_binding_to_immutable_binding(err, expr, error) {
if self.annotate_mut_binding_to_immutable_binding(err, expr, expr_ty, expected, error) {
return;
}
@ -799,17 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Detect the following case
///
/// ```text
/// fn change_object(mut a: &Ty) {
/// fn change_object(mut b: &Ty) {
/// let a = Ty::new();
/// b = a;
/// }
/// ```
///
/// where the user likely meant to modify the value behind there reference, use `a` as an out
/// where the user likely meant to modify the value behind there reference, use `b` as an out
/// parameter, instead of mutating the local binding. When encountering this we suggest:
///
/// ```text
/// fn change_object(a: &'_ mut Ty) {
/// fn change_object(b: &'_ mut Ty) {
/// let a = Ty::new();
/// *b = a;
/// }
@ -818,13 +818,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>,
expected: Ty<'tcx>,
error: Option<TypeError<'tcx>>,
) -> bool {
if let Some(TypeError::Sorts(ExpectedFound { expected, found })) = error
if let Some(TypeError::Sorts(ExpectedFound { .. })) = error
&& let ty::Ref(_, inner, hir::Mutability::Not) = expected.kind()
// The difference between the expected and found values is one level of borrowing.
&& self.can_eq(self.param_env, *inner, found)
&& self.can_eq(self.param_env, *inner, expr_ty)
// We have an `ident = expr;` assignment.
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =

View File

@ -218,7 +218,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
);
}
let old_outermost_fn_param_pat = self.outermost_fn_param_pat.take();
if let PatKind::Guard(subpat, _) = p.kind {
// We'll visit the guard when checking it. Don't gather its locals twice.
self.visit_pat(subpat);
} else {
intravisit::walk_pat(self, p);
}
self.outermost_fn_param_pat = old_outermost_fn_param_pat;
}

View File

@ -9,17 +9,21 @@
//! which creates a new `TypeckResults` which doesn't contain any inference variables.
use std::mem;
use std::ops::ControlFlow;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::ExtendUnord;
use rustc_errors::ErrorGuaranteed;
use rustc_errors::{E0720, ErrorGuaranteed};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_infer::traits::solve::Goal;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::{
self, DefiningScopeKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt, fold_regions,
self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
fold_regions,
};
use rustc_span::{Span, sym};
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
@ -595,6 +599,35 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
entry.span = prev.span.substitute_dummy(hidden_type.span);
}
}
let recursive_opaques: Vec<_> = self
.typeck_results
.concrete_opaque_types
.iter()
.filter(|&(&def_id, hidden_ty)| {
hidden_ty
.ty
.visit_with(&mut HasRecursiveOpaque {
def_id,
seen: Default::default(),
opaques: &self.typeck_results.concrete_opaque_types,
tcx,
})
.is_break()
})
.map(|(def_id, hidden_ty)| (*def_id, hidden_ty.span))
.collect();
for (def_id, span) in recursive_opaques {
let guar = self
.fcx
.dcx()
.struct_span_err(span, "cannot resolve opaque type")
.with_code(E0720)
.emit();
self.typeck_results
.concrete_opaque_types
.insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
}
}
fn visit_field_id(&mut self, hir_id: HirId) {
@ -959,3 +992,34 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
self.tcx.try_normalize_erasing_regions(self.typing_env, ct).unwrap_or(ct)
}
}
struct HasRecursiveOpaque<'a, 'tcx> {
def_id: LocalDefId,
seen: FxHashSet<LocalDefId>,
opaques: &'a FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
tcx: TyCtxt<'tcx>,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRecursiveOpaque<'_, 'tcx> {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Opaque, alias_ty) = *t.kind()
&& let Some(def_id) = alias_ty.def_id.as_local()
{
if self.def_id == def_id {
return ControlFlow::Break(());
}
if self.seen.insert(def_id)
&& let Some(hidden_ty) = self.opaques.get(&def_id)
{
ty::EarlyBinder::bind(hidden_ty.ty)
.instantiate(self.tcx, alias_ty.args)
.visit_with(self)?;
}
}
t.super_visit_with(self)
}
}

View File

@ -2,7 +2,7 @@ metadata_as_needed_compatibility =
linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
metadata_async_drop_types_in_dependency =
found async drop types in dependecy `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
.help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
metadata_bad_panic_strategy =

View File

@ -1,6 +1,5 @@
use std::fmt;
use std::iter::once;
use std::ops::ControlFlow;
use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx};
use rustc_arena::DroplessArena;
@ -12,8 +11,7 @@ use rustc_middle::mir::{self, Const};
use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, VariantDef,
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
@ -137,22 +135,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
/// Returns the hidden type corresponding to this key if the body under analysis is allowed to
/// know it.
fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
if let Some(hidden_ty) = self.typeck_results.concrete_opaque_types.get(&key.def_id) {
let ty = ty::EarlyBinder::bind(hidden_ty.ty).instantiate(self.tcx, key.args);
if ty.visit_with(&mut RecursiveOpaque { def_id: key.def_id.into() }).is_continue() {
Some(ty)
} else {
// HACK: We skip revealing opaque types which recursively expand
// to themselves. This is because we may infer hidden types like
// `Opaque<T> = Opaque<Opaque<T>>` or `Opaque<T> = Opaque<(T,)>`
// in hir typeck.
None
self.typeck_results
.concrete_opaque_types
.get(&key.def_id)
.map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
}
} else {
None
}
}
// This can take a non-revealed `Ty` because it reveals opaques itself.
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
!ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
@ -1177,20 +1164,3 @@ fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
}
Ok(())
}
struct RecursiveOpaque {
def_id: DefId,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for RecursiveOpaque {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Opaque, alias_ty) = t.kind() {
if alias_ty.def_id == self.def_id {
return ControlFlow::Break(());
}
}
if t.has_opaque_types() { t.super_visit_with(self) } else { ControlFlow::Continue(()) }
}
}

View File

@ -193,7 +193,7 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
ReVar(vid) => write!(f, "{vid:?}"),
RePlaceholder(placeholder) => write!(f, "{placeholder:?}"),
RePlaceholder(placeholder) => write!(f, "'{placeholder:?}"),
// Use `'{erased}` as the output instead of `'erased` so that its more obviously distinct from
// a `ReEarlyParam` named `'erased`. Technically that would print as `'erased/#IDX` so this is

View File

@ -1 +1 @@
414482f6a0d4e7290f614300581a0b55442552a3
e42bbfe1f7c26f8760a99c4b1f27d33aba1040bb

View File

@ -134,9 +134,9 @@
- [Command-line arguments](./cli.md)
- [rustc_driver and rustc_interface](./rustc-driver/intro.md)
- [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md)
- [Example: Type checking](./rustc-driver/interacting-with-the-ast.md)
- [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md)
- [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md)
- [Errors and lints](diagnostics.md)
- [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
- [Translation](./diagnostics/translation.md)

View File

@ -28,8 +28,8 @@ format is specific to `rustc`, and may change over time. This file contains:
[`-C embed-bitcode=no`][embed-bitcode] CLI option to improve compile times
and reduce disk space if LTO is not needed.
* `rustc` [metadata], in a file named `lib.rmeta`.
* A symbol table, which is generally a list of symbols with offsets to the
object file that contain that symbol. This is pretty standard for archive
* A symbol table, which is essentially a list of symbols with offsets to the
object files that contain that symbol. This is pretty standard for archive
files.
[archive file]: https://en.wikipedia.org/wiki/Ar_(Unix)
@ -46,12 +46,11 @@ A `dylib` is a platform-specific shared library. It includes the `rustc`
### rmeta
An `rmeta` file is custom binary format that contains the [metadata] for the
crate. This file can be used for fast "checks" of a project by skipping all
code generation (as is done with `cargo check`), collecting enough information
for documentation (as is done with `cargo doc`), or for
[pipelining](#pipelining). This file is created if the
[`--emit=metadata`][emit] CLI option is used.
An `rmeta` file is a custom binary format that contains the [metadata] for the
crate. This file can be used for fast "checks" of a project by skipping all code
generation (as is done with `cargo check`), collecting enough information for
documentation (as is done with `cargo doc`), or for [pipelining](#pipelining).
This file is created if the [`--emit=metadata`][emit] CLI option is used.
`rmeta` files do not support linking, since they do not contain compiled
object files.
@ -60,8 +59,8 @@ object files.
## Metadata
The metadata contains a wide swath of different elements. This guide will not
go into detail of every field it contains. You are encouraged to browse the
The metadata contains a wide swath of different elements. This guide will not go
into detail about every field it contains. You are encouraged to browse the
[`CrateRoot`] definition to get a sense of the different elements it contains.
Everything about metadata encoding and decoding is in the [`rustc_metadata`]
package.
@ -122,9 +121,9 @@ much more.
By default, all Rust symbols are mangled and incorporate the stable crate id.
This allows multiple versions of the same crate to be included together. Cargo
automatically generates `-C metadata` hashes based on a variety of factors,
like the package version, source, and the target kind (a lib and test can have
the same crate name, so they need to be disambiguated).
automatically generates `-C metadata` hashes based on a variety of factors, like
the package version, source, and target kind (a lib and test can have the same
crate name, so they need to be disambiguated).
[`StableCrateId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.StableCrateId.html
[`StableCrateId::new`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.StableCrateId.html#method.new
@ -154,7 +153,7 @@ will also look at the [sysroot] to find dependencies.
As crates are loaded, they are kept in the [`CStore`] with the crate metadata
wrapped in the [`CrateMetadata`] struct. After resolution and expansion, the
`CStore` will make its way into the [`GlobalCtxt`] for the rest of
`CStore` will make its way into the [`GlobalCtxt`] for the rest of the
compilation.
[name resolution]: ../name-resolution.md

View File

@ -28,6 +28,6 @@ adding a new command-line argument.
unstable-options` flag.
[cli-docs]: https://doc.rust-lang.org/rustc/command-line-arguments.html
[forge guide for new options]: https://forge.rust-lang.org/compiler/new_option.html
[forge guide for new options]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#compiler-flags
[unstable book]: https://doc.rust-lang.org/nightly/unstable-book/
[`parse_bool`]: https://github.com/rust-lang/rust/blob/e5335592e78354e33d798d20c04bcd677c1df62d/src/librustc_session/options.rs#L307-L313

View File

@ -89,7 +89,7 @@ filtering the search to areas you're interested in. For example:
Not all important or beginner work has issue labels.
See below for how to find work that isn't labelled.
[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+
[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked:pr+
[Triage]: ./contributing.md#issue-triage
### Recurring work

View File

@ -7,8 +7,8 @@ It acts as the glue for running the various phases of the compiler in the correc
using the interface defined in the [`rustc_interface`] crate. Where possible, using [`rustc_driver`] rather than [`rustc_interface`] is recommended.
The main entry point of [`rustc_driver`] is [`rustc_driver::run_compiler`][rd_rc].
This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`][cb] and a couple of other optional options.
[`Callbacks`][cb] is a `trait` that allows for custom compiler configuration,
This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`] and a couple of other optional options.
[`Callbacks`] is a `trait` that allows for custom compiler configuration,
as well as allowing custom code to run after different phases of the compilation.
## `rustc_interface`
@ -33,14 +33,8 @@ specifically [`rustc_driver_impl::run_compiler`][rdi_rc]
[`Compiler`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html
[`rustc_driver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/
[`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html
[`Session`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html
[`SourceMap`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html
[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html
[Appendix A]: appendix/stupid-stats.html
[cb]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html
[`Callbacks`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html
[example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-interface-example.rs
[i_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/fn.run_compiler.html
[rd_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.run_compiler.html
[rdi_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver_impl/fn.run_compiler.html
[stupid-stats]: https://github.com/nrc/stupid-stats
[`nightly-rustc`]: https://doc.rust-lang.org/nightly/nightly-rustc/

View File

@ -1,9 +0,0 @@
//@ known-bug: #140823
struct Container<T> {
data: T,
}
fn ice(callback: Box<dyn Fn(Container<&u8>)>) {
let fails: Box<dyn Fn(&Container<&u8>)> = callback;
}

View File

@ -5,7 +5,7 @@
//@ edition:2021
#![cfg_attr(with_feature, feature(async_drop))]
//[without_feature]~^ WARN found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
//[without_feature]~^ WARN found async drop types in dependency `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
#![allow(incomplete_features)]

View File

@ -1,4 +1,4 @@
warning: found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
warning: found async drop types in dependency `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
--> $DIR/dependency-dropped.rs:7:1
|
LL | #![cfg_attr(with_feature, feature(async_drop))]

View File

@ -0,0 +1,26 @@
//! Functions with a mismatch between the expected and found type where the difference is a
//! reference may trigger analysis for additional help. In this test the expected type will be
//! &'a Container<&'a u8> and the found type will be Container<&'?0 u8>.
//!
//! This test exercises a scenario where the found type being analyzed contains an inference region
//! variable ('?0). This cannot be used in comparisons because the variable no longer exists by the
//! time the later analysis is performed.
//!
//! This is a regression test of #140823
trait MyFn<P> {}
struct Container<T> {
data: T,
}
struct Desugared {
callback: Box<dyn for<'a> MyFn<&'a Container<&'a u8>>>,
}
fn test(callback: Box<dyn for<'a> MyFn<Container<&'a u8>>>) -> Desugared {
Desugared { callback }
//~^ ERROR mismatched types
}
fn main() {}

View File

@ -0,0 +1,12 @@
error[E0308]: mismatched types
--> $DIR/coerce-suggestion-infer-region.rs:22:17
|
LL | Desugared { callback }
| ^^^^^^^^ expected `Box<dyn MyFn<&Container<&u8>>>`, found `Box<dyn MyFn<Container<&u8>>>`
|
= note: expected struct `Box<(dyn for<'a> MyFn<&'a Container<&'a u8>> + 'static)>`
found struct `Box<(dyn for<'a> MyFn<Container<&'a u8>> + 'static)>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,3 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/issue-100075-2.rs:1:23
|
LL | fn opaque<T>(t: T) -> impl Sized {
| ^^^^^^^^^^
warning: function cannot return without recursing
--> $DIR/issue-100075-2.rs:1:1
|
@ -10,15 +16,6 @@ LL | opaque(Some(t))
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
error[E0720]: cannot resolve opaque type
--> $DIR/issue-100075-2.rs:1:23
|
LL | fn opaque<T>(t: T) -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | opaque(Some(t))
| --------------- returning here with type `impl Sized`
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0720`.

View File

@ -2,10 +2,7 @@ error[E0720]: cannot resolve opaque type
--> $DIR/issue-100075.rs:13:37
|
LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
| ^^^^^^^^^^^ recursive opaque type
...
LL | return _g(t);
| ----- returning here with type `&impl Marker`
| ^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -1,9 +1,8 @@
//@ check-pass
trait T {}
fn wrap(x: impl T) -> impl T {
//~^ WARN function cannot return without recursing
//~^ ERROR cannot resolve opaque type
//~| WARN function cannot return without recursing
wrap(wrap(x))
}

View File

@ -1,14 +1,21 @@
error[E0720]: cannot resolve opaque type
--> $DIR/issue-103599.rs:3:23
|
LL | fn wrap(x: impl T) -> impl T {
| ^^^^^^
warning: function cannot return without recursing
--> $DIR/issue-103599.rs:5:1
--> $DIR/issue-103599.rs:3:1
|
LL | fn wrap(x: impl T) -> impl T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL |
...
LL | wrap(wrap(x))
| ------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
warning: 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0720`.

View File

@ -3,8 +3,8 @@ fn bar() -> impl Fn() {
}
fn foo() -> impl Fn() {
//~^ WARNING 5:1: 5:22: function cannot return without recursing [unconditional_recursion]
//~| ERROR 5:13: 5:22: cannot resolve opaque type [E0720]
//~^ WARN function cannot return without recursing
//~| ERROR cannot resolve opaque type
wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
}

View File

@ -1,3 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/issue-87450.rs:5:13
|
LL | fn foo() -> impl Fn() {
| ^^^^^^^^^
warning: function cannot return without recursing
--> $DIR/issue-87450.rs:5:1
|
@ -10,18 +16,6 @@ LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
error[E0720]: cannot resolve opaque type
--> $DIR/issue-87450.rs:5:13
|
LL | fn foo() -> impl Fn() {
| ^^^^^^^^^ recursive opaque type
...
LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
| ----------------------------------------------- returning here with type `impl Fn()`
...
LL | fn wrap(f: impl Fn()) -> impl Fn() {
| --------- returning this opaque type `impl Fn()`
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0720`.

View File

@ -2,112 +2,67 @@ error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:6:22
|
LL | fn option(i: i32) -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | if i < 0 { None } else { Some((option(i - 1), i)) }
| ---- ------------------------ returning here with type `Option<(impl Sized, i32)>`
| |
| returning here with type `Option<(impl Sized, i32)>`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:11:15
|
LL | fn tuple() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | (tuple(),)
| ---------- returning here with type `(impl Sized,)`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:16:15
|
LL | fn array() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | [array()]
| --------- returning here with type `[impl Sized; 1]`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:21:13
|
LL | fn ptr() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | &ptr() as *const _
| ------------------ returning here with type `*const impl Sized`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:26:16
|
LL | fn fn_ptr() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | fn_ptr as fn() -> _
| ------------------- returning here with type `fn() -> impl Sized`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:31:25
|
LL | fn closure_capture() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | / move || {
LL | | x;
| | - closure captures itself here
LL | | }
| |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:34:5: 34:12}`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:39:29
|
LL | fn closure_ref_capture() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | / move || {
LL | | &x;
| | - closure captures itself here
LL | | }
| |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:42:5: 42:12}`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:47:21
|
LL | fn closure_sig() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | || closure_sig()
| ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:49:5: 49:7}`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:52:23
|
LL | fn coroutine_sig() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | || coroutine_sig()
| ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7}`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:57:27
|
LL | fn coroutine_capture() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | / move || {
LL | | yield;
LL | | x;
| | - coroutine captures itself here
LL | | }
| |_____- returning here with type `{coroutine@$DIR/recursive-impl-trait-type-indirect.rs:62:5: 62:12}`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:68:35
|
LL | fn substs_change<T: 'static>() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | (substs_change::<&T>(),)
| ------------------------ returning here with type `(impl Sized,)`
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:78:26

View File

@ -1,56 +1,21 @@
warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:17:1
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:17:22
|
LL | fn build<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL |
LL | let (x,) = (build(x),);
| -------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:27:1
|
LL | fn build2<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
LL | let (x,) = (build2(x),);
| --------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
| ^^^^^^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:27:23
|
LL | fn build2<T>(x: T) -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | (build2(x),)
| ------------ returning here with type `(impl Sized,)`
| ^^^^^^^^^^
warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:40:1
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:39:23
|
LL | fn build3<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL |
LL | let (x,) = (build3((x,)),);
| ------------ recursive call site
|
= help: a `loop` may express intention better if this is on purpose
| ^^^^^^^^^^
error[E0792]: expected generic type parameter, found `(T,)`
--> $DIR/recursive-in-exhaustiveness.rs:49:5
|
LL | fn build3<T>(x: T) -> impl Sized {
| - this generic parameter must be used with a generic type parameter
...
LL | build3(x)
| ^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors; 3 warnings emitted
Some errors have detailed explanations: E0720, E0792.
For more information about an error, try `rustc --explain E0720`.
For more information about this error, try `rustc --explain E0720`.

View File

@ -5,19 +5,19 @@ LL | let (x,) = (build(x),);
| ^^^^^^^^ cannot satisfy `impl Sized == _`
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:31:6
--> $DIR/recursive-in-exhaustiveness.rs:30:6
|
LL | (build2(x),)
| ^^^^^^^^^ types differ
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:31:5
--> $DIR/recursive-in-exhaustiveness.rs:30:5
|
LL | (build2(x),)
| ^^^^^^^^^^^^ types differ
error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
--> $DIR/recursive-in-exhaustiveness.rs:31:5
--> $DIR/recursive-in-exhaustiveness.rs:30:5
|
LL | (build2(x),)
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -26,13 +26,13 @@ LL | (build2(x),)
= note: tuples must have a statically known size to be initialized
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:41:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:41:16
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -41,7 +41,7 @@ LL | let (x,) = (build3((x,)),);
= note: tuples must have a statically known size to be initialized
error[E0308]: mismatched types
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:41:16
|
LL | fn build3<T>(x: T) -> impl Sized {
| ---------- the found opaque type
@ -53,7 +53,7 @@ LL | let (x,) = (build3((x,)),);
found tuple `(impl Sized,)`
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:41:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
@ -61,13 +61,13 @@ LL | let (x,) = (build3((x,)),);
= note: the return type of a function must have a statically known size
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:41:16
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^^^^ types differ
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:41:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ

View File

@ -15,7 +15,7 @@
// We unfortunately accept this today, and due to how opaque type relating is implemented
// in the NLL type relation, this defines `Opaque<T> = T`.
fn build<T>(x: T) -> impl Sized {
//[current]~^ WARN function cannot return without recursing
//[current]~^ ERROR cannot resolve opaque type
let (x,) = (build(x),);
//[next]~^ ERROR type annotations needed
build(x)
@ -26,7 +26,6 @@ fn build<T>(x: T) -> impl Sized {
// Not allowed today. Detected as recursive.
fn build2<T>(x: T) -> impl Sized {
//[current]~^ ERROR cannot resolve opaque type
//[current]~| WARN function cannot return without recursing
let (x,) = (build2(x),);
(build2(x),)
//[next]~^ ERROR type mismatch resolving
@ -38,7 +37,7 @@ fn build2<T>(x: T) -> impl Sized {
//
// Not allowed today. Detected as not defining.
fn build3<T>(x: T) -> impl Sized {
//[current]~^ WARN function cannot return without recursing
//[current]~^ ERROR cannot resolve opaque type
let (x,) = (build3((x,)),);
//[next]~^ ERROR type mismatch resolving
//[next]~| ERROR type mismatch resolving
@ -47,7 +46,6 @@ fn build3<T>(x: T) -> impl Sized {
//[next]~| ERROR the size for values of type
//[next]~| ERROR mismatched types
build3(x)
//[current]~^ ERROR expected generic type parameter, found `(T,)`
}
fn main() {}

View File

@ -0,0 +1,15 @@
//@ check-pass
//! Test that `GatherLocalsVisitor` only visits expressions in guard patterns when checking the
//! expressions, and not a second time when visiting the pattern. If locals are declared inside the
//! the guard expression, it would ICE if visited twice ("evaluated expression more than once").
#![feature(guard_patterns)]
#![expect(incomplete_features)]
fn main() {
match (0,) {
// FIXME(guard_patterns): liveness lints don't work yet; this will ICE without the `_`.
(_ if { let _x = false; _x },) => {}
_ => {}
}
}

View File

@ -1,10 +1,10 @@
#![feature(type_alias_impl_trait)]
type T = impl Copy;
//~^ ERROR cannot resolve opaque type
#[define_opaque(T)]
fn foo() -> T {
//~^ ERROR cannot resolve opaque type
None::<&'static T>
}

View File

@ -1,8 +1,8 @@
error[E0720]: cannot resolve opaque type
--> $DIR/infinite-cycle-involving-weak.rs:3:10
--> $DIR/infinite-cycle-involving-weak.rs:6:13
|
LL | type T = impl Copy;
| ^^^^^^^^^ cannot resolve opaque type
LL | fn foo() -> T {
| ^
error: aborting due to 1 previous error

View File

@ -1,8 +1,12 @@
//@ known-bug: #139817
#![feature(type_alias_impl_trait)]
fn enum_upvar() {
type T = impl Copy;
let foo: T = Some((42, std::marker::PhantomData::<T>));
let x = move || match foo {
None => (),
//~^ ERROR cannot resolve opaque type
};
}
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/match-upvar-discriminant-of-opaque.rs:7:9
|
LL | None => (),
| ^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0720`.

View File

@ -13,7 +13,7 @@ pub fn add(
n: Diff,
m: Diff,
) -> Diff {
//~^ ERROR concrete type differs
//~^ ERROR cannot resolve opaque type
move |x: usize| m(n(x))
}

View File

@ -1,14 +1,9 @@
error: concrete type differs from previous defining opaque type use
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-fn-tait.rs:15:6
|
LL | ) -> Diff {
| ^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:17:5: 17:20}`
|
note: previous use here
--> $DIR/recursive-fn-tait.rs:7:18
|
LL | pub fn lift() -> Diff {
| ^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0720`.

View File

@ -13,7 +13,7 @@ fn transform<S>() -> impl std::fmt::Display {
}
#[define_opaque(Op)]
fn bad() -> Op {
//~^ ERROR concrete type differs from previous defining opaque type use
//~^ ERROR cannot resolve opaque type
transform::<Op>()
}

View File

@ -1,14 +1,9 @@
error: concrete type differs from previous defining opaque type use
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-tait-conflicting-defn-2.rs:15:13
|
LL | fn bad() -> Op {
| ^^ expected `&&str`, got `impl std::fmt::Display`
|
note: previous use here
--> $DIR/recursive-tait-conflicting-defn-2.rs:7:13
|
LL | fn foo() -> Op {
| ^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0720`.

View File

@ -23,7 +23,7 @@ pub fn test() -> TestImpl {
#[define_opaque(TestImpl)]
fn make_option2() -> Option<TestImpl> {
//~^ ERROR concrete type differs from previous defining opaque type use
//~^ ERROR cannot resolve opaque type
let inner = make_option().unwrap();
Some(B { inner })
}

View File

@ -1,14 +1,9 @@
error: concrete type differs from previous defining opaque type use
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-tait-conflicting-defn.rs:25:22
|
LL | fn make_option2() -> Option<TestImpl> {
| ^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
note: previous use here
--> $DIR/recursive-tait-conflicting-defn.rs:20:18
|
LL | pub fn test() -> TestImpl {
| ^^^^^^^^
| ^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0720`.