2014-11-26 11:11:29 +00:00
|
|
|
/*!
|
2012-11-29 00:20:41 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
# typeck
|
2012-11-29 00:20:41 +00:00
|
|
|
|
|
|
|
The type checker is responsible for:
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
1. Determining the type of each expression.
|
|
|
|
2. Resolving methods and traits.
|
|
|
|
3. Guaranteeing that most type rules are met. ("Most?", you say, "why most?"
|
2021-01-30 07:03:35 +00:00
|
|
|
Well, dear reader, read on.)
|
2012-11-29 00:20:41 +00:00
|
|
|
|
2021-01-30 07:03:35 +00:00
|
|
|
The main entry point is [`check_crate()`]. Type checking operates in
|
2013-10-29 10:08:34 +00:00
|
|
|
several major phases:
|
2012-11-29 00:20:41 +00:00
|
|
|
|
2013-10-29 10:08:34 +00:00
|
|
|
1. The collect phase first passes over all items and determines their
|
|
|
|
type, without examining their "innards".
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
2. Variance inference then runs to compute the variance of each parameter.
|
2013-10-29 10:08:34 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
3. Coherence checks for overlapping or orphaned impls.
|
2013-10-29 10:08:34 +00:00
|
|
|
|
|
|
|
4. Finally, the check phase then checks function bodies and so forth.
|
|
|
|
Within the check phase, we check each function body one at a time
|
|
|
|
(bodies of function expressions are checked as part of the
|
2022-11-16 20:34:16 +00:00
|
|
|
containing function). Inference is used to supply types wherever
|
2013-10-29 10:08:34 +00:00
|
|
|
they are unknown. The actual checking of a function itself has
|
|
|
|
several phases (check, regionck, writeback), as discussed in the
|
2021-01-30 07:03:35 +00:00
|
|
|
documentation for the [`check`] module.
|
2012-11-29 00:20:41 +00:00
|
|
|
|
|
|
|
The type checker is defined into various submodules which are documented
|
|
|
|
independently:
|
|
|
|
|
|
|
|
- astconv: converts the AST representation of types
|
2018-11-27 02:59:49 +00:00
|
|
|
into the `ty` representation.
|
2012-11-29 00:20:41 +00:00
|
|
|
|
|
|
|
- collect: computes the types of each top-level item and enters them into
|
2018-11-27 02:59:49 +00:00
|
|
|
the `tcx.types` table for later use.
|
2012-11-29 00:20:41 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
- coherence: enforces coherence rules, builds some tables.
|
2013-10-29 10:08:34 +00:00
|
|
|
|
|
|
|
- variance: variance inference
|
|
|
|
|
2017-09-28 00:18:41 +00:00
|
|
|
- outlives: outlives inference
|
|
|
|
|
2012-11-29 00:20:41 +00:00
|
|
|
- check: walks over function bodies and type checks them, inferring types for
|
|
|
|
local variables, type parameters, etc as necessary.
|
|
|
|
|
|
|
|
- infer: finds the types to use for each type variable such that
|
2022-11-16 20:34:16 +00:00
|
|
|
all subtyping and assignment constraints are met. In essence, the check
|
2012-11-29 00:20:41 +00:00
|
|
|
module specifies the constraints, and the infer module solves them.
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
## Note
|
2014-11-26 11:11:29 +00:00
|
|
|
|
|
|
|
This API is completely unstable and subject to change.
|
|
|
|
|
2012-11-29 00:20:41 +00:00
|
|
|
*/
|
2015-12-11 21:07:11 +00:00
|
|
|
|
2022-02-26 10:43:47 +00:00
|
|
|
#![allow(rustc::potential_query_instability)]
|
2020-09-23 19:51:56 +00:00
|
|
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
2021-10-13 13:58:41 +00:00
|
|
|
#![feature(box_patterns)]
|
2022-02-26 10:43:47 +00:00
|
|
|
#![feature(control_flow_enum)]
|
2021-08-16 15:29:49 +00:00
|
|
|
#![feature(if_let_guard)]
|
2020-11-13 19:23:37 +00:00
|
|
|
#![feature(is_sorted)]
|
2022-04-13 14:49:03 +00:00
|
|
|
#![feature(iter_intersperse)]
|
2022-08-20 18:40:08 +00:00
|
|
|
#![feature(let_chains)]
|
2021-10-07 19:56:40 +00:00
|
|
|
#![feature(min_specialization)]
|
2019-12-11 14:55:29 +00:00
|
|
|
#![feature(never_type)]
|
2022-12-12 05:42:45 +00:00
|
|
|
#![feature(lazy_cell)]
|
2022-02-26 10:43:47 +00:00
|
|
|
#![feature(slice_partition_dedup)]
|
|
|
|
#![feature(try_blocks)]
|
2022-08-01 02:23:09 +00:00
|
|
|
#![feature(type_alias_impl_trait)]
|
2018-03-15 09:08:52 +00:00
|
|
|
#![recursion_limit = "256"]
|
2017-05-08 21:36:44 +00:00
|
|
|
|
2015-01-06 17:24:46 +00:00
|
|
|
#[macro_use]
|
2020-08-14 06:05:01 +00:00
|
|
|
extern crate tracing;
|
2018-09-15 17:23:30 +00:00
|
|
|
|
2016-03-28 22:06:35 +00:00
|
|
|
#[macro_use]
|
2020-03-29 14:41:09 +00:00
|
|
|
extern crate rustc_middle;
|
2014-11-26 11:11:29 +00:00
|
|
|
|
2020-08-03 00:19:33 +00:00
|
|
|
// These are used by Clippy.
|
|
|
|
pub mod check;
|
2019-11-09 10:38:06 +00:00
|
|
|
|
2022-10-20 15:51:37 +00:00
|
|
|
pub mod astconv;
|
2022-12-27 00:39:36 +00:00
|
|
|
pub mod autoderef;
|
2020-08-19 17:07:03 +00:00
|
|
|
mod bounds;
|
2017-05-03 15:28:22 +00:00
|
|
|
mod check_unused;
|
2018-01-23 02:07:35 +00:00
|
|
|
mod coherence;
|
2022-10-20 15:51:37 +00:00
|
|
|
// FIXME: This module shouldn't be public.
|
|
|
|
pub mod collect;
|
2019-03-29 00:28:07 +00:00
|
|
|
mod constrained_generic_params;
|
2020-08-27 10:00:21 +00:00
|
|
|
mod errors;
|
Add initial implementation of HIR-based WF checking for diagnostics
During well-formed checking, we walk through all types 'nested' in
generic arguments. For example, WF-checking `Option<MyStruct<u8>>`
will cause us to check `MyStruct<u8>` and `u8`. However, this is done
on a `rustc_middle::ty::Ty`, which has no span information. As a result,
any errors that occur will have a very general span (e.g. the
definintion of an associated item).
This becomes a problem when macros are involved. In general, an
associated type like `type MyType = Option<MyStruct<u8>>;` may
have completely different spans for each nested type in the HIR. Using
the span of the entire associated item might end up pointing to a macro
invocation, even though a user-provided span is available in one of the
nested types.
This PR adds a framework for HIR-based well formed checking. This check
is only run during error reporting, and is used to obtain a more precise
span for an existing error. This is accomplished by individually
checking each 'nested' type in the HIR for the type, allowing us to
find the most-specific type (and span) that produces a given error.
The majority of the changes are to the error-reporting code. However,
some of the general trait code is modified to pass through more
information.
Since this has no soundness implications, I've implemented a minimal
version to begin with, which can be extended over time. In particular,
this only works for HIR items with a corresponding `DefId` (e.g. it will
not work for WF-checking performed within function bodies).
2021-04-04 20:55:39 +00:00
|
|
|
pub mod hir_wf_check;
|
2016-11-11 14:52:46 +00:00
|
|
|
mod impl_wf_check;
|
2017-09-28 00:18:41 +00:00
|
|
|
mod outlives;
|
2022-10-20 15:51:37 +00:00
|
|
|
pub mod structured_errors;
|
2017-05-03 15:28:22 +00:00
|
|
|
mod variance;
|
2014-11-26 10:48:57 +00:00
|
|
|
|
2023-02-24 20:23:30 +00:00
|
|
|
use rustc_errors::ErrorGuaranteed;
|
2022-10-13 09:13:02 +00:00
|
|
|
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
|
2023-04-16 12:33:00 +00:00
|
|
|
use rustc_fluent_macro::fluent_messages;
|
2020-01-05 01:37:57 +00:00
|
|
|
use rustc_hir as hir;
|
2023-01-15 11:58:46 +00:00
|
|
|
use rustc_hir::Node;
|
2023-03-14 13:19:06 +00:00
|
|
|
use rustc_infer::infer::TyCtxtInferExt;
|
2020-03-29 14:41:09 +00:00
|
|
|
use rustc_middle::middle;
|
2023-05-15 04:24:45 +00:00
|
|
|
use rustc_middle::query::Providers;
|
2020-03-29 14:41:09 +00:00
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
|
|
|
use rustc_middle::util;
|
2022-08-08 13:31:32 +00:00
|
|
|
use rustc_session::{config::EntryFnType, parse::feature_err};
|
2023-01-15 11:58:46 +00:00
|
|
|
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
2020-08-04 05:30:04 +00:00
|
|
|
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
2018-11-27 02:59:49 +00:00
|
|
|
use rustc_target::spec::abi::Abi;
|
2022-09-09 20:08:06 +00:00
|
|
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
2023-03-14 13:19:06 +00:00
|
|
|
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt};
|
2018-11-27 02:59:49 +00:00
|
|
|
|
2023-01-09 15:21:08 +00:00
|
|
|
use std::ops::Not;
|
2018-11-27 02:59:49 +00:00
|
|
|
|
2023-04-18 23:55:05 +00:00
|
|
|
use astconv::{AstConv, OnlySelfBounds};
|
2020-08-19 17:07:03 +00:00
|
|
|
use bounds::Bounds;
|
2023-07-11 09:24:59 +00:00
|
|
|
use rustc_hir::def::DefKind;
|
2014-05-06 13:52:04 +00:00
|
|
|
|
2023-03-02 23:18:38 +00:00
|
|
|
fluent_messages! { "../messages.ftl" }
|
2022-10-13 09:13:02 +00:00
|
|
|
|
2019-12-01 15:08:58 +00:00
|
|
|
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
|
2022-08-16 18:29:19 +00:00
|
|
|
const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`";
|
|
|
|
const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
|
2022-08-08 13:31:32 +00:00
|
|
|
const UNSTABLE_EXPLAIN: &str =
|
2022-10-23 23:11:25 +00:00
|
|
|
"using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
|
2022-08-08 13:31:32 +00:00
|
|
|
|
|
|
|
if !decl.c_variadic || matches!(abi, Abi::C { .. } | Abi::Cdecl { .. }) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let extended_abi_support = tcx.features().extended_varargs_abi_support;
|
|
|
|
let conventions = match (extended_abi_support, abi.supports_varargs()) {
|
|
|
|
// User enabled additional ABI support for varargs and function ABI matches those ones.
|
|
|
|
(true, true) => return,
|
|
|
|
|
|
|
|
// Using this ABI would be ok, if the feature for additional ABI support was enabled.
|
|
|
|
// Return CONVENTIONS_STABLE, because we want the other error to look the same.
|
|
|
|
(false, true) => {
|
|
|
|
feature_err(
|
|
|
|
&tcx.sess.parse_sess,
|
|
|
|
sym::extended_varargs_abi_support,
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 15:49:18 +00:00
|
|
|
span,
|
2022-08-08 13:31:32 +00:00
|
|
|
UNSTABLE_EXPLAIN,
|
|
|
|
)
|
|
|
|
.emit();
|
|
|
|
CONVENTIONS_STABLE
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 15:49:18 +00:00
|
|
|
}
|
2022-08-08 13:31:32 +00:00
|
|
|
|
|
|
|
(false, false) => CONVENTIONS_STABLE,
|
|
|
|
(true, false) => CONVENTIONS_UNSTABLE,
|
|
|
|
};
|
|
|
|
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
|
2015-07-21 15:41:08 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 21:11:55 +00:00
|
|
|
fn require_same_types<'tcx>(
|
2019-06-13 21:48:52 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2019-06-11 21:11:55 +00:00
|
|
|
cause: &ObligationCause<'tcx>,
|
2023-03-14 13:19:06 +00:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2019-06-11 21:11:55 +00:00
|
|
|
expected: Ty<'tcx>,
|
|
|
|
actual: Ty<'tcx>,
|
2023-03-14 13:19:06 +00:00
|
|
|
) {
|
2017-06-09 07:55:16 +00:00
|
|
|
let infcx = &tcx.infer_ctxt().build();
|
2023-03-14 13:19:06 +00:00
|
|
|
let ocx = ObligationCtxt::new(infcx);
|
|
|
|
match ocx.eq(cause, param_env, expected, actual) {
|
|
|
|
Ok(()) => {
|
|
|
|
let errors = ocx.select_all_or_error();
|
|
|
|
if !errors.is_empty() {
|
|
|
|
infcx.err_ctxt().report_fulfillment_errors(&errors);
|
|
|
|
}
|
|
|
|
}
|
2016-10-03 23:19:40 +00:00
|
|
|
Err(err) => {
|
2022-09-09 20:08:06 +00:00
|
|
|
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
2016-05-02 15:07:47 +00:00
|
|
|
}
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
|
|
|
|
2021-04-25 17:09:35 +00:00
|
|
|
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
2023-07-11 21:35:29 +00:00
|
|
|
let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity();
|
2019-01-13 12:06:26 +00:00
|
|
|
let main_span = tcx.def_span(main_def_id);
|
2021-04-25 17:09:35 +00:00
|
|
|
|
2023-01-15 11:58:46 +00:00
|
|
|
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
|
2021-04-25 17:09:35 +00:00
|
|
|
if let Some(local_def_id) = def_id.as_local() {
|
2023-07-11 21:35:29 +00:00
|
|
|
let hir_type = tcx.type_of(local_def_id).instantiate_identity();
|
2021-04-25 17:09:35 +00:00
|
|
|
if !matches!(hir_type.kind(), ty::FnDef(..)) {
|
|
|
|
span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
2023-01-15 11:58:46 +00:00
|
|
|
local_def_id
|
2021-04-25 17:09:35 +00:00
|
|
|
} else {
|
2023-01-15 11:58:46 +00:00
|
|
|
CRATE_DEF_ID
|
2021-04-25 17:09:35 +00:00
|
|
|
}
|
|
|
|
}
|
2017-12-21 12:07:50 +00:00
|
|
|
|
2021-04-25 17:09:35 +00:00
|
|
|
fn main_fn_generics_params_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
|
|
|
|
if !def_id.is_local() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
|
|
|
match tcx.hir().find(hir_id) {
|
2023-01-09 15:21:08 +00:00
|
|
|
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
|
2023-02-15 17:39:43 +00:00
|
|
|
generics.params.is_empty().not().then_some(generics.span)
|
2021-04-25 17:09:35 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
span_bug!(tcx.def_span(def_id), "main has a non-function type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-21 12:07:50 +00:00
|
|
|
|
2021-04-25 17:09:35 +00:00
|
|
|
fn main_fn_where_clauses_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
|
|
|
|
if !def_id.is_local() {
|
|
|
|
return None;
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
2021-04-25 17:09:35 +00:00
|
|
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
|
|
|
match tcx.hir().find(hir_id) {
|
2023-01-09 16:30:40 +00:00
|
|
|
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
|
2022-06-07 04:01:06 +00:00
|
|
|
Some(generics.where_clause_span)
|
2021-04-25 17:09:35 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
span_bug!(tcx.def_span(def_id), "main has a non-function type");
|
|
|
|
}
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-25 17:09:35 +00:00
|
|
|
fn main_fn_asyncness_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
|
|
|
|
if !def_id.is_local() {
|
|
|
|
return None;
|
|
|
|
}
|
2022-07-04 08:23:24 +00:00
|
|
|
Some(tcx.def_span(def_id))
|
2021-04-25 17:09:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
|
|
|
|
if !def_id.is_local() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
|
|
|
match tcx.hir().find(hir_id) {
|
2023-01-09 16:30:40 +00:00
|
|
|
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
|
2021-04-25 17:09:35 +00:00
|
|
|
Some(fn_sig.decl.output.span())
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
span_bug!(tcx.def_span(def_id), "main has a non-function type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut error = false;
|
2023-01-15 11:58:46 +00:00
|
|
|
let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);
|
2021-04-25 17:09:35 +00:00
|
|
|
let main_fn_generics = tcx.generics_of(main_def_id);
|
|
|
|
let main_fn_predicates = tcx.predicates_of(main_def_id);
|
|
|
|
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
|
|
|
|
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::MainFunctionGenericParameters {
|
|
|
|
span: generics_param_span.unwrap_or(main_span),
|
|
|
|
label_span: generics_param_span,
|
|
|
|
});
|
2021-04-25 17:09:35 +00:00
|
|
|
error = true;
|
|
|
|
} else if !main_fn_predicates.predicates.is_empty() {
|
|
|
|
// generics may bring in implicit predicates, so we skip this check if generics is present.
|
|
|
|
let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
|
2023-02-22 23:50:38 +00:00
|
|
|
tcx.sess.emit_err(errors::WhereClauseOnMain {
|
|
|
|
span: generics_where_clauses_span.unwrap_or(main_span),
|
|
|
|
generics_span: generics_where_clauses_span,
|
|
|
|
});
|
2021-04-25 17:09:35 +00:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
let main_asyncness = tcx.asyncness(main_def_id);
|
|
|
|
if let hir::IsAsync::Async = main_asyncness {
|
|
|
|
let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
|
2021-04-25 17:09:35 +00:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
|
2022-05-02 07:31:56 +00:00
|
|
|
for attr in tcx.get_attrs(main_def_id, sym::track_caller) {
|
2023-02-21 20:27:16 +00:00
|
|
|
tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span });
|
2022-05-02 07:31:56 +00:00
|
|
|
error = true;
|
2021-04-25 17:09:35 +00:00
|
|
|
}
|
|
|
|
|
2023-03-10 12:27:13 +00:00
|
|
|
if !tcx.codegen_fn_attrs(main_def_id).target_features.is_empty()
|
|
|
|
// Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
|
|
|
|
&& !tcx.sess.target.is_like_wasm
|
|
|
|
&& !tcx.sess.opts.actually_rustdoc
|
|
|
|
{
|
2023-03-02 11:37:32 +00:00
|
|
|
tcx.sess.emit_err(errors::TargetFeatureOnMain { main: main_span });
|
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
|
2021-04-25 17:09:35 +00:00
|
|
|
if error {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-03-14 13:19:06 +00:00
|
|
|
// Main should have no WC, so empty param env is OK here.
|
|
|
|
let param_env = ty::ParamEnv::empty();
|
2021-04-25 17:09:35 +00:00
|
|
|
let expected_return_type;
|
2022-07-26 03:18:45 +00:00
|
|
|
if let Some(term_did) = tcx.lang_items().termination() {
|
2021-04-25 17:09:35 +00:00
|
|
|
let return_ty = main_fnsig.output();
|
|
|
|
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
|
|
|
|
if !return_ty.bound_vars().is_empty() {
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
|
2021-04-25 17:09:35 +00:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
let return_ty = return_ty.skip_binder();
|
|
|
|
let infcx = tcx.infer_ctxt().build();
|
|
|
|
let cause = traits::ObligationCause::new(
|
|
|
|
return_ty_span,
|
2023-01-15 11:58:46 +00:00
|
|
|
main_diagnostics_def_id,
|
2021-04-25 17:09:35 +00:00
|
|
|
ObligationCauseCode::MainFunctionType,
|
|
|
|
);
|
2022-07-26 03:18:45 +00:00
|
|
|
let ocx = traits::ObligationCtxt::new(&infcx);
|
2022-11-25 18:40:52 +00:00
|
|
|
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty);
|
2022-07-26 03:18:45 +00:00
|
|
|
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
|
|
|
|
let errors = ocx.select_all_or_error();
|
2021-11-08 15:35:23 +00:00
|
|
|
if !errors.is_empty() {
|
2023-03-09 23:23:43 +00:00
|
|
|
infcx.err_ctxt().report_fulfillment_errors(&errors);
|
2021-04-25 17:09:35 +00:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
// now we can take the return type of the given main function
|
|
|
|
expected_return_type = main_fnsig.output();
|
|
|
|
} else {
|
|
|
|
// standard () main return type
|
2023-07-05 19:13:26 +00:00
|
|
|
expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx));
|
2021-04-25 17:09:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if error {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:13:26 +00:00
|
|
|
let se_ty = Ty::new_fn_ptr(
|
|
|
|
tcx,
|
|
|
|
expected_return_type.map_bound(|expected_return_type| {
|
|
|
|
tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
|
|
|
|
}),
|
|
|
|
);
|
2021-04-25 17:09:35 +00:00
|
|
|
|
|
|
|
require_same_types(
|
|
|
|
tcx,
|
|
|
|
&ObligationCause::new(
|
|
|
|
main_span,
|
2023-01-15 11:58:46 +00:00
|
|
|
main_diagnostics_def_id,
|
2021-04-25 17:09:35 +00:00
|
|
|
ObligationCauseCode::MainFunctionType,
|
|
|
|
),
|
2023-03-14 13:19:06 +00:00
|
|
|
param_env,
|
2021-04-25 17:09:35 +00:00
|
|
|
se_ty,
|
2023-07-05 19:13:26 +00:00
|
|
|
Ty::new_fn_ptr(tcx, main_fnsig),
|
2021-04-25 17:09:35 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
|
|
|
let start_def_id = start_def_id.expect_local();
|
2020-08-12 10:22:56 +00:00
|
|
|
let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
|
2019-01-13 12:06:26 +00:00
|
|
|
let start_span = tcx.def_span(start_def_id);
|
2023-07-11 21:35:29 +00:00
|
|
|
let start_t = tcx.type_of(start_def_id).instantiate_identity();
|
2020-08-02 22:49:11 +00:00
|
|
|
match start_t.kind() {
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::FnDef(..) => {
|
2019-06-24 07:58:49 +00:00
|
|
|
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
|
2023-01-09 16:30:40 +00:00
|
|
|
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
|
2018-09-26 15:32:23 +00:00
|
|
|
let mut error = false;
|
|
|
|
if !generics.params.is_empty() {
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span });
|
2018-09-26 15:32:23 +00:00
|
|
|
error = true;
|
|
|
|
}
|
2022-06-07 04:01:06 +00:00
|
|
|
if generics.has_where_clause_predicates {
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::StartFunctionWhere {
|
|
|
|
span: generics.where_clause_span,
|
|
|
|
});
|
2018-09-26 15:32:23 +00:00
|
|
|
error = true;
|
|
|
|
}
|
2020-04-08 19:39:02 +00:00
|
|
|
if let hir::IsAsync::Async = sig.header.asyncness {
|
2022-10-27 03:02:18 +00:00
|
|
|
let span = tcx.def_span(it.owner_id);
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::StartAsync { span: span });
|
2020-04-08 19:39:02 +00:00
|
|
|
error = true;
|
|
|
|
}
|
2020-08-04 05:30:04 +00:00
|
|
|
|
2021-01-24 12:17:54 +00:00
|
|
|
let attrs = tcx.hir().attrs(start_id);
|
|
|
|
for attr in attrs {
|
2021-07-29 17:00:41 +00:00
|
|
|
if attr.has_name(sym::track_caller) {
|
2023-02-24 20:23:30 +00:00
|
|
|
tcx.sess.emit_err(errors::StartTrackCaller {
|
|
|
|
span: attr.span,
|
|
|
|
start: start_span,
|
|
|
|
});
|
2020-08-04 05:30:04 +00:00
|
|
|
error = true;
|
|
|
|
}
|
2023-03-10 12:27:13 +00:00
|
|
|
if attr.has_name(sym::target_feature)
|
|
|
|
// Calling functions with `#[target_feature]` is
|
|
|
|
// not unsafe on WASM, see #84988
|
|
|
|
&& !tcx.sess.target.is_like_wasm
|
|
|
|
&& !tcx.sess.opts.actually_rustdoc
|
|
|
|
{
|
2023-03-02 13:26:12 +00:00
|
|
|
tcx.sess.emit_err(errors::StartTargetFeature {
|
|
|
|
span: attr.span,
|
|
|
|
start: start_span,
|
|
|
|
});
|
|
|
|
error = true;
|
|
|
|
}
|
2020-08-04 05:30:04 +00:00
|
|
|
}
|
|
|
|
|
2018-09-26 15:32:23 +00:00
|
|
|
if error {
|
|
|
|
return;
|
2013-04-09 08:16:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:13:26 +00:00
|
|
|
let se_ty = Ty::new_fn_ptr(
|
|
|
|
tcx,
|
|
|
|
ty::Binder::dummy(tcx.mk_fn_sig(
|
|
|
|
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
|
|
|
|
tcx.types.isize,
|
|
|
|
false,
|
|
|
|
hir::Unsafety::Normal,
|
|
|
|
Abi::Rust,
|
|
|
|
)),
|
|
|
|
);
|
2013-04-09 08:16:06 +00:00
|
|
|
|
2016-07-16 16:38:17 +00:00
|
|
|
require_same_types(
|
2016-10-03 23:19:40 +00:00
|
|
|
tcx,
|
2023-01-15 11:58:46 +00:00
|
|
|
&ObligationCause::new(
|
|
|
|
start_span,
|
|
|
|
start_def_id,
|
|
|
|
ObligationCauseCode::StartFunctionType,
|
|
|
|
),
|
2023-03-14 13:19:06 +00:00
|
|
|
ty::ParamEnv::empty(), // start should not have any where bounds.
|
2016-08-30 03:44:21 +00:00
|
|
|
se_ty,
|
2023-07-11 21:35:29 +00:00
|
|
|
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
|
2017-05-13 14:11:52 +00:00
|
|
|
);
|
2013-04-09 08:16:06 +00:00
|
|
|
}
|
|
|
|
_ => {
|
2016-03-28 22:06:35 +00:00
|
|
|
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
|
2013-04-09 08:16:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-21 21:49:03 +00:00
|
|
|
fn check_for_entry_fn(tcx: TyCtxt<'_>) {
|
2021-05-11 10:00:59 +00:00
|
|
|
match tcx.entry_fn(()) {
|
2022-07-05 17:56:22 +00:00
|
|
|
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
|
2020-04-18 15:34:41 +00:00
|
|
|
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
|
2019-01-13 12:06:26 +00:00
|
|
|
_ => {}
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 20:00:14 +00:00
|
|
|
pub fn provide(providers: &mut Providers) {
|
2017-02-13 23:11:24 +00:00
|
|
|
collect::provide(providers);
|
2017-02-19 12:46:29 +00:00
|
|
|
coherence::provide(providers);
|
2017-02-14 09:32:00 +00:00
|
|
|
check::provide(providers);
|
2017-04-24 15:15:12 +00:00
|
|
|
variance::provide(providers);
|
2017-09-28 01:01:48 +00:00
|
|
|
outlives::provide(providers);
|
2019-01-26 11:18:32 +00:00
|
|
|
impl_wf_check::provide(providers);
|
Add initial implementation of HIR-based WF checking for diagnostics
During well-formed checking, we walk through all types 'nested' in
generic arguments. For example, WF-checking `Option<MyStruct<u8>>`
will cause us to check `MyStruct<u8>` and `u8`. However, this is done
on a `rustc_middle::ty::Ty`, which has no span information. As a result,
any errors that occur will have a very general span (e.g. the
definintion of an associated item).
This becomes a problem when macros are involved. In general, an
associated type like `type MyType = Option<MyStruct<u8>>;` may
have completely different spans for each nested type in the HIR. Using
the span of the entire associated item might end up pointing to a macro
invocation, even though a user-provided span is available in one of the
nested types.
This PR adds a framework for HIR-based well formed checking. This check
is only run during error reporting, and is used to obtain a more precise
span for an existing error. This is accomplished by individually
checking each 'nested' type in the HIR for the type, allowing us to
find the most-specific type (and span) that produces a given error.
The majority of the changes are to the error-reporting code. However,
some of the general trait code is modified to pass through more
information.
Since this has no soundness implications, I've implemented a minimal
version to begin with, which can be extended over time. In particular,
this only works for HIR items with a corresponding `DefId` (e.g. it will
not work for WF-checking performed within function bodies).
2021-04-04 20:55:39 +00:00
|
|
|
hir_wf_check::provide(providers);
|
2017-02-13 23:11:24 +00:00
|
|
|
}
|
|
|
|
|
2022-01-23 18:34:26 +00:00
|
|
|
pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
2020-01-01 01:24:05 +00:00
|
|
|
let _prof_timer = tcx.sess.timer("type_check_crate");
|
2018-05-19 17:50:58 +00:00
|
|
|
|
2013-05-06 13:00:37 +00:00
|
|
|
// this ensures that later parts of type checking can assume that items
|
|
|
|
// have valid types and not error
|
2020-09-26 16:56:03 +00:00
|
|
|
// FIXME(matthewjasper) We shouldn't need to use `track_errors`.
|
2016-03-23 03:01:37 +00:00
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-07 20:34:08 +00:00
|
|
|
tcx.sess.time("type_collecting", || {
|
2021-07-18 16:12:17 +00:00
|
|
|
tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
|
2019-02-23 18:18:14 +00:00
|
|
|
});
|
2016-03-23 03:01:37 +00:00
|
|
|
})?;
|
2013-05-06 13:00:37 +00:00
|
|
|
|
2019-01-26 14:26:49 +00:00
|
|
|
if tcx.features().rustc_attrs {
|
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-07 20:34:08 +00:00
|
|
|
tcx.sess.time("outlives_testing", || outlives::test::test_inferred_outlives(tcx));
|
2019-01-26 14:26:49 +00:00
|
|
|
})?;
|
|
|
|
}
|
2017-09-28 01:20:44 +00:00
|
|
|
|
2016-11-11 14:52:46 +00:00
|
|
|
tcx.sess.track_errors(|| {
|
2021-05-09 18:49:17 +00:00
|
|
|
tcx.sess.time("impl_wf_inference", || {
|
|
|
|
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module))
|
|
|
|
});
|
2016-11-11 14:52:46 +00:00
|
|
|
})?;
|
|
|
|
|
2016-03-23 03:01:37 +00:00
|
|
|
tcx.sess.track_errors(|| {
|
2021-05-09 18:53:13 +00:00
|
|
|
tcx.sess.time("coherence_checking", || {
|
|
|
|
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
|
|
|
|
tcx.ensure().coherent_trait(trait_def_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
// these queries are executed for side-effects (error reporting):
|
|
|
|
tcx.ensure().crate_inherent_impls(());
|
|
|
|
tcx.ensure().crate_inherent_impls_overlap_check(());
|
|
|
|
});
|
2016-03-23 03:01:37 +00:00
|
|
|
})?;
|
2013-03-21 10:28:58 +00:00
|
|
|
|
2019-01-26 14:26:49 +00:00
|
|
|
if tcx.features().rustc_attrs {
|
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-07 20:34:08 +00:00
|
|
|
tcx.sess.time("variance_testing", || variance::test::test_variance(tcx));
|
2019-01-26 14:26:49 +00:00
|
|
|
})?;
|
|
|
|
}
|
2017-04-25 09:45:59 +00:00
|
|
|
|
2019-06-22 11:46:48 +00:00
|
|
|
tcx.sess.track_errors(|| {
|
2021-05-10 10:18:55 +00:00
|
|
|
tcx.sess.time("wf_checking", || {
|
|
|
|
tcx.hir().par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
|
|
|
|
});
|
2019-06-22 11:46:48 +00:00
|
|
|
})?;
|
2015-08-07 13:39:54 +00:00
|
|
|
|
2020-08-08 00:07:07 +00:00
|
|
|
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
|
2020-01-07 20:34:08 +00:00
|
|
|
tcx.sess.time("item_types_checking", || {
|
2021-07-18 16:12:17 +00:00
|
|
|
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
|
2019-04-19 22:37:34 +00:00
|
|
|
});
|
2013-03-21 10:28:58 +00:00
|
|
|
|
2023-07-11 09:24:59 +00:00
|
|
|
// FIXME: Remove this when we implement creating `DefId`s
|
|
|
|
// for anon constants during their parents' typeck.
|
|
|
|
// Typeck all body owners in parallel will produce queries
|
|
|
|
// cycle errors because it may typeck on anon constants directly.
|
|
|
|
tcx.hir().par_body_owners(|item_def_id| {
|
|
|
|
let def_kind = tcx.def_kind(item_def_id);
|
|
|
|
if !matches!(def_kind, DefKind::AnonConst) {
|
|
|
|
tcx.ensure().typeck(item_def_id);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-04-19 13:43:10 +00:00
|
|
|
check_unused::check_crate(tcx);
|
2016-10-03 23:19:40 +00:00
|
|
|
check_for_entry_fn(tcx);
|
2016-01-27 06:01:01 +00:00
|
|
|
|
2022-01-23 00:49:12 +00:00
|
|
|
if let Some(reported) = tcx.sess.has_errors() { Err(reported) } else { Ok(()) }
|
2012-11-29 00:20:41 +00:00
|
|
|
}
|
2015-04-28 02:48:22 +00:00
|
|
|
|
2019-04-11 21:31:34 +00:00
|
|
|
/// A quasi-deprecated helper used in rustdoc and clippy to get
|
2017-05-03 15:28:22 +00:00
|
|
|
/// the type from a HIR node.
|
2019-12-01 15:08:58 +00:00
|
|
|
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
2019-02-28 22:43:53 +00:00
|
|
|
// In case there are any projections, etc., find the "environment"
|
|
|
|
// def-ID that will be used to determine the traits/predicates in
|
2022-11-16 20:34:16 +00:00
|
|
|
// scope. This is derived from the enclosing item-like thing.
|
2021-10-21 17:41:47 +00:00
|
|
|
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
2023-03-13 19:06:41 +00:00
|
|
|
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.def_id);
|
2023-01-11 18:58:44 +00:00
|
|
|
item_cx.astconv().ast_ty_to_ty(hir_ty)
|
2017-11-18 15:49:37 +00:00
|
|
|
}
|
|
|
|
|
2019-12-01 15:08:58 +00:00
|
|
|
pub fn hir_trait_to_predicates<'tcx>(
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
hir_trait: &hir::TraitRef<'_>,
|
2020-04-07 00:03:54 +00:00
|
|
|
self_ty: Ty<'tcx>,
|
2019-12-01 15:08:58 +00:00
|
|
|
) -> Bounds<'tcx> {
|
2019-02-28 22:43:53 +00:00
|
|
|
// In case there are any projections, etc., find the "environment"
|
|
|
|
// def-ID that will be used to determine the traits/predicates in
|
2022-11-16 20:34:16 +00:00
|
|
|
// scope. This is derived from the enclosing item-like thing.
|
2021-10-21 17:41:47 +00:00
|
|
|
let env_def_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id);
|
2023-03-13 19:06:41 +00:00
|
|
|
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.def_id);
|
2019-03-16 00:04:02 +00:00
|
|
|
let mut bounds = Bounds::default();
|
2023-01-11 18:58:44 +00:00
|
|
|
let _ = &item_cx.astconv().instantiate_poly_trait_ref(
|
2019-06-17 23:02:26 +00:00
|
|
|
hir_trait,
|
|
|
|
DUMMY_SP,
|
2021-08-27 05:02:23 +00:00
|
|
|
ty::BoundConstness::NotConst,
|
2023-04-25 05:15:50 +00:00
|
|
|
ty::ImplPolarity::Positive,
|
2020-04-07 00:03:54 +00:00
|
|
|
self_ty,
|
2019-06-17 23:02:26 +00:00
|
|
|
&mut bounds,
|
|
|
|
true,
|
2023-04-18 23:55:05 +00:00
|
|
|
OnlySelfBounds(false),
|
2017-11-18 15:49:37 +00:00
|
|
|
);
|
2018-09-26 15:32:23 +00:00
|
|
|
|
2019-06-17 23:02:26 +00:00
|
|
|
bounds
|
2017-05-03 15:28:22 +00:00
|
|
|
}
|