Remove double spaces after dots in comments
This commit is contained in:
parent
279f1c9d8c
commit
6a28fb42a8
157 changed files with 313 additions and 313 deletions
|
@ -1263,8 +1263,8 @@ pub enum Variants<V: Idx> {
|
||||||
|
|
||||||
/// Enum-likes with more than one inhabited variant: each variant comes with
|
/// Enum-likes with more than one inhabited variant: each variant comes with
|
||||||
/// a *discriminant* (usually the same as the variant index but the user can
|
/// a *discriminant* (usually the same as the variant index but the user can
|
||||||
/// assign explicit discriminant values). That discriminant is encoded
|
/// assign explicit discriminant values). That discriminant is encoded
|
||||||
/// as a *tag* on the machine. The layout of each variant is
|
/// as a *tag* on the machine. The layout of each variant is
|
||||||
/// a struct, and they all have space reserved for the tag.
|
/// a struct, and they all have space reserved for the tag.
|
||||||
/// For enums, the tag is the sole field of the layout.
|
/// For enums, the tag is the sole field of the layout.
|
||||||
Multiple {
|
Multiple {
|
||||||
|
|
|
@ -304,7 +304,7 @@ impl ExprPrecedence {
|
||||||
| ExprPrecedence::Yeet => PREC_JUMP,
|
| ExprPrecedence::Yeet => PREC_JUMP,
|
||||||
|
|
||||||
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
|
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
|
||||||
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
|
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
|
||||||
// ensures that `pprust` will add parentheses in the right places to get the desired
|
// ensures that `pprust` will add parentheses in the right places to get the desired
|
||||||
// parse.
|
// parse.
|
||||||
ExprPrecedence::Range => PREC_RANGE,
|
ExprPrecedence::Range => PREC_RANGE,
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub(super) fn index_hir<'hir>(
|
||||||
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, FxHashMap<LocalDefId, ItemLocalId>) {
|
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, FxHashMap<LocalDefId, ItemLocalId>) {
|
||||||
let mut nodes = IndexVec::new();
|
let mut nodes = IndexVec::new();
|
||||||
// This node's parent should never be accessed: the owner's parent is computed by the
|
// This node's parent should never be accessed: the owner's parent is computed by the
|
||||||
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
|
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
|
||||||
// used.
|
// used.
|
||||||
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
|
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
|
||||||
let mut collector = NodeCollector {
|
let mut collector = NodeCollector {
|
||||||
|
|
|
@ -523,7 +523,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
//
|
//
|
||||||
// The first two are produced by recursively invoking
|
// The first two are produced by recursively invoking
|
||||||
// `lower_use_tree` (and indeed there may be things
|
// `lower_use_tree` (and indeed there may be things
|
||||||
// like `use foo::{a::{b, c}}` and so forth). They
|
// like `use foo::{a::{b, c}}` and so forth). They
|
||||||
// wind up being directly added to
|
// wind up being directly added to
|
||||||
// `self.items`. However, the structure of this
|
// `self.items`. However, the structure of this
|
||||||
// function also requires us to return one item, and
|
// function also requires us to return one item, and
|
||||||
|
|
|
@ -663,7 +663,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
|
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
|
||||||
/// queries which depend on the full HIR tree and those which only depend on the item signature.
|
/// queries which depend on the full HIR tree and those which only depend on the item signature.
|
||||||
fn hash_owner(
|
fn hash_owner(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1194,7 +1194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
itctx: &ImplTraitContext,
|
itctx: &ImplTraitContext,
|
||||||
) -> hir::Ty<'hir> {
|
) -> hir::Ty<'hir> {
|
||||||
// Check whether we should interpret this as a bare trait object.
|
// Check whether we should interpret this as a bare trait object.
|
||||||
// This check mirrors the one in late resolution. We only introduce this special case in
|
// This check mirrors the one in late resolution. We only introduce this special case in
|
||||||
// the rare occurrence we need to lower `Fresh` anonymous lifetimes.
|
// the rare occurrence we need to lower `Fresh` anonymous lifetimes.
|
||||||
// The other cases when a qpath should be opportunistically made a trait object are handled
|
// The other cases when a qpath should be opportunistically made a trait object are handled
|
||||||
// by `ty_path`.
|
// by `ty_path`.
|
||||||
|
@ -1919,7 +1919,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
this.with_remapping(new_remapping, |this| {
|
this.with_remapping(new_remapping, |this| {
|
||||||
// We have to be careful to get elision right here. The
|
// We have to be careful to get elision right here. The
|
||||||
// idea is that we create a lifetime parameter for each
|
// idea is that we create a lifetime parameter for each
|
||||||
// lifetime in the return type. So, given a return type
|
// lifetime in the return type. So, given a return type
|
||||||
// like `async fn foo(..) -> &[&u32]`, we lower to `impl
|
// like `async fn foo(..) -> &[&u32]`, we lower to `impl
|
||||||
// Future<Output = &'1 [ &'2 u32 ]>`.
|
// Future<Output = &'1 [ &'2 u32 ]>`.
|
||||||
//
|
//
|
||||||
|
@ -2013,7 +2013,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
// Create the `Foo<...>` reference itself. Note that the `type
|
// Create the `Foo<...>` reference itself. Note that the `type
|
||||||
// Foo = impl Trait` is, internally, created as a child of the
|
// Foo = impl Trait` is, internally, created as a child of the
|
||||||
// async fn, so the *type parameters* are inherited. It's
|
// async fn, so the *type parameters* are inherited. It's
|
||||||
// only the lifetime parameters that we must supply.
|
// only the lifetime parameters that we must supply.
|
||||||
let opaque_ty_ref = hir::TyKind::OpaqueDef(
|
let opaque_ty_ref = hir::TyKind::OpaqueDef(
|
||||||
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
|
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
|
||||||
|
|
|
@ -473,10 +473,10 @@ impl<'a> State<'a> {
|
||||||
self.word("]");
|
self.word("]");
|
||||||
}
|
}
|
||||||
ast::ExprKind::Range(start, end, limits) => {
|
ast::ExprKind::Range(start, end, limits) => {
|
||||||
// Special case for `Range`. `AssocOp` claims that `Range` has higher precedence
|
// Special case for `Range`. `AssocOp` claims that `Range` has higher precedence
|
||||||
// than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`.
|
// than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`.
|
||||||
// Here we use a fake precedence value so that any child with lower precedence than
|
// Here we use a fake precedence value so that any child with lower precedence than
|
||||||
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
||||||
let fake_prec = AssocOp::LOr.precedence() as i8;
|
let fake_prec = AssocOp::LOr.precedence() as i8;
|
||||||
if let Some(e) = start {
|
if let Some(e) = start {
|
||||||
self.print_expr_maybe_paren(e, fake_prec);
|
self.print_expr_maybe_paren(e, fake_prec);
|
||||||
|
|
|
@ -2173,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// `self.foo` -- we want to double
|
// `self.foo` -- we want to double
|
||||||
// check that the location `*self`
|
// check that the location `*self`
|
||||||
// is mutable (i.e., this is not a
|
// is mutable (i.e., this is not a
|
||||||
// `Fn` closure). But if that
|
// `Fn` closure). But if that
|
||||||
// check succeeds, we want to
|
// check succeeds, we want to
|
||||||
// *blame* the mutability on
|
// *blame* the mutability on
|
||||||
// `place` (that is,
|
// `place` (that is,
|
||||||
|
|
|
@ -109,7 +109,7 @@ where
|
||||||
R1: Copy + Hash + Eq,
|
R1: Copy + Hash + Eq,
|
||||||
{
|
{
|
||||||
/// Remap the "member region" key using `map_fn`, producing a new
|
/// Remap the "member region" key using `map_fn`, producing a new
|
||||||
/// member constraint set. This is used in the NLL code to map from
|
/// member constraint set. This is used in the NLL code to map from
|
||||||
/// the original `RegionVid` to an scc index. In some cases, we
|
/// the original `RegionVid` to an scc index. In some cases, we
|
||||||
/// may have multiple `R1` values mapping to the same `R2` key -- that
|
/// may have multiple `R1` values mapping to the same `R2` key -- that
|
||||||
/// is ok, the two sets will be merged.
|
/// is ok, the two sets will be merged.
|
||||||
|
@ -158,7 +158,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate down the constraint indices associated with a given
|
/// Iterate down the constraint indices associated with a given
|
||||||
/// peek-region. You can then use `choice_regions` and other
|
/// peek-region. You can then use `choice_regions` and other
|
||||||
/// methods to access data.
|
/// methods to access data.
|
||||||
pub(crate) fn indices(
|
pub(crate) fn indices(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -385,7 +385,7 @@ pub(super) fn dump_annotation<'tcx>(
|
||||||
|
|
||||||
// When the enclosing function is tagged with `#[rustc_regions]`,
|
// When the enclosing function is tagged with `#[rustc_regions]`,
|
||||||
// we dump out various bits of state as warnings. This is useful
|
// we dump out various bits of state as warnings. This is useful
|
||||||
// for verifying that the compiler is behaving as expected. These
|
// for verifying that the compiler is behaving as expected. These
|
||||||
// warnings focus on the closure region requirements -- for
|
// warnings focus on the closure region requirements -- for
|
||||||
// viewing the intraprocedural state, the -Zdump-mir output is
|
// viewing the intraprocedural state, the -Zdump-mir output is
|
||||||
// better.
|
// better.
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
||||||
ty::RawPtr(..) | ty::Ref(_, _, hir::Mutability::Not) => {
|
ty::RawPtr(..) | ty::Ref(_, _, hir::Mutability::Not) => {
|
||||||
// For both derefs of raw pointers and `&T`
|
// For both derefs of raw pointers and `&T`
|
||||||
// references, the original path is `Copy` and
|
// references, the original path is `Copy` and
|
||||||
// therefore not significant. In particular,
|
// therefore not significant. In particular,
|
||||||
// there is nothing the user can do to the
|
// there is nothing the user can do to the
|
||||||
// original path that would invalidate the
|
// original path that would invalidate the
|
||||||
// newly created reference -- and if there
|
// newly created reference -- and if there
|
||||||
|
|
|
@ -680,7 +680,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
/// enforce the constraint).
|
/// enforce the constraint).
|
||||||
///
|
///
|
||||||
/// The current value of `scc` at the time the method is invoked
|
/// The current value of `scc` at the time the method is invoked
|
||||||
/// is considered a *lower bound*. If possible, we will modify
|
/// is considered a *lower bound*. If possible, we will modify
|
||||||
/// the constraint to set it equal to one of the option regions.
|
/// the constraint to set it equal to one of the option regions.
|
||||||
/// If we make any changes, returns true, else false.
|
/// If we make any changes, returns true, else false.
|
||||||
#[instrument(skip(self, member_constraint_index), level = "debug")]
|
#[instrument(skip(self, member_constraint_index), level = "debug")]
|
||||||
|
@ -959,7 +959,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
//
|
//
|
||||||
// This is needed because -- particularly in the case
|
// This is needed because -- particularly in the case
|
||||||
// where `ur` is a local bound -- we are sometimes in a
|
// where `ur` is a local bound -- we are sometimes in a
|
||||||
// position to prove things that our caller cannot. See
|
// position to prove things that our caller cannot. See
|
||||||
// #53570 for an example.
|
// #53570 for an example.
|
||||||
if self.eval_verify_bound(infcx, param_env, generic_ty, ur, &type_test.verify_bound) {
|
if self.eval_verify_bound(infcx, param_env, generic_ty, ur, &type_test.verify_bound) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2035,7 +2035,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
// '5: '6 ('6 is the target)
|
// '5: '6 ('6 is the target)
|
||||||
//
|
//
|
||||||
// Some of those regions are unified with `'6` (in the same
|
// Some of those regions are unified with `'6` (in the same
|
||||||
// SCC). We want to screen those out. After that point, the
|
// SCC). We want to screen those out. After that point, the
|
||||||
// "closest" constraint we have to the end is going to be the
|
// "closest" constraint we have to the end is going to be the
|
||||||
// most likely to be the point where the value escapes -- but
|
// most likely to be the point where the value escapes -- but
|
||||||
// we still want to screen for an "interesting" point to
|
// we still want to screen for an "interesting" point to
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||||
closure_substs: ty::SubstsRef<'tcx>,
|
closure_substs: ty::SubstsRef<'tcx>,
|
||||||
) {
|
) {
|
||||||
// Extract the values of the free regions in `closure_substs`
|
// Extract the values of the free regions in `closure_substs`
|
||||||
// into a vector. These are the regions that we will be
|
// into a vector. These are the regions that we will be
|
||||||
// relating to one another.
|
// relating to one another.
|
||||||
let closure_mapping = &UniversalRegions::closure_mapping(
|
let closure_mapping = &UniversalRegions::closure_mapping(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
|
|
@ -98,7 +98,7 @@ impl UniversalRegionRelations<'_> {
|
||||||
let upper_bounds = self.non_local_upper_bounds(fr);
|
let upper_bounds = self.non_local_upper_bounds(fr);
|
||||||
|
|
||||||
// In case we find more than one, reduce to one for
|
// In case we find more than one, reduce to one for
|
||||||
// convenience. This is to prevent us from generating more
|
// convenience. This is to prevent us from generating more
|
||||||
// complex constraints, but it will cause spurious errors.
|
// complex constraints, but it will cause spurious errors.
|
||||||
let post_dom = self.inverse_outlives.mutual_immediate_postdominator(upper_bounds);
|
let post_dom = self.inverse_outlives.mutual_immediate_postdominator(upper_bounds);
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ impl UniversalRegionRelations<'_> {
|
||||||
let lower_bounds = self.non_local_bounds(&self.outlives, fr);
|
let lower_bounds = self.non_local_bounds(&self.outlives, fr);
|
||||||
|
|
||||||
// In case we find more than one, reduce to one for
|
// In case we find more than one, reduce to one for
|
||||||
// convenience. This is to prevent us from generating more
|
// convenience. This is to prevent us from generating more
|
||||||
// complex constraints, but it will cause spurious errors.
|
// complex constraints, but it will cause spurious errors.
|
||||||
let post_dom = self.outlives.mutual_immediate_postdominator(lower_bounds);
|
let post_dom = self.outlives.mutual_immediate_postdominator(lower_bounds);
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||||
debug_assert!(self.drop_live_at.contains(term_point));
|
debug_assert!(self.drop_live_at.contains(term_point));
|
||||||
|
|
||||||
// Otherwise, scan backwards through the statements in the
|
// Otherwise, scan backwards through the statements in the
|
||||||
// block. One of them may be either a definition or use
|
// block. One of them may be either a definition or use
|
||||||
// live point.
|
// live point.
|
||||||
let term_location = self.cx.elements.to_location(term_point);
|
let term_location = self.cx.elements.to_location(term_point);
|
||||||
debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,);
|
debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,);
|
||||||
|
|
|
@ -1665,7 +1665,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
|
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
// Erase the regions from `ty` to get a global type. The
|
// Erase the regions from `ty` to get a global type. The
|
||||||
// `Sized` bound in no way depends on precise regions, so this
|
// `Sized` bound in no way depends on precise regions, so this
|
||||||
// shouldn't affect `is_sized`.
|
// shouldn't affect `is_sized`.
|
||||||
let erased_ty = tcx.erase_regions(ty);
|
let erased_ty = tcx.erase_regions(ty);
|
||||||
|
|
|
@ -637,7 +637,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
||||||
|
|
||||||
// The "inputs" of the closure in the
|
// The "inputs" of the closure in the
|
||||||
// signature appear as a tuple. The MIR side
|
// signature appear as a tuple. The MIR side
|
||||||
// flattens this tuple.
|
// flattens this tuple.
|
||||||
let (&output, tuplized_inputs) =
|
let (&output, tuplized_inputs) =
|
||||||
inputs_and_output.skip_binder().split_last().unwrap();
|
inputs_and_output.skip_binder().split_last().unwrap();
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn expand_deriving_clone(
|
||||||
// some additional `AssertParamIsClone` assertions.
|
// some additional `AssertParamIsClone` assertions.
|
||||||
//
|
//
|
||||||
// We can use the simple form if either of the following are true.
|
// We can use the simple form if either of the following are true.
|
||||||
// - The type derives Copy and there are no generic parameters. (If we
|
// - The type derives Copy and there are no generic parameters. (If we
|
||||||
// used the simple form with generics, we'd have to bound the generics
|
// used the simple form with generics, we'd have to bound the generics
|
||||||
// with Clone + Copy, and then there'd be no Clone impl at all if the
|
// with Clone + Copy, and then there'd be no Clone impl at all if the
|
||||||
// user fills in something that is Clone but not Copy. After
|
// user fills in something that is Clone but not Copy. After
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// The compiler code necessary to support the env! extension. Eventually this
|
// The compiler code necessary to support the env! extension. Eventually this
|
||||||
// should all get sucked into either the compiler syntax extension plugin
|
// should all get sucked into either the compiler syntax extension plugin
|
||||||
// interface.
|
// interface.
|
||||||
//
|
//
|
||||||
|
|
|
@ -583,7 +583,7 @@ fn report_missing_placeholders(
|
||||||
if detect_foreign_fmt {
|
if detect_foreign_fmt {
|
||||||
use super::format_foreign as foreign;
|
use super::format_foreign as foreign;
|
||||||
|
|
||||||
// The set of foreign substitutions we've explained. This prevents spamming the user
|
// The set of foreign substitutions we've explained. This prevents spamming the user
|
||||||
// with `%d should be written as {}` over and over again.
|
// with `%d should be written as {}` over and over again.
|
||||||
let mut explained = FxHashSet::default();
|
let mut explained = FxHashSet::default();
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ pub(crate) mod printf {
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
pub enum Num {
|
pub enum Num {
|
||||||
// The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
|
// The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
|
||||||
// libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
|
// libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
|
||||||
// is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
|
// is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
|
||||||
// with more precision, than 32 thousand positions which is so wide it couldn't possibly fit
|
// with more precision, than 32 thousand positions which is so wide it couldn't possibly fit
|
||||||
// on a screen.
|
// on a screen.
|
||||||
|
|
|
@ -304,7 +304,7 @@ fn data_id_for_static(
|
||||||
|
|
||||||
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
||||||
// Declare an internal global `extern_with_linkage_foo` which
|
// Declare an internal global `extern_with_linkage_foo` which
|
||||||
// is initialized with the address of `foo`. If `foo` is
|
// is initialized with the address of `foo`. If `foo` is
|
||||||
// discarded during linking (for example, if `foo` has weak
|
// discarded during linking (for example, if `foo` has weak
|
||||||
// linkage and there are no definitions), then
|
// linkage and there are no definitions), then
|
||||||
// `extern_with_linkage_foo` will instead be initialized to
|
// `extern_with_linkage_foo` will instead be initialized to
|
||||||
|
|
|
@ -221,7 +221,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
bx.store(val, cast_dst, self.layout.align.abi);
|
bx.store(val, cast_dst, self.layout.align.abi);
|
||||||
} else {
|
} else {
|
||||||
// The actual return type is a struct, but the ABI
|
// The actual return type is a struct, but the ABI
|
||||||
// adaptation code has cast it into some scalar type. The
|
// adaptation code has cast it into some scalar type. The
|
||||||
// code that follows is the only reliable way I have
|
// code that follows is the only reliable way I have
|
||||||
// found to do a transform like i64 -> {i32,i32}.
|
// found to do a transform like i64 -> {i32,i32}.
|
||||||
// Basically we dump the data onto the stack then memcpy it.
|
// Basically we dump the data onto the stack then memcpy it.
|
||||||
|
|
|
@ -445,7 +445,7 @@ pub(crate) fn inline_asm_call<'ll>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store mark in a metadata node so we can map LLVM errors
|
// Store mark in a metadata node so we can map LLVM errors
|
||||||
// back to source locations. See #17552.
|
// back to source locations. See #17552.
|
||||||
let key = "srcloc";
|
let key = "srcloc";
|
||||||
let kind = llvm::LLVMGetMDKindIDInContext(
|
let kind = llvm::LLVMGetMDKindIDInContext(
|
||||||
bx.llcx,
|
bx.llcx,
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
||||||
// The binutils linker used on -windows-gnu targets cannot read the import
|
// The binutils linker used on -windows-gnu targets cannot read the import
|
||||||
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
||||||
// that loaded but crashed with an AV upon calling one of the imported
|
// that loaded but crashed with an AV upon calling one of the imported
|
||||||
// functions. Therefore, use binutils to create the import library instead,
|
// functions. Therefore, use binutils to create the import library instead,
|
||||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
||||||
let def_file_path =
|
let def_file_path =
|
||||||
tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def");
|
tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def");
|
||||||
|
@ -219,7 +219,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
||||||
|
|
||||||
// All import names are Rust identifiers and therefore cannot contain \0 characters.
|
// All import names are Rust identifiers and therefore cannot contain \0 characters.
|
||||||
// FIXME: when support for #[link_name] is implemented, ensure that the import names
|
// FIXME: when support for #[link_name] is implemented, ensure that the import names
|
||||||
// still don't contain any \0 characters. Also need to check that the names don't
|
// still don't contain any \0 characters. Also need to check that the names don't
|
||||||
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
|
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
|
||||||
// in definition files.
|
// in definition files.
|
||||||
let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
|
let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
|
||||||
|
@ -433,7 +433,7 @@ fn find_binutils_dlltool(sess: &Session) -> OsString {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The user didn't specify the location of the dlltool binary, and we weren't able
|
// The user didn't specify the location of the dlltool binary, and we weren't able
|
||||||
// to find the appropriate one on the PATH. Just return the name of the tool
|
// to find the appropriate one on the PATH. Just return the name of the tool
|
||||||
// and let the invocation fail with a hopefully useful error message.
|
// and let the invocation fail with a hopefully useful error message.
|
||||||
tool_name
|
tool_name
|
||||||
}
|
}
|
||||||
|
|
|
@ -909,7 +909,7 @@ unsafe fn embed_bitcode(
|
||||||
|
|
||||||
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
|
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
|
||||||
// This is required to satisfy `dllimport` references to static data in .rlibs
|
// This is required to satisfy `dllimport` references to static data in .rlibs
|
||||||
// when using MSVC linker. We do this only for data, as linker can fix up
|
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||||
// code references on its own.
|
// code references on its own.
|
||||||
// See #26591, #27438
|
// See #26591, #27438
|
||||||
fn create_msvc_imps(
|
fn create_msvc_imps(
|
||||||
|
|
|
@ -49,8 +49,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
||||||
let llptrty = fn_abi.ptr_to_llvm_type(cx);
|
let llptrty = fn_abi.ptr_to_llvm_type(cx);
|
||||||
|
|
||||||
// This is subtle and surprising, but sometimes we have to bitcast
|
// This is subtle and surprising, but sometimes we have to bitcast
|
||||||
// the resulting fn pointer. The reason has to do with external
|
// the resulting fn pointer. The reason has to do with external
|
||||||
// functions. If you have two crates that both bind the same C
|
// functions. If you have two crates that both bind the same C
|
||||||
// library, they may not use precisely the same types: for
|
// library, they may not use precisely the same types: for
|
||||||
// example, they will probably each declare their own structs,
|
// example, they will probably each declare their own structs,
|
||||||
// which are distinct types from LLVM's point of view (nominal
|
// which are distinct types from LLVM's point of view (nominal
|
||||||
|
|
|
@ -140,7 +140,7 @@ pub fn codegen_static_initializer<'ll, 'tcx>(
|
||||||
fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Align) {
|
fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Align) {
|
||||||
// The target may require greater alignment for globals than the type does.
|
// The target may require greater alignment for globals than the type does.
|
||||||
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
|
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
|
||||||
// which can force it to be smaller. Rust doesn't support this yet.
|
// which can force it to be smaller. Rust doesn't support this yet.
|
||||||
if let Some(min) = cx.sess().target.min_global_align {
|
if let Some(min) = cx.sess().target.min_global_align {
|
||||||
match Align::from_bits(min) {
|
match Align::from_bits(min) {
|
||||||
Ok(min) => align = align.max(min),
|
Ok(min) => align = align.max(min),
|
||||||
|
@ -171,7 +171,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
|
||||||
llvm::LLVMRustSetLinkage(g1, base::linkage_to_llvm(linkage));
|
llvm::LLVMRustSetLinkage(g1, base::linkage_to_llvm(linkage));
|
||||||
|
|
||||||
// Declare an internal global `extern_with_linkage_foo` which
|
// Declare an internal global `extern_with_linkage_foo` which
|
||||||
// is initialized with the address of `foo`. If `foo` is
|
// is initialized with the address of `foo`. If `foo` is
|
||||||
// discarded during linking (for example, if `foo` has weak
|
// discarded during linking (for example, if `foo` has weak
|
||||||
// linkage and there are no definitions), then
|
// linkage and there are no definitions), then
|
||||||
// `extern_with_linkage_foo` will instead be initialized to
|
// `extern_with_linkage_foo` will instead be initialized to
|
||||||
|
|
|
@ -654,7 +654,7 @@ fn codegen_gnu_try<'ll>(
|
||||||
// Type indicator for the exception being thrown.
|
// Type indicator for the exception being thrown.
|
||||||
//
|
//
|
||||||
// The first value in this tuple is a pointer to the exception object
|
// The first value in this tuple is a pointer to the exception object
|
||||||
// being thrown. The second value is a "selector" indicating which of
|
// being thrown. The second value is a "selector" indicating which of
|
||||||
// the landing pad clauses the exception's type had been matched to.
|
// the landing pad clauses the exception's type had been matched to.
|
||||||
// rust_try ignores the selector.
|
// rust_try ignores the selector.
|
||||||
bx.switch_to_block(catch);
|
bx.switch_to_block(catch);
|
||||||
|
@ -718,7 +718,7 @@ fn codegen_emcc_try<'ll>(
|
||||||
// Type indicator for the exception being thrown.
|
// Type indicator for the exception being thrown.
|
||||||
//
|
//
|
||||||
// The first value in this tuple is a pointer to the exception object
|
// The first value in this tuple is a pointer to the exception object
|
||||||
// being thrown. The second value is a "selector" indicating which of
|
// being thrown. The second value is a "selector" indicating which of
|
||||||
// the landing pad clauses the exception's type had been matched to.
|
// the landing pad clauses the exception's type had been matched to.
|
||||||
bx.switch_to_block(catch);
|
bx.switch_to_block(catch);
|
||||||
let tydesc = bx.eh_catch_typeinfo();
|
let tydesc = bx.eh_catch_typeinfo();
|
||||||
|
|
|
@ -352,10 +352,10 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
||||||
let scalar = [a, b][index];
|
let scalar = [a, b][index];
|
||||||
|
|
||||||
// Make sure to return the same type `immediate_llvm_type` would when
|
// Make sure to return the same type `immediate_llvm_type` would when
|
||||||
// dealing with an immediate pair. This means that `(bool, bool)` is
|
// dealing with an immediate pair. This means that `(bool, bool)` is
|
||||||
// effectively represented as `{i8, i8}` in memory and two `i1`s as an
|
// effectively represented as `{i8, i8}` in memory and two `i1`s as an
|
||||||
// immediate, just like `bool` is typically `i8` in memory and only `i1`
|
// immediate, just like `bool` is typically `i8` in memory and only `i1`
|
||||||
// when immediate. We need to load/store `bool` as `i8` to avoid
|
// when immediate. We need to load/store `bool` as `i8` to avoid
|
||||||
// crippling LLVM optimizations or triggering other LLVM bugs with `i1`.
|
// crippling LLVM optimizations or triggering other LLVM bugs with `i1`.
|
||||||
if immediate && scalar.is_bool() {
|
if immediate && scalar.is_bool() {
|
||||||
return cx.type_i1();
|
return cx.type_i1();
|
||||||
|
|
|
@ -445,7 +445,7 @@ fn link_rlib<'a>(
|
||||||
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
|
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
|
||||||
///
|
///
|
||||||
/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
|
/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
|
||||||
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
|
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
|
||||||
/// linker appears to expect only a single import library for each library used, so we need to
|
/// linker appears to expect only a single import library for each library used, so we need to
|
||||||
/// collate the symbols together by library name before generating the import libraries.
|
/// collate the symbols together by library name before generating the import libraries.
|
||||||
fn collate_raw_dylibs<'a, 'b>(
|
fn collate_raw_dylibs<'a, 'b>(
|
||||||
|
@ -1197,7 +1197,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
||||||
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
|
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
|
||||||
// On historical Solaris systems, "cc" may have
|
// On historical Solaris systems, "cc" may have
|
||||||
// been Sun Studio, which is not flag-compatible
|
// been Sun Studio, which is not flag-compatible
|
||||||
// with "gcc". This history casts a long shadow,
|
// with "gcc". This history casts a long shadow,
|
||||||
// and many modern illumos distributions today
|
// and many modern illumos distributions today
|
||||||
// ship GCC as "gcc" without also making it
|
// ship GCC as "gcc" without also making it
|
||||||
// available as "cc".
|
// available as "cc".
|
||||||
|
|
|
@ -544,7 +544,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
// link times negatively.
|
// link times negatively.
|
||||||
//
|
//
|
||||||
// -dead_strip can't be part of the pre_link_args because it's also used
|
// -dead_strip can't be part of the pre_link_args because it's also used
|
||||||
// for partial linking when using multiple codegen units (-r). So we
|
// for partial linking when using multiple codegen units (-r). So we
|
||||||
// insert it here.
|
// insert it here.
|
||||||
if self.sess.target.is_like_osx {
|
if self.sess.target.is_like_osx {
|
||||||
self.linker_arg("-dead_strip");
|
self.linker_arg("-dead_strip");
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub struct ModuleConfig {
|
||||||
pub emit_thin_lto: bool,
|
pub emit_thin_lto: bool,
|
||||||
pub bc_cmdline: String,
|
pub bc_cmdline: String,
|
||||||
|
|
||||||
// Miscellaneous flags. These are mostly copied from command-line
|
// Miscellaneous flags. These are mostly copied from command-line
|
||||||
// options.
|
// options.
|
||||||
pub verify_llvm_ir: bool,
|
pub verify_llvm_ir: bool,
|
||||||
pub no_prepopulate_passes: bool,
|
pub no_prepopulate_passes: bool,
|
||||||
|
@ -538,7 +538,7 @@ fn produce_final_output_artifacts(
|
||||||
|
|
||||||
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
|
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
|
||||||
if compiled_modules.modules.len() == 1 {
|
if compiled_modules.modules.len() == 1 {
|
||||||
// 1) Only one codegen unit. In this case it's no difficulty
|
// 1) Only one codegen unit. In this case it's no difficulty
|
||||||
// to copy `foo.0.x` to `foo.x`.
|
// to copy `foo.0.x` to `foo.x`.
|
||||||
let module_name = Some(&compiled_modules.modules[0].name[..]);
|
let module_name = Some(&compiled_modules.modules[0].name[..]);
|
||||||
let path = crate_output.temp_path(output_type, module_name);
|
let path = crate_output.temp_path(output_type, module_name);
|
||||||
|
@ -557,15 +557,15 @@ fn produce_final_output_artifacts(
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
if crate_output.outputs.contains_key(&output_type) {
|
if crate_output.outputs.contains_key(&output_type) {
|
||||||
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
||||||
// no good solution for this case, so warn the user.
|
// no good solution for this case, so warn the user.
|
||||||
sess.emit_warning(errors::IgnoringEmitPath { extension });
|
sess.emit_warning(errors::IgnoringEmitPath { extension });
|
||||||
} else if crate_output.single_output_file.is_some() {
|
} else if crate_output.single_output_file.is_some() {
|
||||||
// 3) Multiple codegen units, with `-o some_name`. We have
|
// 3) Multiple codegen units, with `-o some_name`. We have
|
||||||
// no good solution for this case, so warn the user.
|
// no good solution for this case, so warn the user.
|
||||||
sess.emit_warning(errors::IgnoringOutput { extension });
|
sess.emit_warning(errors::IgnoringOutput { extension });
|
||||||
} else {
|
} else {
|
||||||
// 4) Multiple codegen units, but no explicit name. We
|
// 4) Multiple codegen units, but no explicit name. We
|
||||||
// just leave the `foo.0.x` files in place.
|
// just leave the `foo.0.x` files in place.
|
||||||
// (We don't have to do any work in this case.)
|
// (We don't have to do any work in this case.)
|
||||||
}
|
}
|
||||||
|
@ -579,7 +579,7 @@ fn produce_final_output_artifacts(
|
||||||
match *output_type {
|
match *output_type {
|
||||||
OutputType::Bitcode => {
|
OutputType::Bitcode => {
|
||||||
user_wants_bitcode = true;
|
user_wants_bitcode = true;
|
||||||
// Copy to .bc, but always keep the .0.bc. There is a later
|
// Copy to .bc, but always keep the .0.bc. There is a later
|
||||||
// check to figure out if we should delete .0.bc files, or keep
|
// check to figure out if we should delete .0.bc files, or keep
|
||||||
// them for making an rlib.
|
// them for making an rlib.
|
||||||
copy_if_one_unit(OutputType::Bitcode, true);
|
copy_if_one_unit(OutputType::Bitcode, true);
|
||||||
|
@ -611,7 +611,7 @@ fn produce_final_output_artifacts(
|
||||||
// `-C save-temps` or `--emit=` flags).
|
// `-C save-temps` or `--emit=` flags).
|
||||||
|
|
||||||
if !sess.opts.cg.save_temps {
|
if !sess.opts.cg.save_temps {
|
||||||
// Remove the temporary .#module-name#.o objects. If the user didn't
|
// Remove the temporary .#module-name#.o objects. If the user didn't
|
||||||
// explicitly request bitcode (with --emit=bc), and the bitcode is not
|
// explicitly request bitcode (with --emit=bc), and the bitcode is not
|
||||||
// needed for building an rlib, then we must remove .#module-name#.bc as
|
// needed for building an rlib, then we must remove .#module-name#.bc as
|
||||||
// well.
|
// well.
|
||||||
|
|
|
@ -658,13 +658,13 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
|
||||||
sole_meta_list
|
sole_meta_list
|
||||||
{
|
{
|
||||||
// According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
|
// According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
|
||||||
// the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
|
// the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
|
||||||
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
|
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
|
||||||
// to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
|
// to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
|
||||||
//
|
//
|
||||||
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for this:
|
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for this:
|
||||||
// both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies
|
// both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies
|
||||||
// a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library
|
// a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library
|
||||||
// for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import
|
// for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import
|
||||||
// library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I don't know yet
|
// library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I don't know yet
|
||||||
// if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
|
// if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
|
||||||
|
|
|
@ -57,9 +57,9 @@ pub struct DebugScope<S, L> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
|
impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
|
||||||
/// DILocations inherit source file name from the parent DIScope. Due to macro expansions
|
/// DILocations inherit source file name from the parent DIScope. Due to macro expansions
|
||||||
/// it may so happen that the current span belongs to a different file than the DIScope
|
/// it may so happen that the current span belongs to a different file than the DIScope
|
||||||
/// corresponding to span's containing source scope. If so, we need to create a DIScope
|
/// corresponding to span's containing source scope. If so, we need to create a DIScope
|
||||||
/// "extension" into that file.
|
/// "extension" into that file.
|
||||||
pub fn adjust_dbg_scope_for_span<Cx: CodegenMethods<'tcx, DIScope = S, DILocation = L>>(
|
pub fn adjust_dbg_scope_for_span<Cx: CodegenMethods<'tcx, DIScope = S, DILocation = L>>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -408,7 +408,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||||
// Only check non-glue functions
|
// Only check non-glue functions
|
||||||
if let ty::InstanceDef::Item(def) = instance.def {
|
if let ty::InstanceDef::Item(def) = instance.def {
|
||||||
// Execution might have wandered off into other crates, so we cannot do a stability-
|
// Execution might have wandered off into other crates, so we cannot do a stability-
|
||||||
// sensitive check here. But we can at least rule out functions that are not const
|
// sensitive check here. But we can at least rule out functions that are not const
|
||||||
// at all.
|
// at all.
|
||||||
if !ecx.tcx.is_const_fn_raw(def.did) {
|
if !ecx.tcx.is_const_fn_raw(def.did) {
|
||||||
// allow calling functions inside a trait marked with #[const_trait].
|
// allow calling functions inside a trait marked with #[const_trait].
|
||||||
|
|
|
@ -196,7 +196,7 @@ impl<'tcx, Prov: Provenance + 'static> LocalState<'tcx, Prov> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overwrite the local. If the local can be overwritten in place, return a reference
|
/// Overwrite the local. If the local can be overwritten in place, return a reference
|
||||||
/// to do so; otherwise return the `MemPlace` to consult instead.
|
/// to do so; otherwise return the `MemPlace` to consult instead.
|
||||||
///
|
///
|
||||||
/// Note: This may only be invoked from the `Machine::access_local_mut` hook and not from
|
/// Note: This may only be invoked from the `Machine::access_local_mut` hook and not from
|
||||||
|
@ -592,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Recurse to get the size of the dynamically sized field (must be
|
// Recurse to get the size of the dynamically sized field (must be
|
||||||
// the last field). Can't have foreign types here, how would we
|
// the last field). Can't have foreign types here, how would we
|
||||||
// adjust alignment and size for them?
|
// adjust alignment and size for them?
|
||||||
let field = layout.field(self, layout.fields.count() - 1);
|
let field = layout.field(self, layout.fields.count() - 1);
|
||||||
let Some((unsized_size, mut unsized_align)) = self.size_and_align_of(metadata, &field)? else {
|
let Some((unsized_size, mut unsized_align)) = self.size_and_align_of(metadata, &field)? else {
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_ev
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)]
|
||||||
enum InternMode {
|
enum InternMode {
|
||||||
/// A static and its current mutability. Below shared references inside a `static mut`,
|
/// A static and its current mutability. Below shared references inside a `static mut`,
|
||||||
/// this is *immutable*, and below mutable references inside an `UnsafeCell`, this
|
/// this is *immutable*, and below mutable references inside an `UnsafeCell`, this
|
||||||
/// is *mutable*.
|
/// is *mutable*.
|
||||||
Static(hir::Mutability),
|
Static(hir::Mutability),
|
||||||
|
@ -296,7 +296,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InternMode::Const => {
|
InternMode::Const => {
|
||||||
// Ignore `UnsafeCell`, everything is immutable. Validity does some sanity
|
// Ignore `UnsafeCell`, everything is immutable. Validity does some sanity
|
||||||
// checking for mutable references that we encounter -- they must all be
|
// checking for mutable references that we encounter -- they must all be
|
||||||
// ZST.
|
// ZST.
|
||||||
InternMode::Const
|
InternMode::Const
|
||||||
|
@ -330,7 +330,7 @@ pub enum InternKind {
|
||||||
|
|
||||||
/// Intern `ret` and everything it references.
|
/// Intern `ret` and everything it references.
|
||||||
///
|
///
|
||||||
/// This *cannot raise an interpreter error*. Doing so is left to validation, which
|
/// This *cannot raise an interpreter error*. Doing so is left to validation, which
|
||||||
/// tracks where in the value we are and thus can show much better error messages.
|
/// tracks where in the value we are and thus can show much better error messages.
|
||||||
#[instrument(level = "debug", skip(ecx))]
|
#[instrument(level = "debug", skip(ecx))]
|
||||||
pub fn intern_const_alloc_recursive<
|
pub fn intern_const_alloc_recursive<
|
||||||
|
@ -379,7 +379,7 @@ pub fn intern_const_alloc_recursive<
|
||||||
inside_unsafe_cell: false,
|
inside_unsafe_cell: false,
|
||||||
}
|
}
|
||||||
.visit_value(&mplace);
|
.visit_value(&mplace);
|
||||||
// We deliberately *ignore* interpreter errors here. When there is a problem, the remaining
|
// We deliberately *ignore* interpreter errors here. When there is a problem, the remaining
|
||||||
// references are "leftover"-interned, and later validation will show a proper error
|
// references are "leftover"-interned, and later validation will show a proper error
|
||||||
// and point at the right part of the value causing the problem.
|
// and point at the right part of the value causing the problem.
|
||||||
match res {
|
match res {
|
||||||
|
@ -454,7 +454,7 @@ pub fn intern_const_alloc_recursive<
|
||||||
return Err(reported);
|
return Err(reported);
|
||||||
} else if ecx.tcx.try_get_global_alloc(alloc_id).is_none() {
|
} else if ecx.tcx.try_get_global_alloc(alloc_id).is_none() {
|
||||||
// We have hit an `AllocId` that is neither in local or global memory and isn't
|
// We have hit an `AllocId` that is neither in local or global memory and isn't
|
||||||
// marked as dangling by local memory. That should be impossible.
|
// marked as dangling by local memory. That should be impossible.
|
||||||
span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id);
|
span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
unwind: StackPopUnwind,
|
unwind: StackPopUnwind,
|
||||||
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>;
|
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>;
|
||||||
|
|
||||||
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction
|
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction
|
||||||
/// pointer as appropriate.
|
/// pointer as appropriate.
|
||||||
fn call_extra_fn(
|
fn call_extra_fn(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
|
@ -439,7 +439,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
|
/// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
|
||||||
/// (CTFE and ConstProp) use the same instance. Here, we share that code.
|
/// (CTFE and ConstProp) use the same instance. Here, we share that code.
|
||||||
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||||
type Provenance = AllocId;
|
type Provenance = AllocId;
|
||||||
type ProvenanceExtra = ();
|
type ProvenanceExtra = ();
|
||||||
|
|
|
@ -146,7 +146,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
|
|
||||||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
/// Call this to turn untagged "global" pointers (obtained via `tcx`) into
|
/// Call this to turn untagged "global" pointers (obtained via `tcx`) into
|
||||||
/// the machine pointer to the allocation. Must never be used
|
/// the machine pointer to the allocation. Must never be used
|
||||||
/// for any other pointers, nor for TLS statics.
|
/// for any other pointers, nor for TLS statics.
|
||||||
///
|
///
|
||||||
/// Using the resulting pointer represents a *direct* access to that memory
|
/// Using the resulting pointer represents a *direct* access to that memory
|
||||||
|
@ -536,7 +536,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
&self,
|
&self,
|
||||||
id: AllocId,
|
id: AllocId,
|
||||||
) -> InterpResult<'tcx, &Allocation<M::Provenance, M::AllocExtra>> {
|
) -> InterpResult<'tcx, &Allocation<M::Provenance, M::AllocExtra>> {
|
||||||
// The error type of the inner closure here is somewhat funny. We have two
|
// The error type of the inner closure here is somewhat funny. We have two
|
||||||
// ways of "erroring": An actual error, or because we got a reference from
|
// ways of "erroring": An actual error, or because we got a reference from
|
||||||
// `get_global_alloc` that we can actually use directly without inserting anything anywhere.
|
// `get_global_alloc` that we can actually use directly without inserting anything anywhere.
|
||||||
// So the error type is `InterpResult<'tcx, &Allocation<M::Provenance>>`.
|
// So the error type is `InterpResult<'tcx, &Allocation<M::Provenance>>`.
|
||||||
|
|
|
@ -488,7 +488,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
Ok(OpTy { op, layout: place.layout, align: Some(place.align) })
|
Ok(OpTy { op, layout: place.layout, align: Some(place.align) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a place with the goal of reading from it. This lets us sometimes
|
/// Evaluate a place with the goal of reading from it. This lets us sometimes
|
||||||
/// avoid allocations.
|
/// avoid allocations.
|
||||||
pub fn eval_place_to_op(
|
pub fn eval_place_to_op(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -233,7 +233,7 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
|
||||||
_ => bug!("len not supported on unsized type {:?}", self.layout.ty),
|
_ => bug!("len not supported on unsized type {:?}", self.layout.ty),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Go through the layout. There are lots of types that support a length,
|
// Go through the layout. There are lots of types that support a length,
|
||||||
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
|
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
|
||||||
match self.layout.fields {
|
match self.layout.fields {
|
||||||
abi::FieldsShape::Array { count, .. } => Ok(count),
|
abi::FieldsShape::Array { count, .. } => Ok(count),
|
||||||
|
@ -294,7 +294,7 @@ where
|
||||||
M: Machine<'mir, 'tcx, Provenance = Prov>,
|
M: Machine<'mir, 'tcx, Provenance = Prov>,
|
||||||
{
|
{
|
||||||
/// Take a value, which represents a (thin or wide) reference, and make it a place.
|
/// Take a value, which represents a (thin or wide) reference, and make it a place.
|
||||||
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
||||||
///
|
///
|
||||||
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
|
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
|
||||||
/// want to ever use the place for memory access!
|
/// want to ever use the place for memory access!
|
||||||
|
@ -703,7 +703,7 @@ where
|
||||||
&mut Operand::Immediate(local_val) => {
|
&mut Operand::Immediate(local_val) => {
|
||||||
// We need to make an allocation.
|
// We need to make an allocation.
|
||||||
|
|
||||||
// We need the layout of the local. We can NOT use the layout we got,
|
// We need the layout of the local. We can NOT use the layout we got,
|
||||||
// that might e.g., be an inner field of a struct with `Scalar` layout,
|
// that might e.g., be an inner field of a struct with `Scalar` layout,
|
||||||
// that has different alignment than the outer field.
|
// that has different alignment than the outer field.
|
||||||
let local_layout =
|
let local_layout =
|
||||||
|
|
|
@ -446,7 +446,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// they go to.
|
// they go to.
|
||||||
|
|
||||||
// For where they come from: If the ABI is RustCall, we untuple the
|
// For where they come from: If the ABI is RustCall, we untuple the
|
||||||
// last incoming argument. These two iterators do not have the same type,
|
// last incoming argument. These two iterators do not have the same type,
|
||||||
// so to keep the code paths uniform we accept an allocation
|
// so to keep the code paths uniform we accept an allocation
|
||||||
// (for RustCall ABI only).
|
// (for RustCall ABI only).
|
||||||
let caller_args: Cow<'_, [OpTy<'tcx, M::Provenance>]> =
|
let caller_args: Cow<'_, [OpTy<'tcx, M::Provenance>]> =
|
||||||
|
@ -481,7 +481,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
.filter(|arg_and_abi| !matches!(arg_and_abi.1.mode, PassMode::Ignore));
|
.filter(|arg_and_abi| !matches!(arg_and_abi.1.mode, PassMode::Ignore));
|
||||||
|
|
||||||
// Now we have to spread them out across the callee's locals,
|
// Now we have to spread them out across the callee's locals,
|
||||||
// taking into account the `spread_arg`. If we could write
|
// taking into account the `spread_arg`. If we could write
|
||||||
// this is a single iterator (that handles `spread_arg`), then
|
// this is a single iterator (that handles `spread_arg`), then
|
||||||
// `pass_argument` would be the loop body. It takes care to
|
// `pass_argument` would be the loop body. It takes care to
|
||||||
// not advance `caller_iter` for ZSTs.
|
// not advance `caller_iter` for ZSTs.
|
||||||
|
@ -648,8 +648,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
unwind: Option<mir::BasicBlock>,
|
unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
trace!("drop_in_place: {:?},\n {:?}, {:?}", *place, place.layout.ty, instance);
|
trace!("drop_in_place: {:?},\n {:?}, {:?}", *place, place.layout.ty, instance);
|
||||||
// We take the address of the object. This may well be unaligned, which is fine
|
// We take the address of the object. This may well be unaligned, which is fine
|
||||||
// for us here. However, unaligned accesses will probably make the actual drop
|
// for us here. However, unaligned accesses will probably make the actual drop
|
||||||
// implementation fail -- a problem shared by rustc.
|
// implementation fail -- a problem shared by rustc.
|
||||||
let place = self.force_allocation(place)?;
|
let place = self.force_allocation(place)?;
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ fn write_path(out: &mut String, path: &[PathElem]) {
|
||||||
TupleElem(idx) => write!(out, ".{}", idx),
|
TupleElem(idx) => write!(out, ".{}", idx),
|
||||||
ArrayElem(idx) => write!(out, "[{}]", idx),
|
ArrayElem(idx) => write!(out, "[{}]", idx),
|
||||||
// `.<deref>` does not match Rust syntax, but it is more readable for long paths -- and
|
// `.<deref>` does not match Rust syntax, but it is more readable for long paths -- and
|
||||||
// some of the other items here also are not Rust syntax. Actually we can't
|
// some of the other items here also are not Rust syntax. Actually we can't
|
||||||
// even use the usual syntax because we are just showing the projections,
|
// even use the usual syntax because we are just showing the projections,
|
||||||
// not the root.
|
// not the root.
|
||||||
Deref => write!(out, ".<deref>"),
|
Deref => write!(out, ".<deref>"),
|
||||||
|
@ -484,7 +484,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if this is a value of primitive type, and if yes check the validity of the value
|
/// Check if this is a value of primitive type, and if yes check the validity of the value
|
||||||
/// at that type. Return `true` if the type is indeed primitive.
|
/// at that type. Return `true` if the type is indeed primitive.
|
||||||
fn try_visit_primitive(
|
fn try_visit_primitive(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: &OpTy<'tcx, M::Provenance>,
|
value: &OpTy<'tcx, M::Provenance>,
|
||||||
|
@ -623,7 +623,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||||
// Can only happen during CTFE.
|
// Can only happen during CTFE.
|
||||||
// We support 2 kinds of ranges here: full range, and excluding zero.
|
// We support 2 kinds of ranges here: full range, and excluding zero.
|
||||||
if start == 1 && end == max_value {
|
if start == 1 && end == max_value {
|
||||||
// Only null is the niche. So make sure the ptr is NOT null.
|
// Only null is the niche. So make sure the ptr is NOT null.
|
||||||
if self.ecx.scalar_may_be_null(scalar)? {
|
if self.ecx.scalar_may_be_null(scalar)? {
|
||||||
throw_validation_failure!(self.path,
|
throw_validation_failure!(self.path,
|
||||||
{ "a potentially null pointer" }
|
{ "a potentially null pointer" }
|
||||||
|
@ -759,7 +759,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||||
// Recursively walk the value at its type.
|
// Recursively walk the value at its type.
|
||||||
self.walk_value(op)?;
|
self.walk_value(op)?;
|
||||||
|
|
||||||
// *After* all of this, check the ABI. We need to check the ABI to handle
|
// *After* all of this, check the ABI. We need to check the ABI to handle
|
||||||
// types like `NonNull` where the `Scalar` info is more restrictive than what
|
// types like `NonNull` where the `Scalar` info is more restrictive than what
|
||||||
// the fields say (`rustc_layout_scalar_valid_range_start`).
|
// the fields say (`rustc_layout_scalar_valid_range_start`).
|
||||||
// But in most cases, this will just propagate what the fields say,
|
// But in most cases, this will just propagate what the fields say,
|
||||||
|
@ -857,10 +857,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||||
// Optimization: we just check the entire range at once.
|
// Optimization: we just check the entire range at once.
|
||||||
// NOTE: Keep this in sync with the handling of integer and float
|
// NOTE: Keep this in sync with the handling of integer and float
|
||||||
// types above, in `visit_primitive`.
|
// types above, in `visit_primitive`.
|
||||||
// In run-time mode, we accept pointers in here. This is actually more
|
// In run-time mode, we accept pointers in here. This is actually more
|
||||||
// permissive than a per-element check would be, e.g., we accept
|
// permissive than a per-element check would be, e.g., we accept
|
||||||
// a &[u8] that contains a pointer even though bytewise checking would
|
// a &[u8] that contains a pointer even though bytewise checking would
|
||||||
// reject it. However, that's good: We don't inherently want
|
// reject it. However, that's good: We don't inherently want
|
||||||
// to reject those pointers, we just do not have the machinery to
|
// to reject those pointers, we just do not have the machinery to
|
||||||
// talk about parts of a pointer.
|
// talk about parts of a pointer.
|
||||||
// We also accept uninit, for consistency with the slow path.
|
// We also accept uninit, for consistency with the slow path.
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! `Frozen` impls `Deref`, so we can ergonomically call methods on `Bar`, but it doesn't `impl
|
//! `Frozen` impls `Deref`, so we can ergonomically call methods on `Bar`, but it doesn't `impl
|
||||||
//! DerefMut`. Now calling `foo.compute.mutate()` will result in a compile-time error stating that
|
//! DerefMut`. Now calling `foo.compute.mutate()` will result in a compile-time error stating that
|
||||||
//! `mutate` requires a mutable reference but we don't have one.
|
//! `mutate` requires a mutable reference but we don't have one.
|
||||||
//!
|
//!
|
||||||
//! # Caveats
|
//! # Caveats
|
||||||
|
|
|
@ -84,7 +84,7 @@ fn test_find_state_2() {
|
||||||
// 0 -> 1 -> 2 -> 1
|
// 0 -> 1 -> 2 -> 1
|
||||||
//
|
//
|
||||||
// and at this point detect a cycle. The state of 2 will thus be
|
// and at this point detect a cycle. The state of 2 will thus be
|
||||||
// `InCycleWith { 1 }`. We will then visit the 1 -> 3 edge, which
|
// `InCycleWith { 1 }`. We will then visit the 1 -> 3 edge, which
|
||||||
// will attempt to visit 0 as well, thus going to the state
|
// will attempt to visit 0 as well, thus going to the state
|
||||||
// `InCycleWith { 0 }`. Finally, node 1 will complete; the lowest
|
// `InCycleWith { 0 }`. Finally, node 1 will complete; the lowest
|
||||||
// depth of any successor was 3 which had depth 0, and thus it
|
// depth of any successor was 3 which had depth 0, and thus it
|
||||||
|
|
|
@ -250,7 +250,7 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
|
||||||
// values. So here is what we do:
|
// values. So here is what we do:
|
||||||
//
|
//
|
||||||
// 1. Find the vector `[X | a < X && b < X]` of all values
|
// 1. Find the vector `[X | a < X && b < X]` of all values
|
||||||
// `X` where `a < X` and `b < X`. In terms of the
|
// `X` where `a < X` and `b < X`. In terms of the
|
||||||
// graph, this means all values reachable from both `a`
|
// graph, this means all values reachable from both `a`
|
||||||
// and `b`. Note that this vector is also a set, but we
|
// and `b`. Note that this vector is also a set, but we
|
||||||
// use the term vector because the order matters
|
// use the term vector because the order matters
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
The `driver` crate is effectively the "main" function for the rust
|
The `driver` crate is effectively the "main" function for the rust
|
||||||
compiler. It orchestrates the compilation process and "knits together"
|
compiler. It orchestrates the compilation process and "knits together"
|
||||||
the code from the other crates within rustc. This crate itself does
|
the code from the other crates within rustc. This crate itself does
|
||||||
not contain any of the "main logic" of the compiler (though it does
|
not contain any of the "main logic" of the compiler (though it does
|
||||||
have some code related to pretty printing or other minor compiler
|
have some code related to pretty printing or other minor compiler
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Error messages for EXXXX errors. Each message should start and end with a
|
// Error messages for EXXXX errors. Each message should start and end with a
|
||||||
// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
|
// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
|
||||||
// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
|
// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
|
||||||
//
|
//
|
||||||
// /!\ IMPORTANT /!\
|
// /!\ IMPORTANT /!\
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn mutable() {
|
||||||
foo(|| x = 2);
|
foo(|| x = 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempts to take a mutable reference to closed-over data. Error message
|
// Attempts to take a mutable reference to closed-over data. Error message
|
||||||
// reads: `cannot borrow data mutably in a captured outer variable...`
|
// reads: `cannot borrow data mutably in a captured outer variable...`
|
||||||
fn mut_addr() {
|
fn mut_addr() {
|
||||||
let mut x = 0u32;
|
let mut x = 0u32;
|
||||||
|
|
|
@ -22,7 +22,7 @@ gets called when they go out of scope. This destructor gets exclusive
|
||||||
access to the fields of the struct when it runs.
|
access to the fields of the struct when it runs.
|
||||||
|
|
||||||
This means that when `s` reaches the end of `demo`, its destructor
|
This means that when `s` reaches the end of `demo`, its destructor
|
||||||
gets exclusive access to its `&mut`-borrowed string data. allowing
|
gets exclusive access to its `&mut`-borrowed string data. allowing
|
||||||
another borrow of that string data (`p`), to exist across the drop of
|
another borrow of that string data (`p`), to exist across the drop of
|
||||||
`s` would be a violation of the principle that `&mut`-borrows have
|
`s` would be a violation of the principle that `&mut`-borrows have
|
||||||
exclusive, unaliased access to their referenced data.
|
exclusive, unaliased access to their referenced data.
|
||||||
|
|
|
@ -15,5 +15,5 @@ fn main() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
The items of marker traits cannot be overridden, so there's no need to have them
|
The items of marker traits cannot be overridden, so there's no need to have them
|
||||||
when they cannot be changed per-type anyway. If you wanted them for ergonomic
|
when they cannot be changed per-type anyway. If you wanted them for ergonomic
|
||||||
reasons, consider making an extension trait instead.
|
reasons, consider making an extension trait instead.
|
||||||
|
|
|
@ -114,9 +114,9 @@ pub struct Diagnostic {
|
||||||
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
|
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
|
||||||
args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>,
|
args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>,
|
||||||
|
|
||||||
/// This is not used for highlighting or rendering any error message. Rather, it can be used
|
/// This is not used for highlighting or rendering any error message. Rather, it can be used
|
||||||
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
|
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
|
||||||
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
|
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
|
||||||
pub sort_span: Span,
|
pub sort_span: Span,
|
||||||
|
|
||||||
/// If diagnostic is from Lint, custom hash function ignores notes
|
/// If diagnostic is from Lint, custom hash function ignores notes
|
||||||
|
|
|
@ -1791,7 +1791,7 @@ impl EmitterWriter {
|
||||||
|
|
||||||
if let Some(span) = span.primary_span() {
|
if let Some(span) = span.primary_span() {
|
||||||
// Compare the primary span of the diagnostic with the span of the suggestion
|
// Compare the primary span of the diagnostic with the span of the suggestion
|
||||||
// being emitted. If they belong to the same file, we don't *need* to show the
|
// being emitted. If they belong to the same file, we don't *need* to show the
|
||||||
// file name, saving in verbosity, but if it *isn't* we do need it, otherwise we're
|
// file name, saving in verbosity, but if it *isn't* we do need it, otherwise we're
|
||||||
// telling users to make a change but not clarifying *where*.
|
// telling users to make a change but not clarifying *where*.
|
||||||
let loc = sm.lookup_char_pos(parts[0].span.lo());
|
let loc = sm.lookup_char_pos(parts[0].span.lo());
|
||||||
|
@ -2529,11 +2529,11 @@ fn emit_to_destination(
|
||||||
//
|
//
|
||||||
// On Unix systems, we write into a buffered terminal rather than directly to a terminal. When
|
// On Unix systems, we write into a buffered terminal rather than directly to a terminal. When
|
||||||
// the .flush() is called we take the buffer created from the buffered writes and write it at
|
// the .flush() is called we take the buffer created from the buffered writes and write it at
|
||||||
// one shot. Because the Unix systems use ANSI for the colors, which is a text-based styling
|
// one shot. Because the Unix systems use ANSI for the colors, which is a text-based styling
|
||||||
// scheme, this buffered approach works and maintains the styling.
|
// scheme, this buffered approach works and maintains the styling.
|
||||||
//
|
//
|
||||||
// On Windows, styling happens through calls to a terminal API. This prevents us from using the
|
// On Windows, styling happens through calls to a terminal API. This prevents us from using the
|
||||||
// same buffering approach. Instead, we use a global Windows mutex, which we acquire long
|
// same buffering approach. Instead, we use a global Windows mutex, which we acquire long
|
||||||
// enough to output the full error message, then we release.
|
// enough to output the full error message, then we release.
|
||||||
let _buffer_lock = lock::acquire_global_lock("rustc_errors");
|
let _buffer_lock = lock::acquire_global_lock("rustc_errors");
|
||||||
for (pos, line) in rendered_buffer.iter().enumerate() {
|
for (pos, line) in rendered_buffer.iter().enumerate() {
|
||||||
|
|
|
@ -171,7 +171,7 @@ fn parse_tree(
|
||||||
} else {
|
} else {
|
||||||
match delim {
|
match delim {
|
||||||
Delimiter::Brace => {
|
Delimiter::Brace => {
|
||||||
// The delimiter is `{`. This indicates the beginning
|
// The delimiter is `{`. This indicates the beginning
|
||||||
// of a meta-variable expression (e.g. `${count(ident)}`).
|
// of a meta-variable expression (e.g. `${count(ident)}`).
|
||||||
// Try to parse the meta-variable expression.
|
// Try to parse the meta-variable expression.
|
||||||
match MetaVarExpr::parse(&tts, delim_span.entire(), sess) {
|
match MetaVarExpr::parse(&tts, delim_span.entire(), sess) {
|
||||||
|
@ -200,7 +200,7 @@ fn parse_tree(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we didn't find a metavar expression above, then we must have a
|
// If we didn't find a metavar expression above, then we must have a
|
||||||
// repetition sequence in the macro (e.g. `$(pat)*`). Parse the
|
// repetition sequence in the macro (e.g. `$(pat)*`). Parse the
|
||||||
// contents of the sequence itself
|
// contents of the sequence itself
|
||||||
let sequence = parse(tts, parsing_patterns, sess, node_id, features, edition);
|
let sequence = parse(tts, parsing_patterns, sess, node_id, features, edition);
|
||||||
// Get the Kleene operator and optional separator
|
// Get the Kleene operator and optional separator
|
||||||
|
|
|
@ -230,7 +230,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
|
||||||
let stream = TokenStream::from_nonterminal_ast(&nt);
|
let stream = TokenStream::from_nonterminal_ast(&nt);
|
||||||
// A hack used to pass AST fragments to attribute and derive
|
// A hack used to pass AST fragments to attribute and derive
|
||||||
// macros as a single nonterminal token instead of a token
|
// macros as a single nonterminal token instead of a token
|
||||||
// stream. Such token needs to be "unwrapped" and not
|
// stream. Such token needs to be "unwrapped" and not
|
||||||
// represented as a delimited group.
|
// represented as a delimited group.
|
||||||
// FIXME: It needs to be removed, but there are some
|
// FIXME: It needs to be removed, but there are some
|
||||||
// compatibility issues (see #73345).
|
// compatibility issues (see #73345).
|
||||||
|
|
|
@ -751,7 +751,7 @@ pub enum LifetimeRes {
|
||||||
binder: NodeId,
|
binder: NodeId,
|
||||||
},
|
},
|
||||||
/// This variant is used for anonymous lifetimes that we did not resolve during
|
/// This variant is used for anonymous lifetimes that we did not resolve during
|
||||||
/// late resolution. Those lifetimes will be inferred by typechecking.
|
/// late resolution. Those lifetimes will be inferred by typechecking.
|
||||||
Infer,
|
Infer,
|
||||||
/// Explicit `'static` lifetime.
|
/// Explicit `'static` lifetime.
|
||||||
Static,
|
Static,
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub enum LifetimeName {
|
||||||
/// Implicit lifetime in a context like `dyn Foo`. This is
|
/// Implicit lifetime in a context like `dyn Foo`. This is
|
||||||
/// distinguished from implicit lifetimes elsewhere because the
|
/// distinguished from implicit lifetimes elsewhere because the
|
||||||
/// lifetime that they default to must appear elsewhere within the
|
/// lifetime that they default to must appear elsewhere within the
|
||||||
/// enclosing type. This means that, in an `impl Trait` context, we
|
/// enclosing type. This means that, in an `impl Trait` context, we
|
||||||
/// don't have to create a parameter for them. That is, `impl
|
/// don't have to create a parameter for them. That is, `impl
|
||||||
/// Trait<Item = &u32>` expands to an opaque type like `type
|
/// Trait<Item = &u32>` expands to an opaque type like `type
|
||||||
/// Foo<'a> = impl Trait<Item = &'a u32>`, but `impl Trait<item =
|
/// Foo<'a> = impl Trait<Item = &'a u32>`, but `impl Trait<item =
|
||||||
|
@ -826,7 +826,7 @@ pub struct OwnerNodes<'tcx> {
|
||||||
pub hash_without_bodies: Fingerprint,
|
pub hash_without_bodies: Fingerprint,
|
||||||
/// Full HIR for the current owner.
|
/// Full HIR for the current owner.
|
||||||
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
|
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
|
||||||
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
|
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
|
||||||
// used.
|
// used.
|
||||||
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
|
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
|
||||||
/// Content of local bodies.
|
/// Content of local bodies.
|
||||||
|
|
|
@ -331,7 +331,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
if potential_assoc_types.len() == assoc_items.len() {
|
if potential_assoc_types.len() == assoc_items.len() {
|
||||||
// When the amount of missing associated types equals the number of
|
// When the amount of missing associated types equals the number of
|
||||||
// extra type arguments present. A suggesting to replace the generic args with
|
// extra type arguments present. A suggesting to replace the generic args with
|
||||||
// associated types is already emitted.
|
// associated types is already emitted.
|
||||||
already_has_generics_args_suggestion = true;
|
already_has_generics_args_suggestion = true;
|
||||||
} else if let (Ok(snippet), false) =
|
} else if let (Ok(snippet), false) =
|
||||||
|
|
|
@ -337,13 +337,13 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
|
||||||
// We should never be able to reach this point with well-formed input.
|
// We should never be able to reach this point with well-formed input.
|
||||||
// There are three situations in which we can encounter this issue.
|
// There are three situations in which we can encounter this issue.
|
||||||
//
|
//
|
||||||
// 1. The number of arguments is incorrect. In this case, an error
|
// 1. The number of arguments is incorrect. In this case, an error
|
||||||
// will already have been emitted, and we can ignore it.
|
// will already have been emitted, and we can ignore it.
|
||||||
// 2. There are late-bound lifetime parameters present, yet the
|
// 2. There are late-bound lifetime parameters present, yet the
|
||||||
// lifetime arguments have also been explicitly specified by the
|
// lifetime arguments have also been explicitly specified by the
|
||||||
// user.
|
// user.
|
||||||
// 3. We've inferred some lifetimes, which have been provided later (i.e.
|
// 3. We've inferred some lifetimes, which have been provided later (i.e.
|
||||||
// after a type or const). We want to throw an error in this case.
|
// after a type or const). We want to throw an error in this case.
|
||||||
|
|
||||||
if arg_count.correct.is_ok()
|
if arg_count.correct.is_ok()
|
||||||
&& arg_count.explicit_late_bound == ExplicitLateBound::No
|
&& arg_count.explicit_late_bound == ExplicitLateBound::No
|
||||||
|
|
|
@ -993,7 +993,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
|
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
|
||||||
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
|
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
|
||||||
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
||||||
///
|
///
|
||||||
/// `span` should be the declaration size of the parameter.
|
/// `span` should be the declaration size of the parameter.
|
||||||
|
@ -1498,7 +1498,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
|
i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
|
||||||
assert_eq!(trait_ref.self_ty(), dummy_self);
|
assert_eq!(trait_ref.self_ty(), dummy_self);
|
||||||
|
|
||||||
// Verify that `dummy_self` did not leak inside default type parameters. This
|
// Verify that `dummy_self` did not leak inside default type parameters. This
|
||||||
// could not be done at path creation, since we need to see through trait aliases.
|
// could not be done at path creation, since we need to see through trait aliases.
|
||||||
let mut missing_type_params = vec![];
|
let mut missing_type_params = vec![];
|
||||||
let mut references_self = false;
|
let mut references_self = false;
|
||||||
|
@ -2694,7 +2694,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the programmer's textual representation of a type into our
|
/// Parses the programmer's textual representation of a type into our
|
||||||
/// internal notion of a type. This is meant to be used within a path.
|
/// internal notion of a type. This is meant to be used within a path.
|
||||||
pub fn ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
pub fn ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
||||||
self.ast_ty_to_ty_inner(ast_ty, false, true)
|
self.ast_ty_to_ty_inner(ast_ty, false, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ pub(super) fn compare_impl_method<'tcx>(
|
||||||
/// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
|
/// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
|
||||||
///
|
///
|
||||||
/// This type is also the same but the name of the bound region (`'a`
|
/// This type is also the same but the name of the bound region (`'a`
|
||||||
/// vs `'b`). However, the normal subtyping rules on fn types handle
|
/// vs `'b`). However, the normal subtyping rules on fn types handle
|
||||||
/// this kind of equivalency just fine.
|
/// this kind of equivalency just fine.
|
||||||
///
|
///
|
||||||
/// We now use these substitutions to ensure that all declared bounds are
|
/// We now use these substitutions to ensure that all declared bounds are
|
||||||
|
@ -625,7 +625,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
match infcx.fully_resolve(ty) {
|
match infcx.fully_resolve(ty) {
|
||||||
Ok(ty) => {
|
Ok(ty) => {
|
||||||
// `ty` contains free regions that we created earlier while liberating the
|
// `ty` contains free regions that we created earlier while liberating the
|
||||||
// trait fn signature. However, projection normalization expects `ty` to
|
// trait fn signature. However, projection normalization expects `ty` to
|
||||||
// contains `def_id`'s early-bound regions.
|
// contains `def_id`'s early-bound regions.
|
||||||
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
debug!(?id_substs, ?substs);
|
debug!(?id_substs, ?substs);
|
||||||
|
@ -883,7 +883,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||||
|
|
||||||
// Must have same number of early-bound lifetime parameters.
|
// Must have same number of early-bound lifetime parameters.
|
||||||
// Unfortunately, if the user screws up the bounds, then this
|
// Unfortunately, if the user screws up the bounds, then this
|
||||||
// will change classification between early and late. E.g.,
|
// will change classification between early and late. E.g.,
|
||||||
// if in trait we have `<'a,'b:'a>`, and in impl we just have
|
// if in trait we have `<'a,'b:'a>`, and in impl we just have
|
||||||
// `<'a,'b>`, then we have 2 early-bound lifetime parameters
|
// `<'a,'b>`, then we have 2 early-bound lifetime parameters
|
||||||
// in trait but 0 in the impl. But if we report "expected 2
|
// in trait but 0 in the impl. But if we report "expected 2
|
||||||
|
@ -994,9 +994,9 @@ fn compare_self_type<'tcx>(
|
||||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
// Try to give more informative error messages about self typing
|
// Try to give more informative error messages about self typing
|
||||||
// mismatches. Note that any mismatch will also be detected
|
// mismatches. Note that any mismatch will also be detected
|
||||||
// below, where we construct a canonical function type that
|
// below, where we construct a canonical function type that
|
||||||
// includes the self parameter as a normal parameter. It's just
|
// includes the self parameter as a normal parameter. It's just
|
||||||
// that the error messages you get out of this code are a bit more
|
// that the error messages you get out of this code are a bit more
|
||||||
// inscrutable, particularly for cases where one method has no
|
// inscrutable, particularly for cases where one method has no
|
||||||
// self.
|
// self.
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Destructors only work on nominal types. This was
|
// Destructors only work on nominal types. This was
|
||||||
// already checked by coherence, but compilation may
|
// already checked by coherence, but compilation may
|
||||||
// not have been terminated.
|
// not have been terminated.
|
||||||
let span = tcx.def_span(drop_impl_did);
|
let span = tcx.def_span(drop_impl_did);
|
||||||
|
|
|
@ -14,23 +14,23 @@ can be broken down into several distinct phases:
|
||||||
|
|
||||||
- main: the main pass does the lion's share of the work: it
|
- main: the main pass does the lion's share of the work: it
|
||||||
determines the types of all expressions, resolves
|
determines the types of all expressions, resolves
|
||||||
methods, checks for most invalid conditions, and so forth. In
|
methods, checks for most invalid conditions, and so forth. In
|
||||||
some cases, where a type is unknown, it may create a type or region
|
some cases, where a type is unknown, it may create a type or region
|
||||||
variable and use that as the type of an expression.
|
variable and use that as the type of an expression.
|
||||||
|
|
||||||
In the process of checking, various constraints will be placed on
|
In the process of checking, various constraints will be placed on
|
||||||
these type variables through the subtyping relationships requested
|
these type variables through the subtyping relationships requested
|
||||||
through the `demand` module. The `infer` module is in charge
|
through the `demand` module. The `infer` module is in charge
|
||||||
of resolving those constraints.
|
of resolving those constraints.
|
||||||
|
|
||||||
- regionck: after main is complete, the regionck pass goes over all
|
- regionck: after main is complete, the regionck pass goes over all
|
||||||
types looking for regions and making sure that they did not escape
|
types looking for regions and making sure that they did not escape
|
||||||
into places where they are not in scope. This may also influence the
|
into places where they are not in scope. This may also influence the
|
||||||
final assignments of the various region variables if there is some
|
final assignments of the various region variables if there is some
|
||||||
flexibility.
|
flexibility.
|
||||||
|
|
||||||
- writeback: writes the final types within a function body, replacing
|
- writeback: writes the final types within a function body, replacing
|
||||||
type variables with their final inferred types. These final types
|
type variables with their final inferred types. These final types
|
||||||
are written into the `tcx.node_types` table, which should *never* contain
|
are written into the `tcx.node_types` table, which should *never* contain
|
||||||
any reference to a type variable.
|
any reference to a type variable.
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ can be broken down into several distinct phases:
|
||||||
|
|
||||||
While type checking a function, the intermediate types for the
|
While type checking a function, the intermediate types for the
|
||||||
expressions, blocks, and so forth contained within the function are
|
expressions, blocks, and so forth contained within the function are
|
||||||
stored in `fcx.node_types` and `fcx.node_substs`. These types
|
stored in `fcx.node_types` and `fcx.node_substs`. These types
|
||||||
may contain unresolved type variables. After type checking is
|
may contain unresolved type variables. After type checking is
|
||||||
complete, the functions in the writeback module are used to take the
|
complete, the functions in the writeback module are used to take the
|
||||||
types from this table, resolve them, and then write them into their
|
types from this table, resolve them, and then write them into their
|
||||||
permanent home in the type context `tcx`.
|
permanent home in the type context `tcx`.
|
||||||
|
@ -51,12 +51,12 @@ nodes within the function.
|
||||||
The types of top-level items, which never contain unbound type
|
The types of top-level items, which never contain unbound type
|
||||||
variables, are stored directly into the `tcx` typeck_results.
|
variables, are stored directly into the `tcx` typeck_results.
|
||||||
|
|
||||||
N.B., a type variable is not the same thing as a type parameter. A
|
N.B., a type variable is not the same thing as a type parameter. A
|
||||||
type variable is an instance of a type parameter. That is,
|
type variable is an instance of a type parameter. That is,
|
||||||
given a generic function `fn foo<T>(t: T)`, while checking the
|
given a generic function `fn foo<T>(t: T)`, while checking the
|
||||||
function `foo`, the type `ty_param(0)` refers to the type `T`, which
|
function `foo`, the type `ty_param(0)` refers to the type `T`, which
|
||||||
is treated in abstract. However, when `foo()` is called, `T` will be
|
is treated in abstract. However, when `foo()` is called, `T` will be
|
||||||
substituted for a fresh type variable `N`. This variable will
|
substituted for a fresh type variable `N`. This variable will
|
||||||
eventually be resolved to some concrete type (which might itself be
|
eventually be resolved to some concrete type (which might itself be
|
||||||
a type parameter).
|
a type parameter).
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
||||||
ty::AssocKind::Fn => {
|
ty::AssocKind::Fn => {
|
||||||
// We skip the binder here because the binder would deanonymize all
|
// We skip the binder here because the binder would deanonymize all
|
||||||
// late-bound regions, and we don't want method signatures to show up
|
// late-bound regions, and we don't want method signatures to show up
|
||||||
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
|
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
|
||||||
// regions just fine, showing `fn(&MyType)`.
|
// regions just fine, showing `fn(&MyType)`.
|
||||||
fn_sig_suggestion(
|
fn_sig_suggestion(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -325,7 +325,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
||||||
// The idea is that call.callee_id represents *the time when
|
// The idea is that call.callee_id represents *the time when
|
||||||
// the invoked function is actually running* and call.id
|
// the invoked function is actually running* and call.id
|
||||||
// represents *the time to prepare the arguments and make the
|
// represents *the time to prepare the arguments and make the
|
||||||
// call*. See the section "Borrows in Calls" borrowck/README.md
|
// call*. See the section "Borrows in Calls" borrowck/README.md
|
||||||
// for an extended explanation of why this distinction is
|
// for an extended explanation of why this distinction is
|
||||||
// important.
|
// important.
|
||||||
//
|
//
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
||||||
fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
||||||
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
|
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
|
||||||
|
|
||||||
// Collect first the crates that are completely unused. These we
|
// Collect first the crates that are completely unused. These we
|
||||||
// can always suggest removing (no matter which edition we are
|
// can always suggest removing (no matter which edition we are
|
||||||
// in).
|
// in).
|
||||||
let unused_extern_crates: FxHashMap<LocalDefId, Span> = tcx
|
let unused_extern_crates: FxHashMap<LocalDefId, Span> = tcx
|
||||||
|
|
|
@ -438,7 +438,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
||||||
// when this coercion occurs, we would be changing the
|
// when this coercion occurs, we would be changing the
|
||||||
// field `ptr` from a thin pointer of type `*mut [i32;
|
// field `ptr` from a thin pointer of type `*mut [i32;
|
||||||
// 3]` to a fat pointer of type `*mut [i32]` (with
|
// 3]` to a fat pointer of type `*mut [i32]` (with
|
||||||
// extra data `3`). **The purpose of this check is to
|
// extra data `3`). **The purpose of this check is to
|
||||||
// make sure that we know how to do this conversion.**
|
// make sure that we know how to do this conversion.**
|
||||||
//
|
//
|
||||||
// To check if this impl is legal, we would walk down
|
// To check if this impl is legal, we would walk down
|
||||||
|
|
|
@ -171,7 +171,7 @@ fn check_object_overlap<'tcx>(
|
||||||
for component_def_id in component_def_ids {
|
for component_def_id in component_def_ids {
|
||||||
if !tcx.is_object_safe(component_def_id) {
|
if !tcx.is_object_safe(component_def_id) {
|
||||||
// Without the 'object_safe_for_dispatch' feature this is an error
|
// Without the 'object_safe_for_dispatch' feature this is an error
|
||||||
// which will be reported by wfcheck. Ignore it here.
|
// which will be reported by wfcheck. Ignore it here.
|
||||||
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
|
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
|
||||||
// With the feature enabled, the trait is not implemented automatically,
|
// With the feature enabled, the trait is not implemented automatically,
|
||||||
// so this is valid.
|
// so this is valid.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! Resolution of early vs late bound lifetimes.
|
//! Resolution of early vs late bound lifetimes.
|
||||||
//!
|
//!
|
||||||
//! Name resolution for lifetimes is performed on the AST and embedded into HIR. From this
|
//! Name resolution for lifetimes is performed on the AST and embedded into HIR. From this
|
||||||
//! information, typechecking needs to transform the lifetime parameters into bound lifetimes.
|
//! information, typechecking needs to transform the lifetime parameters into bound lifetimes.
|
||||||
//! Lifetimes can be early-bound or late-bound. Construction of typechecking terms needs to visit
|
//! Lifetimes can be early-bound or late-bound. Construction of typechecking terms needs to visit
|
||||||
//! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices. This file
|
//! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices. This file
|
||||||
//! is also responsible for assigning their semantics to implicit lifetimes in trait objects.
|
//! is also responsible for assigning their semantics to implicit lifetimes in trait objects.
|
||||||
|
|
||||||
use rustc_ast::walk_list;
|
use rustc_ast::walk_list;
|
||||||
|
@ -70,7 +70,7 @@ impl RegionExt for Region {
|
||||||
/// that it corresponds to.
|
/// that it corresponds to.
|
||||||
///
|
///
|
||||||
/// FIXME. This struct gets converted to a `ResolveLifetimes` for
|
/// FIXME. This struct gets converted to a `ResolveLifetimes` for
|
||||||
/// actual use. It has the same data, but indexed by `LocalDefId`. This
|
/// actual use. It has the same data, but indexed by `LocalDefId`. This
|
||||||
/// is silly.
|
/// is silly.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct NamedRegionMap {
|
struct NamedRegionMap {
|
||||||
|
@ -1283,7 +1283,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
// We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
|
// We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
|
||||||
// AST-based resolution does not care for impl-trait desugaring, which are the
|
// AST-based resolution does not care for impl-trait desugaring, which are the
|
||||||
// responibility of lowering. This may create a mismatch between the resolution
|
// responibility of lowering. This may create a mismatch between the resolution
|
||||||
// AST found (`region_def_id`) which points to HRTB, and what HIR allows.
|
// AST found (`region_def_id`) which points to HRTB, and what HIR allows.
|
||||||
// ```
|
// ```
|
||||||
// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
||||||
|
@ -1434,7 +1434,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
|
DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
|
||||||
DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
|
DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
|
||||||
// We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
|
// We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
|
||||||
// works. Ignore it because it can't have a meaningful lifetime default.
|
// works. Ignore it because it can't have a meaningful lifetime default.
|
||||||
DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
|
DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
|
||||||
dk => bug!("unexpected def_kind {:?}", dk),
|
dk => bug!("unexpected def_kind {:?}", dk),
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||||
|
|
||||||
// Subtle: before we store the predicates into the tcx, we
|
// Subtle: before we store the predicates into the tcx, we
|
||||||
// sort them so that predicates like `T: Foo<Item=U>` come
|
// sort them so that predicates like `T: Foo<Item=U>` come
|
||||||
// before uses of `U`. This avoids false ambiguity errors
|
// before uses of `U`. This avoids false ambiguity errors
|
||||||
// in trait checking. See `setup_constraining_predicates`
|
// in trait checking. See `setup_constraining_predicates`
|
||||||
// for details.
|
// for details.
|
||||||
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
|
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
|
||||||
|
|
|
@ -22,7 +22,7 @@ several major phases:
|
||||||
4. Finally, the check phase then checks function bodies and so forth.
|
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
|
Within the check phase, we check each function body one at a time
|
||||||
(bodies of function expressions are checked as part of the
|
(bodies of function expressions are checked as part of the
|
||||||
containing function). Inference is used to supply types wherever
|
containing function). Inference is used to supply types wherever
|
||||||
they are unknown. The actual checking of a function itself has
|
they are unknown. The actual checking of a function itself has
|
||||||
several phases (check, regionck, writeback), as discussed in the
|
several phases (check, regionck, writeback), as discussed in the
|
||||||
documentation for the [`check`] module.
|
documentation for the [`check`] module.
|
||||||
|
@ -46,7 +46,7 @@ independently:
|
||||||
local variables, type parameters, etc as necessary.
|
local variables, type parameters, etc as necessary.
|
||||||
|
|
||||||
- infer: finds the types to use for each type variable such that
|
- infer: finds the types to use for each type variable such that
|
||||||
all subtyping and assignment constraints are met. In essence, the check
|
all subtyping and assignment constraints are met. In essence, the check
|
||||||
module specifies the constraints, and the infer module solves them.
|
module specifies the constraints, and the infer module solves them.
|
||||||
|
|
||||||
## Note
|
## Note
|
||||||
|
@ -542,7 +542,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||||
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
||||||
// In case there are any projections, etc., find the "environment"
|
// In case there are any projections, etc., find the "environment"
|
||||||
// def-ID that will be used to determine the traits/predicates in
|
// def-ID that will be used to determine the traits/predicates in
|
||||||
// scope. This is derived from the enclosing item-like thing.
|
// scope. This is derived from the enclosing item-like thing.
|
||||||
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
||||||
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
||||||
item_cx.astconv().ast_ty_to_ty(hir_ty)
|
item_cx.astconv().ast_ty_to_ty(hir_ty)
|
||||||
|
@ -555,7 +555,7 @@ pub fn hir_trait_to_predicates<'tcx>(
|
||||||
) -> Bounds<'tcx> {
|
) -> Bounds<'tcx> {
|
||||||
// In case there are any projections, etc., find the "environment"
|
// In case there are any projections, etc., find the "environment"
|
||||||
// def-ID that will be used to determine the traits/predicates in
|
// def-ID that will be used to determine the traits/predicates in
|
||||||
// scope. This is derived from the enclosing item-like thing.
|
// scope. This is derived from the enclosing item-like thing.
|
||||||
let env_def_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id);
|
let env_def_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id);
|
||||||
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
|
|
|
@ -139,7 +139,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
|
if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
|
||||||
for (unsubstituted_predicate, &span) in &unsubstituted_predicates.0 {
|
for (unsubstituted_predicate, &span) in &unsubstituted_predicates.0 {
|
||||||
// `unsubstituted_predicate` is `U: 'b` in the
|
// `unsubstituted_predicate` is `U: 'b` in the
|
||||||
// example above. So apply the substitution to
|
// example above. So apply the substitution to
|
||||||
// get `T: 'a` (or `predicate`):
|
// get `T: 'a` (or `predicate`):
|
||||||
let predicate = unsubstituted_predicates
|
let predicate = unsubstituted_predicates
|
||||||
.rebind(*unsubstituted_predicate)
|
.rebind(*unsubstituted_predicate)
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// Here `outlived_region = 'a` and `kind = &'b
|
// Here `outlived_region = 'a` and `kind = &'b
|
||||||
// u32`. Decomposing `&'b u32` into
|
// u32`. Decomposing `&'b u32` into
|
||||||
// components would yield `'b`, and we add the
|
// components would yield `'b`, and we add the
|
||||||
// where clause that `'b: 'a`.
|
// where clause that `'b: 'a`.
|
||||||
insert_outlives_predicate(
|
insert_outlives_predicate(
|
||||||
|
@ -71,7 +71,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// Here `outlived_region = 'a` and `kind =
|
// Here `outlived_region = 'a` and `kind =
|
||||||
// Vec<U>`. Decomposing `Vec<U>` into
|
// Vec<U>`. Decomposing `Vec<U>` into
|
||||||
// components would yield `U`, and we add the
|
// components would yield `U`, and we add the
|
||||||
// where clause that `U: 'a`.
|
// where clause that `U: 'a`.
|
||||||
let ty: Ty<'tcx> = param_ty.to_ty(tcx);
|
let ty: Ty<'tcx> = param_ty.to_ty(tcx);
|
||||||
|
@ -115,7 +115,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
|
||||||
|
|
||||||
Component::EscapingProjection(_) => {
|
Component::EscapingProjection(_) => {
|
||||||
// As above, but the projection involves
|
// As above, but the projection involves
|
||||||
// late-bound regions. Therefore, the WF
|
// late-bound regions. Therefore, the WF
|
||||||
// requirement is not checked in type definition
|
// requirement is not checked in type definition
|
||||||
// but at fn call site, so ignore it.
|
// but at fn call site, so ignore it.
|
||||||
//
|
//
|
||||||
|
@ -175,7 +175,7 @@ fn is_free_region(region: Region<'_>) -> bool {
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// The type above might generate a `T: 'b` bound, but we can
|
// The type above might generate a `T: 'b` bound, but we can
|
||||||
// ignore it. We can't put it on the struct header anyway.
|
// ignore it. We can't put it on the struct header anyway.
|
||||||
ty::ReLateBound(..) => false,
|
ty::ReLateBound(..) => false,
|
||||||
|
|
||||||
// These regions don't appear in types from type declarations:
|
// These regions don't appear in types from type declarations:
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub fn solve_constraints<'tcx>(
|
||||||
|
|
||||||
impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
||||||
fn solve(&mut self) {
|
fn solve(&mut self) {
|
||||||
// Propagate constraints until a fixed point is reached. Note
|
// Propagate constraints until a fixed point is reached. Note
|
||||||
// that the maximum number of iterations is 2C where C is the
|
// that the maximum number of iterations is 2C where C is the
|
||||||
// number of constraints (each variable can change values at most
|
// number of constraints (each variable can change values at most
|
||||||
// twice). Since number of constraints is linear in size of the
|
// twice). Since number of constraints is linear in size of the
|
||||||
|
|
|
@ -524,7 +524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// FIXME(#45727): As discussed in [this comment][c1], naively
|
// FIXME(#45727): As discussed in [this comment][c1], naively
|
||||||
// forcing equality here actually results in suboptimal error
|
// forcing equality here actually results in suboptimal error
|
||||||
// messages in some cases. For now, if there would have been
|
// messages in some cases. For now, if there would have been
|
||||||
// an obvious error, we fallback to declaring the type of the
|
// an obvious error, we fallback to declaring the type of the
|
||||||
// closure to be the one the user gave, which allows other
|
// closure to be the one the user gave, which allows other
|
||||||
// error message code to trigger.
|
// error message code to trigger.
|
||||||
|
|
|
@ -313,7 +313,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
|
|
||||||
// If we have a parameter of type `&M T_a` and the value
|
// If we have a parameter of type `&M T_a` and the value
|
||||||
// provided is `expr`, we will be adding an implicit borrow,
|
// provided is `expr`, we will be adding an implicit borrow,
|
||||||
// meaning that we convert `f(expr)` to `f(&M *expr)`. Therefore,
|
// meaning that we convert `f(expr)` to `f(&M *expr)`. Therefore,
|
||||||
// to type check, we will construct the type that `&M*expr` would
|
// to type check, we will construct the type that `&M*expr` would
|
||||||
// yield.
|
// yield.
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we have deref'd `a` to `referent_ty`. So
|
// At this point, we have deref'd `a` to `referent_ty`. So
|
||||||
// imagine we are coercing from `&'a mut Vec<T>` to `&'b mut [T]`.
|
// imagine we are coercing from `&'a mut Vec<T>` to `&'b mut [T]`.
|
||||||
// In the autoderef loop for `&'a mut Vec<T>`, we would get
|
// In the autoderef loop for `&'a mut Vec<T>`, we would get
|
||||||
// three callbacks:
|
// three callbacks:
|
||||||
|
@ -371,7 +371,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
// - if in sub mode, that means we want to use `'b` (the
|
// - if in sub mode, that means we want to use `'b` (the
|
||||||
// region from the target reference) for both
|
// region from the target reference) for both
|
||||||
// pointers [2]. This is because sub mode (somewhat
|
// pointers [2]. This is because sub mode (somewhat
|
||||||
// arbitrarily) returns the subtype region. In the case
|
// arbitrarily) returns the subtype region. In the case
|
||||||
// where we are coercing to a target type, we know we
|
// where we are coercing to a target type, we know we
|
||||||
// want to use that target type region (`'b`) because --
|
// want to use that target type region (`'b`) because --
|
||||||
// for the program to type-check -- it must be the
|
// for the program to type-check -- it must be the
|
||||||
|
@ -383,7 +383,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
// annotate the region of a borrow), and regionck has
|
// annotate the region of a borrow), and regionck has
|
||||||
// code that adds edges from the region of a borrow
|
// code that adds edges from the region of a borrow
|
||||||
// (`'b`, here) into the regions in the borrowed
|
// (`'b`, here) into the regions in the borrowed
|
||||||
// expression (`*x`, here). (Search for "link".)
|
// expression (`*x`, here). (Search for "link".)
|
||||||
// - if in lub mode, things can get fairly complicated. The
|
// - if in lub mode, things can get fairly complicated. The
|
||||||
// easiest thing is just to make a fresh
|
// easiest thing is just to make a fresh
|
||||||
// region variable [4], which effectively means we defer
|
// region variable [4], which effectively means we defer
|
||||||
|
@ -457,7 +457,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
if ty == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 {
|
if ty == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 {
|
||||||
// As a special case, if we would produce `&'a *x`, that's
|
// As a special case, if we would produce `&'a *x`, that's
|
||||||
// a total no-op. We end up with the type `&'a T` just as
|
// a total no-op. We end up with the type `&'a T` just as
|
||||||
// we started with. In that case, just skip it
|
// we started with. In that case, just skip it
|
||||||
// altogether. This is just an optimization.
|
// altogether. This is just an optimization.
|
||||||
//
|
//
|
||||||
// Note that for `&mut`, we DO want to reborrow --
|
// Note that for `&mut`, we DO want to reborrow --
|
||||||
|
@ -1476,7 +1476,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
// if let Some(x) = ... { }
|
// if let Some(x) = ... { }
|
||||||
//
|
//
|
||||||
// we wind up with a second match arm that is like `_ =>
|
// we wind up with a second match arm that is like `_ =>
|
||||||
// ()`. That is the case we are considering here. We take
|
// ()`. That is the case we are considering here. We take
|
||||||
// a different path to get the right "expected, found"
|
// a different path to get the right "expected, found"
|
||||||
// message and so forth (and because we know that
|
// message and so forth (and because we know that
|
||||||
// `expression_ty` will be unit).
|
// `expression_ty` will be unit).
|
||||||
|
|
|
@ -459,9 +459,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
hir::BorrowKind::Ref => {
|
hir::BorrowKind::Ref => {
|
||||||
// Note: at this point, we cannot say what the best lifetime
|
// Note: at this point, we cannot say what the best lifetime
|
||||||
// is to use for resulting pointer. We want to use the
|
// is to use for resulting pointer. We want to use the
|
||||||
// shortest lifetime possible so as to avoid spurious borrowck
|
// shortest lifetime possible so as to avoid spurious borrowck
|
||||||
// errors. Moreover, the longest lifetime will depend on the
|
// errors. Moreover, the longest lifetime will depend on the
|
||||||
// precise details of the value whose address is being taken
|
// precise details of the value whose address is being taken
|
||||||
// (and how long it is valid), which we don't know yet until
|
// (and how long it is valid), which we don't know yet until
|
||||||
// type inference is complete.
|
// type inference is complete.
|
||||||
|
@ -687,7 +687,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If `ctxt.coerce` is `None`, we can just ignore
|
// If `ctxt.coerce` is `None`, we can just ignore
|
||||||
// the type of the expression. This is because
|
// the type of the expression. This is because
|
||||||
// either this was a break *without* a value, in
|
// either this was a break *without* a value, in
|
||||||
// which case it is always a legal type (`()`), or
|
// which case it is always a legal type (`()`), or
|
||||||
// else an error would have been flagged by the
|
// else an error would have been flagged by the
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
// We now see if we can make progress. This might cause us to
|
// We now see if we can make progress. This might cause us to
|
||||||
// unify inference variables for opaque types, since we may
|
// unify inference variables for opaque types, since we may
|
||||||
// have unified some other type variables during the first
|
// have unified some other type variables during the first
|
||||||
// phase of fallback. This means that we only replace
|
// phase of fallback. This means that we only replace
|
||||||
// inference variables with their underlying opaque types as a
|
// inference variables with their underlying opaque types as a
|
||||||
// last resort.
|
// last resort.
|
||||||
//
|
//
|
||||||
|
@ -76,7 +76,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
// (and the setting of `#![feature(never_type_fallback)]`).
|
// (and the setting of `#![feature(never_type_fallback)]`).
|
||||||
//
|
//
|
||||||
// Fallback becomes very dubious if we have encountered
|
// Fallback becomes very dubious if we have encountered
|
||||||
// type-checking errors. In that case, fallback to Error.
|
// type-checking errors. In that case, fallback to Error.
|
||||||
//
|
//
|
||||||
// Sets `FnCtxt::fallback_has_occurred` if fallback is performed
|
// Sets `FnCtxt::fallback_has_occurred` if fallback is performed
|
||||||
// during this call.
|
// during this call.
|
||||||
|
@ -136,7 +136,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
/// constrained to have some other type).
|
/// constrained to have some other type).
|
||||||
///
|
///
|
||||||
/// However, the fallback used to be `()` (before the `!` type was
|
/// However, the fallback used to be `()` (before the `!` type was
|
||||||
/// added). Moreover, there are cases where the `!` type 'leaks
|
/// added). Moreover, there are cases where the `!` type 'leaks
|
||||||
/// out' from dead code into type variables that affect live
|
/// out' from dead code into type variables that affect live
|
||||||
/// code. The most common case is something like this:
|
/// code. The most common case is something like this:
|
||||||
///
|
///
|
||||||
|
@ -149,7 +149,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Here, coercing the type `!` into `?M` will create a diverging
|
/// Here, coercing the type `!` into `?M` will create a diverging
|
||||||
/// type variable `?X` where `?X <: ?M`. We also have that `?D <:
|
/// type variable `?X` where `?X <: ?M`. We also have that `?D <:
|
||||||
/// ?M`. If `?M` winds up unconstrained, then `?X` will
|
/// ?M`. If `?M` winds up unconstrained, then `?X` will
|
||||||
/// fallback. If it falls back to `!`, then all the type variables
|
/// fallback. If it falls back to `!`, then all the type variables
|
||||||
/// will wind up equal to `!` -- this includes the type `?D`
|
/// will wind up equal to `!` -- this includes the type `?D`
|
||||||
|
@ -185,7 +185,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
///
|
///
|
||||||
/// The algorithm we use:
|
/// The algorithm we use:
|
||||||
/// * Identify all variables that are coerced *into* by a
|
/// * Identify all variables that are coerced *into* by a
|
||||||
/// diverging variable. Do this by iterating over each
|
/// diverging variable. Do this by iterating over each
|
||||||
/// diverging, unsolved variable and finding all variables
|
/// diverging, unsolved variable and finding all variables
|
||||||
/// reachable from there. Call that set `D`.
|
/// reachable from there. Call that set `D`.
|
||||||
/// * Walk over all unsolved, non-diverging variables, and find
|
/// * Walk over all unsolved, non-diverging variables, and find
|
||||||
|
|
|
@ -452,7 +452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&& method_call_list.contains(&conversion_method.name)
|
&& method_call_list.contains(&conversion_method.name)
|
||||||
// If receiver is `.clone()` and found type has one of those methods,
|
// If receiver is `.clone()` and found type has one of those methods,
|
||||||
// we guess that the user wants to convert from a slice type (`&[]` or `&str`)
|
// we guess that the user wants to convert from a slice type (`&[]` or `&str`)
|
||||||
// to an owned type (`Vec` or `String`). These conversions clone internally,
|
// to an owned type (`Vec` or `String`). These conversions clone internally,
|
||||||
// so we remove the user's `clone` call.
|
// so we remove the user's `clone` call.
|
||||||
{
|
{
|
||||||
vec![(
|
vec![(
|
||||||
|
@ -649,7 +649,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => {
|
ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => {
|
||||||
// Check if the parent expression is a call to Pin::new. If it
|
// Check if the parent expression is a call to Pin::new. If it
|
||||||
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
|
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
|
||||||
// can suggest Box::pin.
|
// can suggest Box::pin.
|
||||||
let parent = self.tcx.hir().parent_id(expr.hir_id);
|
let parent = self.tcx.hir().parent_id(expr.hir_id);
|
||||||
|
|
|
@ -116,7 +116,7 @@ impl<'tcx> ExprUseDelegate<'tcx> {
|
||||||
// where the `identity(...)` (the rvalue) produces a return type
|
// where the `identity(...)` (the rvalue) produces a return type
|
||||||
// of `&'rv mut A`, where `'a: 'rv`. We then assign this result to
|
// of `&'rv mut A`, where `'a: 'rv`. We then assign this result to
|
||||||
// `'y`, resulting in (transitively) `'a: 'y` (i.e., while `y` is in use,
|
// `'y`, resulting in (transitively) `'a: 'y` (i.e., while `y` is in use,
|
||||||
// `a` will be considered borrowed). Other parts of the code will ensure
|
// `a` will be considered borrowed). Other parts of the code will ensure
|
||||||
// that if `y` is live over a yield, `&'y mut A` appears in the generator
|
// that if `y` is live over a yield, `&'y mut A` appears in the generator
|
||||||
// state. If `'y` is live, then any sound region analysis must conclude
|
// state. If `'y` is live, then any sound region analysis must conclude
|
||||||
// that `'a` is also live. So if this causes a bug, blame some other
|
// that `'a` is also live. So if this causes a bug, blame some other
|
||||||
|
|
|
@ -736,7 +736,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Box(ref subpat) | PatKind::Ref(ref subpat, _) => {
|
PatKind::Box(ref subpat) | PatKind::Ref(ref subpat, _) => {
|
||||||
// box p1, &p1, &mut p1. we can ignore the mutability of
|
// box p1, &p1, &mut p1. we can ignore the mutability of
|
||||||
// PatKind::Ref since that information is already contained
|
// PatKind::Ref since that information is already contained
|
||||||
// in the type.
|
// in the type.
|
||||||
let subplace = self.cat_deref(pat, place_with_id)?;
|
let subplace = self.cat_deref(pat, place_with_id)?;
|
||||||
|
|
|
@ -413,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Register obligations for the parameters. This will include the
|
// Register obligations for the parameters. This will include the
|
||||||
// `Self` parameter, which in turn has a bound of the main trait,
|
// `Self` parameter, which in turn has a bound of the main trait,
|
||||||
// so this also effectively registers `obligation` as well. (We
|
// so this also effectively registers `obligation` as well. (We
|
||||||
// used to register `obligation` explicitly, but that resulted in
|
// used to register `obligation` explicitly, but that resulted in
|
||||||
// double error messages being reported.)
|
// double error messages being reported.)
|
||||||
//
|
//
|
||||||
|
|
|
@ -368,7 +368,7 @@ fn walk_between<'q>(
|
||||||
) -> FxHashSet<DepKind> {
|
) -> FxHashSet<DepKind> {
|
||||||
// This is a bit tricky. We want to include a node only if it is:
|
// This is a bit tricky. We want to include a node only if it is:
|
||||||
// (a) reachable from a source and (b) will reach a target. And we
|
// (a) reachable from a source and (b) will reach a target. And we
|
||||||
// have to be careful about cycles etc. Luckily efficiency is not
|
// have to be careful about cycles etc. Luckily efficiency is not
|
||||||
// a big concern!
|
// a big concern!
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Debugging code to test fingerprints computed for query results. For each node marked with
|
//! Debugging code to test fingerprints computed for query results. For each node marked with
|
||||||
//! `#[rustc_clean]` we will compare the fingerprint from the current and from the previous
|
//! `#[rustc_clean]` we will compare the fingerprint from the current and from the previous
|
||||||
//! compilation session as appropriate:
|
//! compilation session as appropriate:
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -331,7 +331,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||||
debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown());
|
debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown());
|
||||||
|
|
||||||
// Generalize type of `a_ty` appropriately depending on the
|
// Generalize type of `a_ty` appropriately depending on the
|
||||||
// direction. As an example, assume:
|
// direction. As an example, assume:
|
||||||
//
|
//
|
||||||
// - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
|
// - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
|
||||||
// inference variable,
|
// inference variable,
|
||||||
|
|
|
@ -370,7 +370,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
||||||
// in the types are about to print
|
// in the types are about to print
|
||||||
// - Meanwhile, the `maybe_highlighting_region` calls set up
|
// - Meanwhile, the `maybe_highlighting_region` calls set up
|
||||||
// highlights so that, if they do appear, we will replace
|
// highlights so that, if they do appear, we will replace
|
||||||
// them `'0` and whatever. (This replacement takes place
|
// them `'0` and whatever. (This replacement takes place
|
||||||
// inside the closure given to `maybe_highlighting_region`.)
|
// inside the closure given to `maybe_highlighting_region`.)
|
||||||
//
|
//
|
||||||
// There is some duplication between the calls -- i.e., the
|
// There is some duplication between the calls -- i.e., the
|
||||||
|
|
|
@ -78,7 +78,7 @@ where
|
||||||
//
|
//
|
||||||
// Example: if the LHS is a type variable, and RHS is
|
// Example: if the LHS is a type variable, and RHS is
|
||||||
// `Box<i32>`, then we current compare `v` to the RHS first,
|
// `Box<i32>`, then we current compare `v` to the RHS first,
|
||||||
// which will instantiate `v` with `Box<i32>`. Then when `v`
|
// which will instantiate `v` with `Box<i32>`. Then when `v`
|
||||||
// is compared to the LHS, we instantiate LHS with `Box<i32>`.
|
// is compared to the LHS, we instantiate LHS with `Box<i32>`.
|
||||||
// But if we did in reverse order, we would create a `v <:
|
// But if we did in reverse order, we would create a `v <:
|
||||||
// LHS` (or vice versa) constraint and then instantiate
|
// LHS` (or vice versa) constraint and then instantiate
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub struct LexicalRegionResolutions<'tcx> {
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub(crate) enum VarValue<'tcx> {
|
pub(crate) enum VarValue<'tcx> {
|
||||||
/// Empty lifetime is for data that is never accessed. We tag the
|
/// Empty lifetime is for data that is never accessed. We tag the
|
||||||
/// empty lifetime with a universe -- the idea is that we don't
|
/// empty lifetime with a universe -- the idea is that we don't
|
||||||
/// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
|
/// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
|
||||||
/// Therefore, the `'empty` in a universe `U` is less than all
|
/// Therefore, the `'empty` in a universe `U` is less than all
|
||||||
|
@ -510,7 +510,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If both `a` and `b` are free, consult the declared
|
// If both `a` and `b` are free, consult the declared
|
||||||
// relationships. Note that this can be more precise than the
|
// relationships. Note that this can be more precise than the
|
||||||
// `lub` relationship defined below, since sometimes the "lub"
|
// `lub` relationship defined below, since sometimes the "lub"
|
||||||
// is actually the `postdom_upper_bound` (see
|
// is actually the `postdom_upper_bound` (see
|
||||||
// `TransitiveRelation` for more details).
|
// `TransitiveRelation` for more details).
|
||||||
|
@ -665,7 +665,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
// conflicting regions to report to the user. As we walk, we
|
// conflicting regions to report to the user. As we walk, we
|
||||||
// trip the flags from false to true, and if we find that
|
// trip the flags from false to true, and if we find that
|
||||||
// we've already reported an error involving any particular
|
// we've already reported an error involving any particular
|
||||||
// node we just stop and don't report the current error. The
|
// node we just stop and don't report the current error. The
|
||||||
// idea is to report errors that derive from independent
|
// idea is to report errors that derive from independent
|
||||||
// regions of the graph, but not those that derive from
|
// regions of the graph, but not those that derive from
|
||||||
// overlapping locations.
|
// overlapping locations.
|
||||||
|
|
|
@ -1105,7 +1105,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
self.tcx.mk_region(ty::ReVar(region_var))
|
self.tcx.mk_region(ty::ReVar(region_var))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the universe that the region `r` was created in. For
|
/// Return the universe that the region `r` was created in. For
|
||||||
/// most regions (e.g., `'static`, named regions from the user,
|
/// most regions (e.g., `'static`, named regions from the user,
|
||||||
/// etc) this is the root universe U0. For inference variables or
|
/// etc) this is the root universe U0. For inference variables or
|
||||||
/// placeholders, however, it will return the universe which they
|
/// placeholders, however, it will return the universe which they
|
||||||
|
@ -1361,7 +1361,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve any type variables found in `value` -- but only one
|
/// Resolve any type variables found in `value` -- but only one
|
||||||
/// level. So, if the variable `?X` is bound to some type
|
/// level. So, if the variable `?X` is bound to some type
|
||||||
/// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may
|
/// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may
|
||||||
/// itself be bound to a type).
|
/// itself be bound to a type).
|
||||||
///
|
///
|
||||||
|
@ -1720,7 +1720,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
if let None = self.tainted_by_errors() {
|
if let None = self.tainted_by_errors() {
|
||||||
// As a heuristic, just skip reporting region errors
|
// As a heuristic, just skip reporting region errors
|
||||||
// altogether if other errors have been reported while
|
// altogether if other errors have been reported while
|
||||||
// this infcx was in use. This is totally hokey but
|
// this infcx was in use. This is totally hokey but
|
||||||
// otherwise we have a hard time separating legit region
|
// otherwise we have a hard time separating legit region
|
||||||
// errors from silly ones.
|
// errors from silly ones.
|
||||||
self.report_region_errors(generic_param_scope, &errors);
|
self.report_region_errors(generic_param_scope, &errors);
|
||||||
|
|
|
@ -439,7 +439,7 @@ trait VidValuePair<'tcx>: Debug {
|
||||||
fn value_ty(&self) -> Ty<'tcx>;
|
fn value_ty(&self) -> Ty<'tcx>;
|
||||||
|
|
||||||
/// Extract the scopes that apply to whichever side of the tuple
|
/// Extract the scopes that apply to whichever side of the tuple
|
||||||
/// the vid was found on. See the comment where this is called
|
/// the vid was found on. See the comment where this is called
|
||||||
/// for more details on why we want them.
|
/// for more details on why we want them.
|
||||||
fn vid_scopes<'r, D: TypeRelatingDelegate<'tcx>>(
|
fn vid_scopes<'r, D: TypeRelatingDelegate<'tcx>>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -831,7 +831,7 @@ where
|
||||||
/// (these are not explicitly present in the ty representation right
|
/// (these are not explicitly present in the ty representation right
|
||||||
/// now). This visitor handles that: it descends the type, tracking
|
/// now). This visitor handles that: it descends the type, tracking
|
||||||
/// binder depth, and finds late-bound regions targeting the
|
/// binder depth, and finds late-bound regions targeting the
|
||||||
/// `for<..`>. For each of those, it creates an entry in
|
/// `for<..`>. For each of those, it creates an entry in
|
||||||
/// `bound_region_scope`.
|
/// `bound_region_scope`.
|
||||||
struct ScopeInstantiator<'me, 'tcx> {
|
struct ScopeInstantiator<'me, 'tcx> {
|
||||||
next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
|
next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
DefiningAnchor::Bind(_) => {
|
DefiningAnchor::Bind(_) => {
|
||||||
// Check that this is `impl Trait` type is
|
// Check that this is `impl Trait` type is
|
||||||
// declared by `parent_def_id` -- i.e., one whose
|
// declared by `parent_def_id` -- i.e., one whose
|
||||||
// value we are inferring. At present, this is
|
// value we are inferring. At present, this is
|
||||||
// always true during the first phase of
|
// always true during the first phase of
|
||||||
// type-check, but not always true later on during
|
// type-check, but not always true later on during
|
||||||
// NLL. Once we support named opaque types more fully,
|
// NLL. Once we support named opaque types more fully,
|
||||||
|
@ -380,7 +380,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
};
|
};
|
||||||
let item_kind = &self.tcx.hir().expect_item(def_id).kind;
|
let item_kind = &self.tcx.hir().expect_item(def_id).kind;
|
||||||
|
|
||||||
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
|
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
span,
|
span,
|
||||||
"weird opaque type: {:#?}, {:#?}",
|
"weird opaque type: {:#?}, {:#?}",
|
||||||
|
|
|
@ -153,7 +153,7 @@ fn compute_components<'tcx>(
|
||||||
out.push(Component::Projection(*data));
|
out.push(Component::Projection(*data));
|
||||||
} else {
|
} else {
|
||||||
// fallback case: hard code
|
// fallback case: hard code
|
||||||
// OutlivesProjectionComponents. Continue walking
|
// OutlivesProjectionComponents. Continue walking
|
||||||
// through and constrain Pi.
|
// through and constrain Pi.
|
||||||
let mut subcomponents = smallvec![];
|
let mut subcomponents = smallvec![];
|
||||||
let mut subvisited = SsoHashSet::new();
|
let mut subvisited = SsoHashSet::new();
|
||||||
|
@ -195,7 +195,7 @@ fn compute_components<'tcx>(
|
||||||
ty::Error(_) => {
|
ty::Error(_) => {
|
||||||
// (*) Function pointers and trait objects are both binders.
|
// (*) Function pointers and trait objects are both binders.
|
||||||
// In the RFC, this means we would add the bound regions to
|
// In the RFC, this means we would add the bound regions to
|
||||||
// the "bound regions list". In our representation, no such
|
// the "bound regions list". In our representation, no such
|
||||||
// list is maintained explicitly, because bound regions
|
// list is maintained explicitly, because bound regions
|
||||||
// themselves can be readily identified.
|
// themselves can be readily identified.
|
||||||
compute_components_recursive(tcx, ty.into(), out, visited);
|
compute_components_recursive(tcx, ty.into(), out, visited);
|
||||||
|
|
|
@ -371,7 +371,7 @@ where
|
||||||
// particular). :) First off, we have to choose between using the
|
// particular). :) First off, we have to choose between using the
|
||||||
// OutlivesProjectionEnv, OutlivesProjectionTraitDef, and
|
// OutlivesProjectionEnv, OutlivesProjectionTraitDef, and
|
||||||
// OutlivesProjectionComponent rules, any one of which is
|
// OutlivesProjectionComponent rules, any one of which is
|
||||||
// sufficient. If there are no inference variables involved, it's
|
// sufficient. If there are no inference variables involved, it's
|
||||||
// not hard to pick the right rule, but if there are, we're in a
|
// not hard to pick the right rule, but if there are, we're in a
|
||||||
// bit of a catch 22: if we picked which rule we were going to
|
// bit of a catch 22: if we picked which rule we were going to
|
||||||
// use, we could add constraints to the region inference graph
|
// use, we could add constraints to the region inference graph
|
||||||
|
|
|
@ -433,7 +433,7 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> {
|
||||||
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, ut::NoError> {
|
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, ut::NoError> {
|
||||||
match (value1, value2) {
|
match (value1, value2) {
|
||||||
// We never equate two type variables, both of which
|
// We never equate two type variables, both of which
|
||||||
// have known types. Instead, we recursively equate
|
// have known types. Instead, we recursively equate
|
||||||
// those types.
|
// those types.
|
||||||
(&TypeVariableValue::Known { .. }, &TypeVariableValue::Known { .. }) => {
|
(&TypeVariableValue::Known { .. }, &TypeVariableValue::Known { .. }) => {
|
||||||
bug!("equating two type variables, both of which have known types")
|
bug!("equating two type variables, both of which have known types")
|
||||||
|
|
|
@ -333,7 +333,7 @@ pub fn transitive_bounds<'tcx>(
|
||||||
/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
|
/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
|
||||||
/// define the given associated type `assoc_name`. It uses the
|
/// define the given associated type `assoc_name`. It uses the
|
||||||
/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
|
/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
|
||||||
/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
|
/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
|
||||||
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
|
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
|
||||||
pub fn transitive_bounds_that_define_assoc_type<'tcx>(
|
pub fn transitive_bounds_that_define_assoc_type<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! The idea with `rustc_lexer` is to make a reusable library,
|
//! The idea with `rustc_lexer` is to make a reusable library,
|
||||||
//! by separating out pure lexing and rustc-specific concerns, like spans,
|
//! by separating out pure lexing and rustc-specific concerns, like spans,
|
||||||
//! error reporting, and interning. So, rustc_lexer operates directly on `&str`,
|
//! error reporting, and interning. So, rustc_lexer operates directly on `&str`,
|
||||||
//! produces simple tokens which are a pair of type-tag and a bit of original text,
|
//! produces simple tokens which are a pair of type-tag and a bit of original text,
|
||||||
//! and does not report errors, instead storing them as flags on the token.
|
//! and does not report errors, instead storing them as flags on the token.
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -299,7 +299,7 @@ where
|
||||||
let tail = &tail[first_non_space..];
|
let tail = &tail[first_non_space..];
|
||||||
if let Some(c) = tail.chars().nth(0) {
|
if let Some(c) = tail.chars().nth(0) {
|
||||||
// For error reporting, we would like the span to contain the character that was not
|
// For error reporting, we would like the span to contain the character that was not
|
||||||
// skipped. The +1 is necessary to account for the leading \ that started the escape.
|
// skipped. The +1 is necessary to account for the leading \ that started the escape.
|
||||||
let end = start + first_non_space + c.len_utf8() + 1;
|
let end = start + first_non_space + c.len_utf8() + 1;
|
||||||
if c.is_whitespace() {
|
if c.is_whitespace() {
|
||||||
callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning));
|
callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning));
|
||||||
|
|
|
@ -50,7 +50,7 @@ rustc_index::newtype_index! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifications found at this position in the stack. This map only represents the lints
|
/// Specifications found at this position in the stack. This map only represents the lints
|
||||||
/// found for one set of attributes (like `shallow_lint_levels_on` does).
|
/// found for one set of attributes (like `shallow_lint_levels_on` does).
|
||||||
///
|
///
|
||||||
/// We store the level specifications as a linked list.
|
/// We store the level specifications as a linked list.
|
||||||
|
@ -163,7 +163,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
|
||||||
match attrs.map.range(..) {
|
match attrs.map.range(..) {
|
||||||
// There is only something to do if there are attributes at all.
|
// There is only something to do if there are attributes at all.
|
||||||
[] => {}
|
[] => {}
|
||||||
// Most of the time, there is only one attribute. Avoid fetching HIR in that case.
|
// Most of the time, there is only one attribute. Avoid fetching HIR in that case.
|
||||||
[(local_id, _)] => levels.add_id(HirId { owner, local_id: *local_id }),
|
[(local_id, _)] => levels.add_id(HirId { owner, local_id: *local_id }),
|
||||||
// Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
|
// Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
|
||||||
// a standard visit.
|
// a standard visit.
|
||||||
|
|
|
@ -277,7 +277,7 @@ impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> {
|
||||||
) -> rustc_errors::SubdiagnosticMessage,
|
) -> rustc_errors::SubdiagnosticMessage,
|
||||||
{
|
{
|
||||||
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
|
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
|
||||||
// bound. Let's see if this type does that.
|
// bound. Let's see if this type does that.
|
||||||
|
|
||||||
// We use a HIR visitor to walk the type.
|
// We use a HIR visitor to walk the type.
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
|
|
|
@ -461,7 +461,7 @@ extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
||||||
|
|
||||||
extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
|
extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
|
||||||
// Initializing the command-line options more than once is not allowed. So,
|
// Initializing the command-line options more than once is not allowed. So,
|
||||||
// check if they've already been initialized. (This could happen if we're
|
// check if they've already been initialized. (This could happen if we're
|
||||||
// being called from rustpkg, for example). If the arguments change, then
|
// being called from rustpkg, for example). If the arguments change, then
|
||||||
// that's just kinda unfortunate.
|
// that's just kinda unfortunate.
|
||||||
static bool Initialized = false;
|
static bool Initialized = false;
|
||||||
|
@ -1428,7 +1428,7 @@ LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is what we used to parse upstream bitcode for actual ThinLTO
|
// This is what we used to parse upstream bitcode for actual ThinLTO
|
||||||
// processing. We'll call this once per module optimized through ThinLTO, and
|
// processing. We'll call this once per module optimized through ThinLTO, and
|
||||||
// it'll be called concurrently on many threads.
|
// it'll be called concurrently on many threads.
|
||||||
extern "C" LLVMModuleRef
|
extern "C" LLVMModuleRef
|
||||||
LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
|
LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
|
||||||
|
|
|
@ -90,7 +90,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
|
||||||
let _prof_timer = tcx.sess.prof.generic_activity("write_crate_metadata");
|
let _prof_timer = tcx.sess.prof.generic_activity("write_crate_metadata");
|
||||||
|
|
||||||
// If the user requests metadata as output, rename `metadata_filename`
|
// If the user requests metadata as output, rename `metadata_filename`
|
||||||
// to the expected output `out_filename`. The match above should ensure
|
// to the expected output `out_filename`. The match above should ensure
|
||||||
// this file always exists.
|
// this file always exists.
|
||||||
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
|
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
|
||||||
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
|
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue