Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7e6d6e5

Browse files
committedAug 16, 2020
Auto merge of rust-lang#75609 - tmandry:rollup-yrcmgke, r=tmandry
Rollup of 10 pull requests Successful merges: - rust-lang#74204 (Don't visit foreign function bodies when lowering ast to hir) - rust-lang#74314 (rustc_typeck: construct {Closure,Generator}Substs more directly.) - rust-lang#74346 (Use LocalDefId instead of HirId for reachable_set elements.) - rust-lang#74399 (Move DelaySpanBugEmitted to ty::context) - rust-lang#75177 (Add regression test for issue-66768) - rust-lang#75223 (Add #[track_caller] to `Session::delay_span_bug`) - rust-lang#75423 (Move to intra-doc links for /library/core/src/hint.rs) - rust-lang#75485 (pin docs: add some forward references) - rust-lang#75569 (Bump minor version of emsdk to 1.38.47) - rust-lang#75596 (Switch to intra-doc links in /sys/windows/ext/{ffi,fs,process}.rs) Failed merges: r? @ghost
2 parents 9b4db69 + e46b1ef commit 7e6d6e5

File tree

20 files changed

+455
-196
lines changed

20 files changed

+455
-196
lines changed
 

‎library/core/src/hint.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use crate::intrinsics;
2424
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
2525
/// optimizations but will panic when executed.
2626
///
27-
/// [`unreachable!`]: ../macro.unreachable.html
2827
///
2928
/// # Example
3029
///
@@ -61,7 +60,7 @@ pub const unsafe fn unreachable_unchecked() -> ! {
6160
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
6261
/// do anything at all.
6362
///
64-
/// [`core::sync::atomic::spin_loop_hint`]: ../sync/atomic/fn.spin_loop_hint.html
63+
/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
6564
#[inline]
6665
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
6766
pub fn spin_loop() {

‎library/core/src/pin.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
//! as moving an object with pointers to itself will invalidate them, which could cause undefined
77
//! behavior.
88
//!
9-
//! A [`Pin<P>`] ensures that the pointee of any pointer type `P` has a stable location in memory,
10-
//! meaning it cannot be moved elsewhere and its memory cannot be deallocated
11-
//! until it gets dropped. We say that the pointee is "pinned".
9+
//! At a high level, a [`Pin<P>`] ensures that the pointee of any pointer type
10+
//! `P` has a stable location in memory, meaning it cannot be moved elsewhere
11+
//! and its memory cannot be deallocated until it gets dropped. We say that the
12+
//! pointee is "pinned". Things get more subtle when discussing types that
13+
//! combine pinned with non-pinned data; [see below](#projections-and-structural-pinning)
14+
//! for more details.
1215
//!
1316
//! By default, all types in Rust are movable. Rust allows passing all types by-value,
1417
//! and common smart-pointer types such as [`Box<T>`] and `&mut T` allow replacing and
@@ -61,6 +64,10 @@
6164
//!
6265
//! # Example: self-referential struct
6366
//!
67+
//! Before we go into more details to explain the guarantees and choices
68+
//! associated with `Pin<T>`, we discuss some examples for how it might be used.
69+
//! Feel free to [skip to where the theoretical discussion continues](#drop-guarantee).
70+
//!
6471
//! ```rust
6572
//! use std::pin::Pin;
6673
//! use std::marker::PhantomPinned;

‎library/std/src/sys/windows/ext/ffi.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030
//! [`OsString`] is the Rust wrapper for owned strings in the
3131
//! preferred representation of the operating system. On Windows,
3232
//! this struct gets augmented with an implementation of the
33-
//! [`OsStringExt`] trait, which has a [`from_wide`] method. This
33+
//! [`OsStringExt`] trait, which has a [`OsStringExt::from_wide`] method. This
3434
//! lets you create an [`OsString`] from a `&[u16]` slice; presumably
3535
//! you get such a slice out of a `WCHAR` Windows API.
3636
//!
3737
//! Similarly, [`OsStr`] is the Rust wrapper for borrowed strings from
3838
//! preferred representation of the operating system. On Windows, the
39-
//! [`OsStrExt`] trait provides the [`encode_wide`] method, which
39+
//! [`OsStrExt`] trait provides the [`OsStrExt::encode_wide`] method, which
4040
//! outputs an [`EncodeWide`] iterator. You can [`collect`] this
4141
//! iterator, for example, to obtain a `Vec<u16>`; you can later get a
4242
//! pointer to this vector's contents and feed it to Windows APIs.
@@ -47,15 +47,8 @@
4747
//! ill-formed UTF-16.
4848
//!
4949
//! [ill-formed-utf-16]: https://simonsapin.github.io/wtf-8/#ill-formed-utf-16
50-
//! [`OsString`]: ../../../ffi/struct.OsString.html
51-
//! [`OsStr`]: ../../../ffi/struct.OsStr.html
52-
//! [`OsStringExt`]: trait.OsStringExt.html
53-
//! [`OsStrExt`]: trait.OsStrExt.html
54-
//! [`EncodeWide`]: struct.EncodeWide.html
55-
//! [`from_wide`]: trait.OsStringExt.html#tymethod.from_wide
56-
//! [`encode_wide`]: trait.OsStrExt.html#tymethod.encode_wide
57-
//! [`collect`]: ../../../iter/trait.Iterator.html#method.collect
58-
//! [U+FFFD]: ../../../char/constant.REPLACEMENT_CHARACTER.html
50+
//! [`collect`]: crate::iter::Iterator::collect
51+
//! [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
5952
6053
#![stable(feature = "rust1", since = "1.0.0")]
6154

@@ -68,14 +61,12 @@ use crate::sys_common::{AsInner, FromInner};
6861
pub use crate::sys_common::wtf8::EncodeWide;
6962

7063
/// Windows-specific extensions to [`OsString`].
71-
///
72-
/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
7364
#[stable(feature = "rust1", since = "1.0.0")]
7465
pub trait OsStringExt {
7566
/// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
7667
/// 16-bit code units.
7768
///
78-
/// This is lossless: calling [`encode_wide`] on the resulting string
69+
/// This is lossless: calling [`OsStrExt::encode_wide`] on the resulting string
7970
/// will always return the original code units.
8071
///
8172
/// # Examples
@@ -89,8 +80,6 @@ pub trait OsStringExt {
8980
///
9081
/// let string = OsString::from_wide(&source[..]);
9182
/// ```
92-
///
93-
/// [`encode_wide`]: ./trait.OsStrExt.html#tymethod.encode_wide
9483
#[stable(feature = "rust1", since = "1.0.0")]
9584
fn from_wide(wide: &[u16]) -> Self;
9685
}
@@ -103,14 +92,12 @@ impl OsStringExt for OsString {
10392
}
10493

10594
/// Windows-specific extensions to [`OsStr`].
106-
///
107-
/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
10895
#[stable(feature = "rust1", since = "1.0.0")]
10996
pub trait OsStrExt {
11097
/// Re-encodes an `OsStr` as a wide character sequence, i.e., potentially
11198
/// ill-formed UTF-16.
11299
///
113-
/// This is lossless: calling [`OsString::from_wide`] and then
100+
/// This is lossless: calling [`OsStringExt::from_wide`] and then
114101
/// `encode_wide` on the result will yield the original code units.
115102
/// Note that the encoding does not add a final null terminator.
116103
///
@@ -128,8 +115,6 @@ pub trait OsStrExt {
128115
/// let result: Vec<u16> = string.encode_wide().collect();
129116
/// assert_eq!(&source[..], &result[..]);
130117
/// ```
131-
///
132-
/// [`OsString::from_wide`]: ./trait.OsStringExt.html#tymethod.from_wide
133118
#[stable(feature = "rust1", since = "1.0.0")]
134119
fn encode_wide(&self) -> EncodeWide<'_>;
135120
}

‎library/std/src/sys/windows/ext/fs.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ use crate::path::Path;
88
use crate::sys;
99
use crate::sys_common::{AsInner, AsInnerMut};
1010

11-
/// Windows-specific extensions to [`File`].
12-
///
13-
/// [`File`]: ../../../fs/struct.File.html
11+
/// Windows-specific extensions to [`fs::File`].
1412
#[stable(feature = "file_offset", since = "1.15.0")]
1513
pub trait FileExt {
1614
/// Seeks to a given position and reads a number of bytes.
@@ -94,8 +92,6 @@ impl FileExt for fs::File {
9492
}
9593

9694
/// Windows-specific extensions to [`fs::OpenOptions`].
97-
///
98-
/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
9995
#[stable(feature = "open_options_ext", since = "1.10.0")]
10096
pub trait OpenOptionsExt {
10197
/// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
@@ -295,7 +291,6 @@ impl OpenOptionsExt for OpenOptions {
295291
/// The data members that this trait exposes correspond to the members
296292
/// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
297293
///
298-
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
299294
/// [`BY_HANDLE_FILE_INFORMATION`]:
300295
/// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
301296
#[stable(feature = "metadata_ext", since = "1.1.0")]
@@ -499,11 +494,9 @@ impl MetadataExt for Metadata {
499494
}
500495
}
501496

502-
/// Windows-specific extensions to [`FileType`].
497+
/// Windows-specific extensions to [`fs::FileType`].
503498
///
504499
/// On Windows, a symbolic link knows whether it is a file or directory.
505-
///
506-
/// [`FileType`]: ../../../../std/fs/struct.FileType.html
507500
#[unstable(feature = "windows_file_type_ext", issue = "none")]
508501
pub trait FileTypeExt {
509502
/// Returns `true` if this file type is a symbolic link that is also a directory.

‎library/std/src/sys/windows/ext/process.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ impl IntoRawHandle for process::ChildStderr {
7373
}
7474

7575
/// Windows-specific extensions to [`process::ExitStatus`].
76-
///
77-
/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html
7876
#[stable(feature = "exit_status_from", since = "1.12.0")]
7977
pub trait ExitStatusExt {
8078
/// Creates a new `ExitStatus` from the raw underlying `u32` return value of
@@ -91,8 +89,6 @@ impl ExitStatusExt for process::ExitStatus {
9189
}
9290

9391
/// Windows-specific extensions to the [`process::Command`] builder.
94-
///
95-
/// [`process::Command`]: ../../../../std/process/struct.Command.html
9692
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
9793
pub trait CommandExt {
9894
/// Sets the [process creation flags][1] to be passed to `CreateProcess`.

‎src/ci/docker/scripts/emscripten.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ exit 1
1919

2020
git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
2121
cd /emsdk-portable
22-
hide_output ./emsdk install 1.38.46-upstream
23-
./emsdk activate 1.38.46-upstream
22+
hide_output ./emsdk install 1.38.47-upstream
23+
./emsdk activate 1.38.47-upstream

‎src/librustc_ast_lowering/item.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::Arena;
55
use rustc_ast::ast::*;
66
use rustc_ast::node_id::NodeMap;
77
use rustc_ast::ptr::P;
8-
use rustc_ast::visit::{self, AssocCtxt, Visitor};
8+
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
99
use rustc_data_structures::fx::FxHashSet;
1010
use rustc_errors::struct_span_err;
1111
use rustc_hir as hir;
@@ -75,6 +75,18 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
7575
}
7676
}
7777

78+
fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) {
79+
match fk {
80+
FnKind::Fn(FnCtxt::Foreign, _, sig, _, _) => {
81+
self.visit_fn_header(&sig.header);
82+
visit::walk_fn_decl(self, &sig.decl);
83+
// Don't visit the foreign function body even if it has one, since lowering the
84+
// body would have no meaning and will have already been caught as a parse error.
85+
}
86+
_ => visit::walk_fn(self, fk, sp),
87+
}
88+
}
89+
7890
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
7991
self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
8092
AssocCtxt::Trait => {

‎src/librustc_codegen_ssa/back/symbol_export.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
6161
let mut reachable_non_generics: DefIdMap<_> = tcx
6262
.reachable_set(LOCAL_CRATE)
6363
.iter()
64-
.filter_map(|&hir_id| {
64+
.filter_map(|&def_id| {
6565
// We want to ignore some FFI functions that are not exposed from
6666
// this crate. Reachable FFI functions can be lumped into two
6767
// categories:
@@ -75,9 +75,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
7575
//
7676
// As a result, if this id is an FFI item (foreign item) then we only
7777
// let it through if it's included statically.
78-
match tcx.hir().get(hir_id) {
78+
match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
7979
Node::ForeignItem(..) => {
80-
let def_id = tcx.hir().local_def_id(hir_id);
8180
tcx.is_statically_included_foreign_item(def_id).then_some(def_id)
8281
}
8382

@@ -87,7 +86,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
8786
..
8887
})
8988
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
90-
let def_id = tcx.hir().local_def_id(hir_id);
9189
let generics = tcx.generics_of(def_id);
9290
if !generics.requires_monomorphization(tcx)
9391
// Functions marked with #[inline] are codegened with "internal"
@@ -361,7 +359,7 @@ fn upstream_drop_glue_for_provider<'tcx>(
361359

362360
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
363361
if let Some(def_id) = def_id.as_local() {
364-
!tcx.reachable_set(LOCAL_CRATE).contains(&tcx.hir().local_def_id_to_hir_id(def_id))
362+
!tcx.reachable_set(LOCAL_CRATE).contains(&def_id)
365363
} else {
366364
bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id)
367365
}

‎src/librustc_middle/query/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,8 @@ rustc_queries! {
740740
}
741741

742742
Other {
743-
query reachable_set(_: CrateNum) -> &'tcx HirIdSet {
743+
query reachable_set(_: CrateNum) -> FxHashSet<LocalDefId> {
744+
storage(ArenaCacheSelector<'tcx>)
744745
desc { "reachability" }
745746
}
746747

‎src/librustc_middle/ty/consts/kind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub enum ConstKind<'tcx> {
3434

3535
/// A placeholder for a const which could not be computed; this is
3636
/// propagated to avoid useless error messages.
37-
Error(ty::sty::DelaySpanBugEmitted),
37+
Error(ty::DelaySpanBugEmitted),
3838
}
3939

4040
#[cfg(target_arch = "x86_64")]

‎src/librustc_middle/ty/context.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ use std::mem;
6565
use std::ops::{Bound, Deref};
6666
use std::sync::Arc;
6767

68+
/// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
69+
/// except through `tcx.err*()`, which are in this module.
70+
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
71+
#[derive(TyEncodable, TyDecodable, HashStable)]
72+
pub struct DelaySpanBugEmitted(());
73+
6874
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
6975

7076
pub struct CtxtInterners<'tcx> {
@@ -1171,18 +1177,15 @@ impl<'tcx> TyCtxt<'tcx> {
11711177
#[track_caller]
11721178
pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
11731179
self.sess.delay_span_bug(span, msg);
1174-
self.mk_ty(Error(super::sty::DelaySpanBugEmitted(())))
1180+
self.mk_ty(Error(DelaySpanBugEmitted(())))
11751181
}
11761182

11771183
/// Like `err` but for constants.
11781184
#[track_caller]
11791185
pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
11801186
self.sess
11811187
.delay_span_bug(DUMMY_SP, "ty::ConstKind::Error constructed but no error reported.");
1182-
self.mk_const(ty::Const {
1183-
val: ty::ConstKind::Error(super::sty::DelaySpanBugEmitted(())),
1184-
ty,
1185-
})
1188+
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
11861189
}
11871190

11881191
pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {

‎src/librustc_middle/ty/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNER
6060
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
6161
pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig};
6262
pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts};
63+
pub use self::sty::{ClosureSubstsParts, GeneratorSubstsParts};
6364
pub use self::sty::{ConstVid, FloatVid, IntVid, RegionVid, TyVid};
6465
pub use self::sty::{ExistentialPredicate, InferTy, ParamConst, ParamTy, ProjectionTy};
6566
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
@@ -72,8 +73,8 @@ pub use self::binding::BindingMode::*;
7273

7374
pub use self::context::{tls, FreeRegionInfo, TyCtxt};
7475
pub use self::context::{
75-
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy,
76-
UserType, UserTypeAnnotationIndex,
76+
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
77+
DelaySpanBugEmitted, ResolvedOpaqueTy, UserType, UserTypeAnnotationIndex,
7778
};
7879
pub use self::context::{
7980
CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckResults,

‎src/librustc_middle/ty/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use rustc_hir as hir;
4343
use rustc_hir::def::DefKind;
4444
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
4545
use rustc_hir::lang_items::{LangItem, LanguageItems};
46-
use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
46+
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
4747
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
4848
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
4949
use rustc_session::utils::NativeLibKind;

‎src/librustc_middle/ty/sty.rs

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
1010
use crate::ty::{
1111
self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
1212
};
13-
use crate::ty::{List, ParamEnv, TyS};
13+
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
1414
use polonius_engine::Atom;
1515
use rustc_ast::ast;
1616
use rustc_data_structures::captures::Captures;
@@ -212,12 +212,6 @@ impl TyKind<'tcx> {
212212
}
213213
}
214214

215-
/// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
216-
/// except through `tcx.err*()`.
217-
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
218-
#[derive(TyEncodable, TyDecodable, HashStable)]
219-
pub struct DelaySpanBugEmitted(pub(super) ());
220-
221215
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
222216
#[cfg(target_arch = "x86_64")]
223217
static_assert_size!(TyKind<'_>, 24);
@@ -325,24 +319,39 @@ pub struct ClosureSubsts<'tcx> {
325319
pub substs: SubstsRef<'tcx>,
326320
}
327321

328-
/// Struct returned by `split()`. Note that these are subslices of the
329-
/// parent slice and not canonical substs themselves.
330-
struct SplitClosureSubsts<'tcx> {
331-
parent: &'tcx [GenericArg<'tcx>],
332-
closure_kind_ty: GenericArg<'tcx>,
333-
closure_sig_as_fn_ptr_ty: GenericArg<'tcx>,
334-
tupled_upvars_ty: GenericArg<'tcx>,
322+
/// Struct returned by `split()`.
323+
pub struct ClosureSubstsParts<'tcx, T> {
324+
pub parent_substs: &'tcx [GenericArg<'tcx>],
325+
pub closure_kind_ty: T,
326+
pub closure_sig_as_fn_ptr_ty: T,
327+
pub tupled_upvars_ty: T,
335328
}
336329

337330
impl<'tcx> ClosureSubsts<'tcx> {
338-
/// Divides the closure substs into their respective
339-
/// components. Single source of truth with respect to the
340-
/// ordering.
341-
fn split(self) -> SplitClosureSubsts<'tcx> {
331+
/// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs`
332+
/// for the closure parent, alongside additional closure-specific components.
333+
pub fn new(
334+
tcx: TyCtxt<'tcx>,
335+
parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
336+
) -> ClosureSubsts<'tcx> {
337+
ClosureSubsts {
338+
substs: tcx.mk_substs(
339+
parts.parent_substs.iter().copied().chain(
340+
[parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
341+
.iter()
342+
.map(|&ty| ty.into()),
343+
),
344+
),
345+
}
346+
}
347+
348+
/// Divides the closure substs into their respective components.
349+
/// The ordering assumed here must match that used by `ClosureSubsts::new` above.
350+
fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> {
342351
match self.substs[..] {
343-
[ref parent @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
344-
SplitClosureSubsts {
345-
parent,
352+
[ref parent_substs @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
353+
ClosureSubstsParts {
354+
parent_substs,
346355
closure_kind_ty,
347356
closure_sig_as_fn_ptr_ty,
348357
tupled_upvars_ty,
@@ -363,7 +372,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
363372

364373
/// Returns the substitutions of the closure's parent.
365374
pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
366-
self.split().parent
375+
self.split().parent_substs
367376
}
368377

369378
#[inline]
@@ -418,21 +427,46 @@ pub struct GeneratorSubsts<'tcx> {
418427
pub substs: SubstsRef<'tcx>,
419428
}
420429

421-
struct SplitGeneratorSubsts<'tcx> {
422-
parent: &'tcx [GenericArg<'tcx>],
423-
resume_ty: GenericArg<'tcx>,
424-
yield_ty: GenericArg<'tcx>,
425-
return_ty: GenericArg<'tcx>,
426-
witness: GenericArg<'tcx>,
427-
tupled_upvars_ty: GenericArg<'tcx>,
430+
pub struct GeneratorSubstsParts<'tcx, T> {
431+
pub parent_substs: &'tcx [GenericArg<'tcx>],
432+
pub resume_ty: T,
433+
pub yield_ty: T,
434+
pub return_ty: T,
435+
pub witness: T,
436+
pub tupled_upvars_ty: T,
428437
}
429438

430439
impl<'tcx> GeneratorSubsts<'tcx> {
431-
fn split(self) -> SplitGeneratorSubsts<'tcx> {
440+
/// Construct `GeneratorSubsts` from `GeneratorSubstsParts`, containing `Substs`
441+
/// for the generator parent, alongside additional generator-specific components.
442+
pub fn new(
443+
tcx: TyCtxt<'tcx>,
444+
parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
445+
) -> GeneratorSubsts<'tcx> {
446+
GeneratorSubsts {
447+
substs: tcx.mk_substs(
448+
parts.parent_substs.iter().copied().chain(
449+
[
450+
parts.resume_ty,
451+
parts.yield_ty,
452+
parts.return_ty,
453+
parts.witness,
454+
parts.tupled_upvars_ty,
455+
]
456+
.iter()
457+
.map(|&ty| ty.into()),
458+
),
459+
),
460+
}
461+
}
462+
463+
/// Divides the generator substs into their respective components.
464+
/// The ordering assumed here must match that used by `GeneratorSubsts::new` above.
465+
fn split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>> {
432466
match self.substs[..] {
433-
[ref parent @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
434-
SplitGeneratorSubsts {
435-
parent,
467+
[ref parent_substs @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
468+
GeneratorSubstsParts {
469+
parent_substs,
436470
resume_ty,
437471
yield_ty,
438472
return_ty,
@@ -455,7 +489,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
455489

456490
/// Returns the substitutions of the generator's parent.
457491
pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
458-
self.split().parent
492+
self.split().parent_substs
459493
}
460494

461495
/// This describes the types that can be contained in a generator.

‎src/librustc_passes/reachable.rs

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use rustc_hir::def_id::LOCAL_CRATE;
1212
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1313
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1414
use rustc_hir::itemlikevisit::ItemLikeVisitor;
15-
use rustc_hir::{HirIdSet, Node};
15+
use rustc_hir::Node;
1616
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
1717
use rustc_middle::middle::privacy;
1818
use rustc_middle::ty::query::Providers;
19-
use rustc_middle::ty::{self, TyCtxt};
19+
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
2020
use rustc_session::config::CrateType;
2121
use rustc_target::spec::abi::Abi;
2222

@@ -65,10 +65,11 @@ struct ReachableContext<'tcx> {
6565
tcx: TyCtxt<'tcx>,
6666
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
6767
// The set of items which must be exported in the linkage sense.
68-
reachable_symbols: HirIdSet,
68+
reachable_symbols: FxHashSet<LocalDefId>,
6969
// A worklist of item IDs. Each item ID in this worklist will be inlined
7070
// and will be scanned for further references.
71-
worklist: Vec<hir::HirId>,
71+
// FIXME(eddyb) benchmark if this would be faster as a `VecDeque`.
72+
worklist: Vec<LocalDefId>,
7273
// Whether any output of this compilation is a library
7374
any_library: bool,
7475
}
@@ -100,37 +101,27 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
100101
_ => None,
101102
};
102103

103-
match res {
104-
Some(Res::Local(hir_id)) => {
105-
self.reachable_symbols.insert(hir_id);
106-
}
107-
Some(res) => {
108-
if let Some((hir_id, def_id)) = res.opt_def_id().and_then(|def_id| {
109-
def_id
110-
.as_local()
111-
.map(|def_id| (self.tcx.hir().local_def_id_to_hir_id(def_id), def_id))
112-
}) {
113-
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
114-
self.worklist.push(hir_id);
115-
} else {
116-
match res {
117-
// If this path leads to a constant, then we need to
118-
// recurse into the constant to continue finding
119-
// items that are reachable.
120-
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
121-
self.worklist.push(hir_id);
122-
}
104+
if let Some(res) = res {
105+
if let Some(def_id) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
106+
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
107+
self.worklist.push(def_id);
108+
} else {
109+
match res {
110+
// If this path leads to a constant, then we need to
111+
// recurse into the constant to continue finding
112+
// items that are reachable.
113+
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
114+
self.worklist.push(def_id);
115+
}
123116

124-
// If this wasn't a static, then the destination is
125-
// surely reachable.
126-
_ => {
127-
self.reachable_symbols.insert(hir_id);
128-
}
117+
// If this wasn't a static, then the destination is
118+
// surely reachable.
119+
_ => {
120+
self.reachable_symbols.insert(def_id);
129121
}
130122
}
131123
}
132124
}
133-
_ => {}
134125
}
135126

136127
intravisit::walk_expr(self, expr)
@@ -209,13 +200,15 @@ impl<'tcx> ReachableContext<'tcx> {
209200
continue;
210201
}
211202

212-
if let Some(ref item) = self.tcx.hir().find(search_item) {
203+
if let Some(ref item) =
204+
self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(search_item))
205+
{
213206
self.propagate_node(item, search_item);
214207
}
215208
}
216209
}
217210

218-
fn propagate_node(&mut self, node: &Node<'tcx>, search_item: hir::HirId) {
211+
fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
219212
if !self.any_library {
220213
// If we are building an executable, only explicitly extern
221214
// types need to be exported.
@@ -297,8 +290,9 @@ impl<'tcx> ReachableContext<'tcx> {
297290
self.visit_nested_body(body);
298291
}
299292
hir::ImplItemKind::Fn(_, body) => {
300-
let did = self.tcx.hir().get_parent_did(search_item);
301-
if method_might_be_inlined(self.tcx, impl_item, did) {
293+
let impl_def_id =
294+
self.tcx.parent(search_item.to_def_id()).unwrap().expect_local();
295+
if method_might_be_inlined(self.tcx, impl_item, impl_def_id) {
302296
self.visit_nested_body(body)
303297
}
304298
}
@@ -317,7 +311,9 @@ impl<'tcx> ReachableContext<'tcx> {
317311
_ => {
318312
bug!(
319313
"found unexpected node kind in worklist: {} ({:?})",
320-
self.tcx.hir().node_to_string(search_item),
314+
self.tcx
315+
.hir()
316+
.node_to_string(self.tcx.hir().local_def_id_to_hir_id(search_item)),
321317
node,
322318
);
323319
}
@@ -336,7 +332,7 @@ impl<'tcx> ReachableContext<'tcx> {
336332
struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
337333
tcx: TyCtxt<'tcx>,
338334
access_levels: &'a privacy::AccessLevels,
339-
worklist: &'a mut Vec<hir::HirId>,
335+
worklist: &'a mut Vec<LocalDefId>,
340336
}
341337

342338
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
@@ -349,13 +345,16 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
349345
if codegen_attrs.contains_extern_indicator()
350346
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
351347
{
352-
self.worklist.push(item.hir_id);
348+
self.worklist.push(def_id);
353349
}
354350

355351
// We need only trait impls here, not inherent impls, and only non-exported ones
356352
if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
357353
if !self.access_levels.is_reachable(item.hir_id) {
358-
self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id));
354+
// FIXME(#53488) remove `let`
355+
let tcx = self.tcx;
356+
self.worklist
357+
.extend(items.iter().map(|ii_ref| tcx.hir().local_def_id(ii_ref.id.hir_id)));
359358

360359
let trait_def_id = match trait_ref.path.res {
361360
Res::Def(DefKind::Trait, def_id) => def_id,
@@ -366,12 +365,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
366365
return;
367366
}
368367

369-
// FIXME(#53488) remove `let`
370-
let tcx = self.tcx;
371-
self.worklist
372-
.extend(tcx.provided_trait_methods(trait_def_id).map(|assoc| {
373-
tcx.hir().local_def_id_to_hir_id(assoc.def_id.expect_local())
374-
}));
368+
self.worklist.extend(
369+
tcx.provided_trait_methods(trait_def_id)
370+
.map(|assoc| assoc.def_id.expect_local()),
371+
);
375372
}
376373
}
377374
}
@@ -383,7 +380,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
383380
}
384381
}
385382

386-
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet {
383+
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> FxHashSet<LocalDefId> {
387384
debug_assert!(crate_num == LOCAL_CRATE);
388385

389386
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
@@ -405,11 +402,13 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
405402
// If other crates link to us, they're going to expect to be able to
406403
// use the lang items, so we need to be sure to mark them as
407404
// exported.
408-
reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
405+
reachable_context
406+
.worklist
407+
.extend(access_levels.map.iter().map(|(id, _)| tcx.hir().local_def_id(*id)));
409408
for item in tcx.lang_items().items().iter() {
410-
if let Some(did) = *item {
411-
if let Some(hir_id) = did.as_local().map(|did| tcx.hir().local_def_id_to_hir_id(did)) {
412-
reachable_context.worklist.push(hir_id);
409+
if let Some(def_id) = *item {
410+
if let Some(def_id) = def_id.as_local() {
411+
reachable_context.worklist.push(def_id);
413412
}
414413
}
415414
}
@@ -428,7 +427,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
428427
debug!("Inline reachability shows: {:?}", reachable_context.reachable_symbols);
429428

430429
// Return the set of reachable symbols.
431-
tcx.arena.alloc(reachable_context.reachable_symbols)
430+
reachable_context.reachable_symbols
432431
}
433432

434433
pub fn provide(providers: &mut Providers) {

‎src/librustc_session/session.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ impl Session {
437437
}
438438
}
439439
/// Delay a span_bug() call until abort_if_errors()
440+
#[track_caller]
440441
pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
441442
self.diagnostic().delay_span_bug(sp, msg)
442443
}

‎src/librustc_typeck/check/closure.rs

Lines changed: 50 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
1111
use rustc_infer::infer::{InferOk, InferResult};
1212
use rustc_middle::ty::fold::TypeFoldable;
1313
use rustc_middle::ty::subst::InternalSubsts;
14-
use rustc_middle::ty::{self, GenericParamDefKind, Ty};
14+
use rustc_middle::ty::{self, Ty};
1515
use rustc_span::source_map::Span;
1616
use rustc_target::spec::abi::Abi;
1717
use rustc_trait_selection::traits::error_reporting::ArgKind;
@@ -76,60 +76,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7676
let generator_types =
7777
check_fn(self, self.param_env, liberated_sig, decl, expr.hir_id, body, gen).1;
7878

79-
let base_substs = InternalSubsts::identity_for_item(
79+
let parent_substs = InternalSubsts::identity_for_item(
8080
self.tcx,
8181
self.tcx.closure_base_def_id(expr_def_id.to_def_id()),
8282
);
83-
// HACK(eddyb) this hardcodes indices into substs but it should rely on
84-
// `ClosureSubsts` and `GeneratorSubsts` providing constructors, instead.
85-
// That would also remove the need for most of the inference variables,
86-
// as they immediately unified with the actual type below, including
87-
// the `InferCtxt::closure_sig` and `ClosureSubsts::sig_ty` methods.
88-
let tupled_upvars_idx = base_substs.len() + if generator_types.is_some() { 4 } else { 2 };
89-
let substs =
90-
base_substs.extend_to(self.tcx, expr_def_id.to_def_id(), |param, _| match param.kind {
91-
GenericParamDefKind::Lifetime => span_bug!(expr.span, "closure has lifetime param"),
92-
GenericParamDefKind::Type { .. } => if param.index as usize == tupled_upvars_idx {
93-
self.tcx.mk_tup(self.tcx.upvars_mentioned(expr_def_id).iter().flat_map(
94-
|upvars| {
95-
upvars.iter().map(|(&var_hir_id, _)| {
96-
// Create type variables (for now) to represent the transformed
97-
// types of upvars. These will be unified during the upvar
98-
// inference phase (`upvar.rs`).
99-
self.infcx.next_ty_var(TypeVariableOrigin {
100-
// FIXME(eddyb) distinguish upvar inference variables from the rest.
101-
kind: TypeVariableOriginKind::ClosureSynthetic,
102-
span: self.tcx.hir().span(var_hir_id),
103-
})
104-
})
105-
},
106-
))
107-
} else {
108-
// Create type variables (for now) to represent the various
109-
// pieces of information kept in `{Closure,Generic}Substs`.
110-
// They will either be unified below, or later during the upvar
111-
// inference phase (`upvar.rs`)
83+
84+
let tupled_upvars_ty =
85+
self.tcx.mk_tup(self.tcx.upvars_mentioned(expr_def_id).iter().flat_map(|upvars| {
86+
upvars.iter().map(|(&var_hir_id, _)| {
87+
// Create type variables (for now) to represent the transformed
88+
// types of upvars. These will be unified during the upvar
89+
// inference phase (`upvar.rs`).
11290
self.infcx.next_ty_var(TypeVariableOrigin {
91+
// FIXME(eddyb) distinguish upvar inference variables from the rest.
11392
kind: TypeVariableOriginKind::ClosureSynthetic,
114-
span: expr.span,
93+
span: self.tcx.hir().span(var_hir_id),
11594
})
116-
}
117-
.into(),
118-
GenericParamDefKind::Const => span_bug!(expr.span, "closure has const param"),
119-
});
95+
})
96+
}));
97+
12098
if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types
12199
{
122-
let generator_substs = substs.as_generator();
123-
self.demand_eqtype(expr.span, resume_ty, generator_substs.resume_ty());
124-
self.demand_eqtype(expr.span, yield_ty, generator_substs.yield_ty());
125-
self.demand_eqtype(expr.span, liberated_sig.output(), generator_substs.return_ty());
126-
self.demand_eqtype(expr.span, interior, generator_substs.witness());
127-
128-
// HACK(eddyb) this forces the types equated above into `substs` but
129-
// it should rely on `GeneratorSubsts` providing a constructor, instead.
130-
let substs = self.resolve_vars_if_possible(&substs);
100+
let generator_substs = ty::GeneratorSubsts::new(
101+
self.tcx,
102+
ty::GeneratorSubstsParts {
103+
parent_substs,
104+
resume_ty,
105+
yield_ty,
106+
return_ty: liberated_sig.output(),
107+
witness: interior,
108+
tupled_upvars_ty,
109+
},
110+
);
131111

132-
return self.tcx.mk_generator(expr_def_id.to_def_id(), substs, movability);
112+
return self.tcx.mk_generator(
113+
expr_def_id.to_def_id(),
114+
generator_substs.substs,
115+
movability,
116+
);
133117
}
134118

135119
// Tuple up the arguments and insert the resulting function type into
@@ -149,18 +133,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
149133
expr_def_id, sig, opt_kind
150134
);
151135

152-
let sig_fn_ptr_ty = self.tcx.mk_fn_ptr(sig);
153-
self.demand_eqtype(expr.span, sig_fn_ptr_ty, substs.as_closure().sig_as_fn_ptr_ty());
136+
let closure_kind_ty = match opt_kind {
137+
Some(kind) => kind.to_ty(self.tcx),
154138

155-
if let Some(kind) = opt_kind {
156-
self.demand_eqtype(expr.span, kind.to_ty(self.tcx), substs.as_closure().kind_ty());
157-
}
139+
// Create a type variable (for now) to represent the closure kind.
140+
// It will be unified during the upvar inference phase (`upvar.rs`)
141+
None => self.infcx.next_ty_var(TypeVariableOrigin {
142+
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
143+
kind: TypeVariableOriginKind::ClosureSynthetic,
144+
span: expr.span,
145+
}),
146+
};
158147

159-
// HACK(eddyb) this forces the types equated above into `substs` but
160-
// it should rely on `ClosureSubsts` providing a constructor, instead.
161-
let substs = self.resolve_vars_if_possible(&substs);
148+
let closure_substs = ty::ClosureSubsts::new(
149+
self.tcx,
150+
ty::ClosureSubstsParts {
151+
parent_substs,
152+
closure_kind_ty,
153+
closure_sig_as_fn_ptr_ty: self.tcx.mk_fn_ptr(sig),
154+
tupled_upvars_ty,
155+
},
156+
);
162157

163-
let closure_type = self.tcx.mk_closure(expr_def_id.to_def_id(), substs);
158+
let closure_type = self.tcx.mk_closure(expr_def_id.to_def_id(), closure_substs.substs);
164159

165160
debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type);
166161

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Previously this ICE'd because `fn g()` would be lowered, but the block associated with `fn f()`
2+
// wasn't.
3+
4+
// compile-flags: --crate-type=lib
5+
6+
extern "C" {
7+
fn f() {
8+
//~^ incorrect function inside `extern` block
9+
fn g() {}
10+
}
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: incorrect function inside `extern` block
2+
--> $DIR/issue-74120-lowering-of-ffi-block-bodies.rs:7:8
3+
|
4+
LL | extern "C" {
5+
| ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
6+
LL | fn f() {
7+
| ________^___-
8+
| | |
9+
| | cannot have a body
10+
LL | |
11+
LL | | fn g() {}
12+
LL | | }
13+
| |_____- help: remove the invalid body: `;`
14+
|
15+
= help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
16+
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
17+
18+
error: aborting due to previous error
19+

‎src/test/ui/issues/issue-66768.rs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
// Regression test for #66768.
2+
// check-pass
3+
#![allow(dead_code)]
4+
//-^ "dead code" is needed to reproduce the issue.
5+
6+
use std::marker::PhantomData;
7+
use std::ops::{Add, Mul};
8+
9+
fn problematic_function<Space>(material_surface_element: Edge2dElement)
10+
where
11+
DefaultAllocator: FiniteElementAllocator<DimU1, Space>,
12+
{
13+
let _: Point2<f64> = material_surface_element.map_reference_coords().into();
14+
}
15+
16+
impl<T> ArrayLength<T> for UTerm {
17+
type ArrayType = ();
18+
}
19+
impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
20+
type ArrayType = GenericArrayImplEven<T, N>;
21+
}
22+
impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
23+
type ArrayType = GenericArrayImplOdd<T, N>;
24+
}
25+
impl<U> Add<U> for UTerm {
26+
type Output = U;
27+
fn add(self, _: U) -> Self::Output {
28+
unimplemented!()
29+
}
30+
}
31+
impl<Ul, Ur> Add<UInt<Ur, B1>> for UInt<Ul, B0>
32+
where
33+
Ul: Add<Ur>,
34+
{
35+
type Output = UInt<Sum<Ul, Ur>, B1>;
36+
fn add(self, _: UInt<Ur, B1>) -> Self::Output {
37+
unimplemented!()
38+
}
39+
}
40+
impl<U> Mul<U> for UTerm {
41+
type Output = UTerm;
42+
fn mul(self, _: U) -> Self {
43+
unimplemented!()
44+
}
45+
}
46+
impl<Ul, B, Ur> Mul<UInt<Ur, B>> for UInt<Ul, B0>
47+
where
48+
Ul: Mul<UInt<Ur, B>>,
49+
{
50+
type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
51+
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
52+
unimplemented!()
53+
}
54+
}
55+
impl<Ul, B, Ur> Mul<UInt<Ur, B>> for UInt<Ul, B1>
56+
where
57+
Ul: Mul<UInt<Ur, B>>,
58+
UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>,
59+
{
60+
type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
61+
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
62+
unimplemented!()
63+
}
64+
}
65+
impl<N, R, C> Allocator<N, R, C> for DefaultAllocator
66+
where
67+
R: DimName,
68+
C: DimName,
69+
R::Value: Mul<C::Value>,
70+
Prod<R::Value, C::Value>: ArrayLength<N>,
71+
{
72+
type Buffer = ArrayStorage<N, R, C>;
73+
fn allocate_uninitialized(_: R, _: C) -> Self::Buffer {
74+
unimplemented!()
75+
}
76+
fn allocate_from_iterator<I>(_: R, _: C, _: I) -> Self::Buffer {
77+
unimplemented!()
78+
}
79+
}
80+
impl<N, C> Allocator<N, Dynamic, C> for DefaultAllocator {
81+
type Buffer = VecStorage<N, Dynamic, C>;
82+
fn allocate_uninitialized(_: Dynamic, _: C) -> Self::Buffer {
83+
unimplemented!()
84+
}
85+
fn allocate_from_iterator<I>(_: Dynamic, _: C, _: I) -> Self::Buffer {
86+
unimplemented!()
87+
}
88+
}
89+
impl DimName for DimU1 {
90+
type Value = U1;
91+
fn name() -> Self {
92+
unimplemented!()
93+
}
94+
}
95+
impl DimName for DimU2 {
96+
type Value = U2;
97+
fn name() -> Self {
98+
unimplemented!()
99+
}
100+
}
101+
impl<N, D> From<VectorN<N, D>> for Point<N, D>
102+
where
103+
DefaultAllocator: Allocator<N, D>,
104+
{
105+
fn from(_: VectorN<N, D>) -> Self {
106+
unimplemented!()
107+
}
108+
}
109+
impl<GeometryDim, NodalDim> FiniteElementAllocator<GeometryDim, NodalDim> for DefaultAllocator where
110+
DefaultAllocator: Allocator<f64, GeometryDim> + Allocator<f64, NodalDim>
111+
{
112+
}
113+
impl ReferenceFiniteElement for Edge2dElement {
114+
type NodalDim = DimU1;
115+
}
116+
impl FiniteElement<DimU2> for Edge2dElement {
117+
fn map_reference_coords(&self) -> Vector2<f64> {
118+
unimplemented!()
119+
}
120+
}
121+
122+
type Owned<N, R, C> = <DefaultAllocator as Allocator<N, R, C>>::Buffer;
123+
type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
124+
type VectorN<N, D> = MatrixMN<N, D, DimU1>;
125+
type Vector2<N> = VectorN<N, DimU2>;
126+
type Point2<N> = Point<N, DimU2>;
127+
type U1 = UInt<UTerm, B1>;
128+
type U2 = UInt<UInt<UTerm, B1>, B0>;
129+
type Sum<A, B> = <A as Add<B>>::Output;
130+
type Prod<A, B> = <A as Mul<B>>::Output;
131+
132+
struct GenericArray<T, U: ArrayLength<T>> {
133+
_data: U::ArrayType,
134+
}
135+
struct GenericArrayImplEven<T, U> {
136+
_parent2: U,
137+
_marker: T,
138+
}
139+
struct GenericArrayImplOdd<T, U> {
140+
_parent2: U,
141+
_data: T,
142+
}
143+
struct B0;
144+
struct B1;
145+
struct UTerm;
146+
struct UInt<U, B> {
147+
_marker: PhantomData<(U, B)>,
148+
}
149+
struct DefaultAllocator;
150+
struct Dynamic;
151+
struct DimU1;
152+
struct DimU2;
153+
struct Matrix<N, R, C, S> {
154+
_data: S,
155+
_phantoms: PhantomData<(N, R, C)>,
156+
}
157+
struct ArrayStorage<N, R, C>
158+
where
159+
R: DimName,
160+
C: DimName,
161+
R::Value: Mul<C::Value>,
162+
Prod<R::Value, C::Value>: ArrayLength<N>,
163+
{
164+
_data: GenericArray<N, Prod<R::Value, C::Value>>,
165+
}
166+
struct VecStorage<N, R, C> {
167+
_data: N,
168+
_nrows: R,
169+
_ncols: C,
170+
}
171+
struct Point<N, D>
172+
where
173+
DefaultAllocator: Allocator<N, D>,
174+
{
175+
_coords: VectorN<N, D>,
176+
}
177+
struct Edge2dElement;
178+
179+
trait ArrayLength<T> {
180+
type ArrayType;
181+
}
182+
trait Allocator<Scalar, R, C = DimU1> {
183+
type Buffer;
184+
fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer;
185+
fn allocate_from_iterator<I>(nrows: R, ncols: C, iter: I) -> Self::Buffer;
186+
}
187+
trait DimName {
188+
type Value;
189+
fn name() -> Self;
190+
}
191+
trait FiniteElementAllocator<GeometryDim, NodalDim>:
192+
Allocator<f64, GeometryDim> + Allocator<f64, NodalDim>
193+
{
194+
}
195+
trait ReferenceFiniteElement {
196+
type NodalDim;
197+
}
198+
trait FiniteElement<GeometryDim>: ReferenceFiniteElement
199+
where
200+
DefaultAllocator: FiniteElementAllocator<GeometryDim, Self::NodalDim>,
201+
{
202+
fn map_reference_coords(&self) -> VectorN<f64, GeometryDim>;
203+
}
204+
205+
fn main() {}

0 commit comments

Comments
 (0)
This repository has been archived.