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,44 +70,32 @@ 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); let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
if let hir::MaybeOwner::Phantom = owner { if let hir::MaybeOwner::Phantom = owner {
let node = self.ast_index[def_id]; let node = self.ast_index[def_id];
match node { match node {
AstOwner::NonOwner => {} AstOwner::NonOwner => {}
AstOwner::Crate(c) => self.lower_crate(c), AstOwner::Crate(c) => {
AstOwner::Item(item) => self.lower_item(item), debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
AstOwner::AssocItem(item, ctxt) => self.lower_assoc_item(item, ctxt), self.with_lctx(CRATE_NODE_ID, |lctx| {
AstOwner::ForeignItem(item) => self.lower_foreign_item(item), let module = lctx.lower_mod(&c.items, &c.spans);
// FIXME(jdonszelman): is dummy span ever a problem here?
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
hir::OwnerNode::Crate(module)
})
}
AstOwner::Item(item) => {
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
}
AstOwner::AssocItem(item, ctxt) => {
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
}
AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
}),
} }
} }
self.owners[def_id]
}
#[instrument(level = "debug", skip(self, c))]
fn lower_crate(&mut self, c: &Crate) {
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);
// FIXME(jdonszelman): is dummy span ever a problem here?
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
hir::OwnerNode::Crate(module)
})
}
#[instrument(level = "debug", skip(self))]
fn lower_item(&mut self, 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) {
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)))
} }
} }

View File

@ -444,14 +444,14 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
tcx.definitions_untracked().def_index_count(), tcx.definitions_untracked().def_index_count(),
); );
let mut lowerer = item::ItemLowerer {
tcx,
resolver: &mut resolver,
ast_index: &ast_index,
owners: &mut owners,
};
for def_id in ast_index.indices() { for def_id in ast_index.indices() {
item::ItemLowerer { lowerer.lower_node(def_id);
tcx,
resolver: &mut resolver,
ast_index: &ast_index,
owners: &mut owners,
}
.lower_node(def_id);
} }
drop(ast_index); 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_expected_due_to_let_ty(err, expr, error);
self.annotate_loop_expected_due_to_inference(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; return;
} }
@ -799,17 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Detect the following case /// Detect the following case
/// ///
/// ```text /// ```text
/// fn change_object(mut a: &Ty) { /// fn change_object(mut b: &Ty) {
/// let a = Ty::new(); /// let a = Ty::new();
/// b = a; /// 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: /// parameter, instead of mutating the local binding. When encountering this we suggest:
/// ///
/// ```text /// ```text
/// fn change_object(a: &'_ mut Ty) { /// fn change_object(b: &'_ mut Ty) {
/// let a = Ty::new(); /// let a = Ty::new();
/// *b = a; /// *b = a;
/// } /// }
@ -818,13 +818,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
err: &mut Diag<'_>, err: &mut Diag<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>,
expected: Ty<'tcx>,
error: Option<TypeError<'tcx>>, error: Option<TypeError<'tcx>>,
) -> bool { ) -> 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() && let ty::Ref(_, inner, hir::Mutability::Not) = expected.kind()
// The difference between the expected and found values is one level of borrowing. // 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. // We have an `ident = expr;` assignment.
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) = && 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(); let old_outermost_fn_param_pat = self.outermost_fn_param_pat.take();
intravisit::walk_pat(self, p); 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; 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. //! which creates a new `TypeckResults` which doesn't contain any inference variables.
use std::mem; use std::mem;
use std::ops::ControlFlow;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::ExtendUnord; 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::intravisit::{self, InferKind, Visitor};
use rustc_hir::{self as hir, AmbigArg, HirId}; use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_infer::traits::solve::Goal; use rustc_infer::traits::solve::Goal;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, DefiningScopeKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeVisitableExt, fold_regions, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
fold_regions,
}; };
use rustc_span::{Span, sym}; use rustc_span::{Span, sym};
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; 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); 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) { 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) 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 linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
metadata_async_drop_types_in_dependency = 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 .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
metadata_bad_panic_strategy = metadata_bad_panic_strategy =

View File

@ -1,6 +1,5 @@
use std::fmt; use std::fmt;
use std::iter::once; use std::iter::once;
use std::ops::ControlFlow;
use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx}; use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx};
use rustc_arena::DroplessArena; 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::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
TypeVisitableExt, TypeVisitor, VariantDef,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint; 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 /// Returns the hidden type corresponding to this key if the body under analysis is allowed to
/// know it. /// know it.
fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> { 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) { self.typeck_results
let ty = ty::EarlyBinder::bind(hidden_ty.ty).instantiate(self.tcx, key.args); .concrete_opaque_types
if ty.visit_with(&mut RecursiveOpaque { def_id: key.def_id.into() }).is_continue() { .get(&key.def_id)
Some(ty) .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
} 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
}
} else {
None
}
} }
// This can take a non-revealed `Ty` because it reveals opaques itself. // This can take a non-revealed `Ty` because it reveals opaques itself.
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
!ty.inhabited_predicate(self.tcx).apply_revealing_opaque( !ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
@ -1177,20 +1164,3 @@ fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
} }
Ok(()) 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:?}"), 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 // 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 // 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) - [Command-line arguments](./cli.md)
- [rustc_driver and rustc_interface](./rustc-driver/intro.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: Type checking](./rustc-driver/interacting-with-the-ast.md)
- [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.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) - [Errors and lints](diagnostics.md)
- [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
- [Translation](./diagnostics/translation.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 [`-C embed-bitcode=no`][embed-bitcode] CLI option to improve compile times
and reduce disk space if LTO is not needed. and reduce disk space if LTO is not needed.
* `rustc` [metadata], in a file named `lib.rmeta`. * `rustc` [metadata], in a file named `lib.rmeta`.
* A symbol table, which is generally a list of symbols with offsets to the * A symbol table, which is essentially a list of symbols with offsets to the
object file that contain that symbol. This is pretty standard for archive object files that contain that symbol. This is pretty standard for archive
files. files.
[archive file]: https://en.wikipedia.org/wiki/Ar_(Unix) [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 ### rmeta
An `rmeta` file is custom binary format that contains the [metadata] for the 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 crate. This file can be used for fast "checks" of a project by skipping all code
code generation (as is done with `cargo check`), collecting enough information generation (as is done with `cargo check`), collecting enough information for
for documentation (as is done with `cargo doc`), or for documentation (as is done with `cargo doc`), or for [pipelining](#pipelining).
[pipelining](#pipelining). This file is created if the This file is created if the [`--emit=metadata`][emit] CLI option is used.
[`--emit=metadata`][emit] CLI option is used.
`rmeta` files do not support linking, since they do not contain compiled `rmeta` files do not support linking, since they do not contain compiled
object files. object files.
@ -60,8 +59,8 @@ object files.
## Metadata ## Metadata
The metadata contains a wide swath of different elements. This guide will not The metadata contains a wide swath of different elements. This guide will not go
go into detail of every field it contains. You are encouraged to browse the 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. [`CrateRoot`] definition to get a sense of the different elements it contains.
Everything about metadata encoding and decoding is in the [`rustc_metadata`] Everything about metadata encoding and decoding is in the [`rustc_metadata`]
package. package.
@ -122,9 +121,9 @@ much more.
By default, all Rust symbols are mangled and incorporate the stable crate id. 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 This allows multiple versions of the same crate to be included together. Cargo
automatically generates `-C metadata` hashes based on a variety of factors, automatically generates `-C metadata` hashes based on a variety of factors, like
like the package version, source, and the target kind (a lib and test can have the package version, source, and target kind (a lib and test can have the same
the same crate name, so they need to be disambiguated). 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`]: 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 [`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 As crates are loaded, they are kept in the [`CStore`] with the crate metadata
wrapped in the [`CrateMetadata`] struct. After resolution and expansion, the 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. compilation.
[name resolution]: ../name-resolution.md [name resolution]: ../name-resolution.md

View File

@ -28,6 +28,6 @@ adding a new command-line argument.
unstable-options` flag. unstable-options` flag.
[cli-docs]: https://doc.rust-lang.org/rustc/command-line-arguments.html [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/ [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 [`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. Not all important or beginner work has issue labels.
See below for how to find work that isn't labelled. 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 [Triage]: ./contributing.md#issue-triage
### Recurring work ### 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. 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]. 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. 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`][cb] is a `trait` that allows for custom compiler configuration, [`Callbacks`] is a `trait` that allows for custom compiler configuration,
as well as allowing custom code to run after different phases of the compilation. as well as allowing custom code to run after different phases of the compilation.
## `rustc_interface` ## `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 [`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_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 [`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 [`Callbacks`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.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
[example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-interface-example.rs [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 [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 [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 [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 //@ edition:2021
#![cfg_attr(with_feature, feature(async_drop))] #![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)] #![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 --> $DIR/dependency-dropped.rs:7:1
| |
LL | #![cfg_attr(with_feature, feature(async_drop))] 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 warning: function cannot return without recursing
--> $DIR/issue-100075-2.rs:1:1 --> $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 = help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default = 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 error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0720`. 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 --> $DIR/issue-100075.rs:13:37
| |
LL | fn _g<T>(t: &'static T) -> &'static impl Marker { 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 error: aborting due to 1 previous error

View File

@ -1,9 +1,8 @@
//@ check-pass
trait T {} trait T {}
fn wrap(x: impl T) -> impl 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)) 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 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 { LL | fn wrap(x: impl T) -> impl T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL | ...
LL | wrap(wrap(x)) LL | wrap(wrap(x))
| ------- recursive call site | ------- recursive call site
| |
= help: a `loop` may express intention better if this is on purpose = help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default = 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() { fn foo() -> impl Fn() {
//~^ WARNING 5:1: 5:22: function cannot return without recursing [unconditional_recursion] //~^ WARN function cannot return without recursing
//~| ERROR 5:13: 5:22: cannot resolve opaque type [E0720] //~| ERROR cannot resolve opaque type
wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo()))))))) 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 warning: function cannot return without recursing
--> $DIR/issue-87450.rs:5:1 --> $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 = help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default = 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 error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0720`. 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 --> $DIR/recursive-impl-trait-type-indirect.rs:6:22
| |
LL | fn option(i: i32) -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:11:15 --> $DIR/recursive-impl-trait-type-indirect.rs:11:15
| |
LL | fn tuple() -> impl Sized { LL | fn tuple() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type | ^^^^^^^^^^
LL |
LL | (tuple(),)
| ---------- returning here with type `(impl Sized,)`
error[E0720]: cannot resolve opaque type error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:16:15 --> $DIR/recursive-impl-trait-type-indirect.rs:16:15
| |
LL | fn array() -> impl Sized { LL | fn array() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type | ^^^^^^^^^^
LL |
LL | [array()]
| --------- returning here with type `[impl Sized; 1]`
error[E0720]: cannot resolve opaque type error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:21:13 --> $DIR/recursive-impl-trait-type-indirect.rs:21:13
| |
LL | fn ptr() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:26:16 --> $DIR/recursive-impl-trait-type-indirect.rs:26:16
| |
LL | fn fn_ptr() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:31:25 --> $DIR/recursive-impl-trait-type-indirect.rs:31:25
| |
LL | fn closure_capture() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:39:29 --> $DIR/recursive-impl-trait-type-indirect.rs:39:29
| |
LL | fn closure_ref_capture() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:47:21 --> $DIR/recursive-impl-trait-type-indirect.rs:47:21
| |
LL | fn closure_sig() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:52:23 --> $DIR/recursive-impl-trait-type-indirect.rs:52:23
| |
LL | fn coroutine_sig() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:57:27 --> $DIR/recursive-impl-trait-type-indirect.rs:57:27
| |
LL | fn coroutine_capture() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:68:35 --> $DIR/recursive-impl-trait-type-indirect.rs:68:35
| |
LL | fn substs_change<T: 'static>() -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:78:26 --> $DIR/recursive-impl-trait-type-indirect.rs:78:26

View File

@ -1,56 +1,21 @@
warning: function cannot return without recursing error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:17:1 --> $DIR/recursive-in-exhaustiveness.rs:17:22
| |
LL | fn build<T>(x: T) -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:27:23 --> $DIR/recursive-in-exhaustiveness.rs:27:23
| |
LL | fn build2<T>(x: T) -> impl Sized { 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 error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:40:1 --> $DIR/recursive-in-exhaustiveness.rs:39:23
| |
LL | fn build3<T>(x: T) -> impl Sized { 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,)` error: aborting due to 3 previous errors
--> $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 2 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0720`.
Some errors have detailed explanations: E0720, E0792.
For more information about an error, try `rustc --explain E0720`.

View File

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

View File

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

View File

@ -1,8 +1,8 @@
error[E0720]: cannot resolve opaque type 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; LL | fn foo() -> T {
| ^^^^^^^^^ cannot resolve opaque type | ^
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -1,8 +1,12 @@
//@ known-bug: #139817 #![feature(type_alias_impl_trait)]
fn enum_upvar() { fn enum_upvar() {
type T = impl Copy; type T = impl Copy;
let foo: T = Some((42, std::marker::PhantomData::<T>)); let foo: T = Some((42, std::marker::PhantomData::<T>));
let x = move || match foo { let x = move || match foo {
None => (), 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, n: Diff,
m: Diff, m: Diff,
) -> Diff { ) -> Diff {
//~^ ERROR concrete type differs //~^ ERROR cannot resolve opaque type
move |x: usize| m(n(x)) 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 --> $DIR/recursive-fn-tait.rs:15:6
| |
LL | ) -> Diff { 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 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)] #[define_opaque(Op)]
fn bad() -> Op { fn bad() -> Op {
//~^ ERROR concrete type differs from previous defining opaque type use //~^ ERROR cannot resolve opaque type
transform::<Op>() 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 --> $DIR/recursive-tait-conflicting-defn-2.rs:15:13
| |
LL | fn bad() -> Op { 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 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)] #[define_opaque(TestImpl)]
fn make_option2() -> Option<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(); let inner = make_option().unwrap();
Some(B { inner }) 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 --> $DIR/recursive-tait-conflicting-defn.rs:25:22
| |
LL | fn make_option2() -> Option<TestImpl> { 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 error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0720`.