Skip to content
Closed
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
be76bdf
Remove ToPredicate impls that use Binder::dummy
jackh726 Sep 16, 2021
c065f57
Remove ToPolyTraitRef impl for TraitRef
jackh726 Sep 16, 2021
b73c8b8
Fix rustdoc
jackh726 Sep 16, 2021
553f649
Fix clippy
jackh726 Sep 16, 2021
9886c23
Remove Symbol::len
bjorn3 Sep 18, 2021
4e0ee2a
Avoid a couple of Symbol::as_str calls in cg_llvm
bjorn3 Sep 18, 2021
df72749
Make SymbolIndex private
bjorn3 Sep 18, 2021
0222556
Simplify scoped_thread
Mark-Simulacrum Sep 19, 2021
7a3e450
Add tests to verify the drop order of fields in fully captured upvars
wesleywiser Sep 23, 2021
ab8aef4
Drop fully captured upvars in the same order as the regular drop code
wesleywiser Sep 23, 2021
d63e0f0
Add time complexities to linked_list.rs
Takashiidobe Sep 23, 2021
b146525
remove trailing whitespace
Takashiidobe Sep 23, 2021
3893656
Fix tidy and respond to some feedback
wesleywiser Sep 24, 2021
9fa59e1
Enable "generate-link-to-definition" option on rust tools docs as well
GuillaumeGomez Sep 24, 2021
cb1c06f
Merge branch 'rust-lang:master' into master
Takashiidobe Sep 24, 2021
cebba31
unitalicize O(1) complexities
Takashiidobe Sep 24, 2021
ed3b751
Give better error for `macro_rules! name!`
aDotInTheVoid Sep 24, 2021
a307dcc
Add 1.56.0 release notes
Mark-Simulacrum Sep 12, 2021
790dc54
Rollup merge of #88893 - Mark-Simulacrum:relnotes, r=pietroalbini
Manishearth Sep 24, 2021
f24b753
Rollup merge of #89001 - jackh726:binder-cleanup, r=nikomatsakis
Manishearth Sep 24, 2021
6b12f3e
Rollup merge of #89072 - bjorn3:less_symbol_as_str, r=michaelwoerister
Manishearth Sep 24, 2021
be29631
Rollup merge of #89104 - Mark-Simulacrum:spawn-unchecked, r=nagisa,bj…
Manishearth Sep 24, 2021
6d29df8
Rollup merge of #89208 - wesleywiser:rfc_2229_droporder, r=nikomatsakis
Manishearth Sep 24, 2021
23c28e3
Rollup merge of #89210 - Takashiidobe:master, r=kennytm
Manishearth Sep 24, 2021
913b9df
Rollup merge of #89217 - GuillaumeGomez:generate-link-to-def-rust-too…
Manishearth Sep 24, 2021
3f43f22
Rollup merge of #89221 - aDotInTheVoid:macro-error-1, r=estebank
Manishearth Sep 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,188 @@
Rust 1.56.0 (2021-10-21)
========================

Language
--------

- [The 2021 Edition is now stable.][rust#88100]
See [the edition guide][rust-2021-edition-guide] for more details.
- [You can now specify explicit discriminant values on any Rust enum.][rust#86860]
- [The pattern in `binding @ pattern` can now also introduce new bindings.][rust#85305]
- [Union field access is permitted in `const fn`.][rust#85769]

[rust-2021-edition-guide]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/index.html

Compiler
--------

- [Upgrade to LLVM 13.][rust#87570]
- [Support memory, address, and thread sanitizers on aarch64-unknown-freebsd.][rust#88023]
- [Allow specifying an deployment target version for all iOS targets][rust#87699]
- [Warnings can be forced on with `--force-warn`.][rust#87472]
This feature is primarily intended for usage by `cargo fix`, rather than end users.
- [Promote `aarch64-apple-ios-sim` to Tier 2\*.][rust#87760]
- [Add `powerpc-unknown-freebsd` at Tier 3\*.][rust#87370]

\* Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.

Libraries
---------

- [Allow writing of incomplete UTF-8 sequences via stdout/stderr on Windows.][rust#83342]
The Windows console still requires valid Unicode, but this change allows
splitting a UTF-8 character across multiple write calls. This allows, for
instance, programs that just read and write data buffers (e.g. copying a file
to stdout) without regard for Unicode or character boundaries.
- [Prefer `AtomicU{64,128}` over Mutex for Instant backsliding protection.][rust#83093]
For this use case, atomics scale much better under contention.
- [Implement `Extend<(A, B)>` for `(Extend<A>, Extend<B>)`][rust#85835]
- [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744]
- [`impl From<[(K, V); N]>` for all collections.][rust#84111]
- [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363]
- [Treat invalid environment variable names as non-existent.][rust#86183]
Previously, the environment functions would panic if given a variable name
with an internal null character or equal sign (`=`). Now, these functions will
just treat such names as non-existent variables, since the OS cannot represent
the existence of a variable with such a name.

Stabilised APIs
---------------

- [`std::os::unix::fs::chroot`]
- [`Iterator::intersperse`]
- [`Iterator::intersperse_with`]
- [`UnsafeCell::raw_get`]
- [`BufWriter::into_parts`]
- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]
These APIs were previously stable in `std`, but are now also available in `core`.
- [`Vec::shrink_to`]
- [`String::shrink_to`]
- [`OsString::shrink_to`]
- [`PathBuf::shrink_to`]
- [`BinaryHeap::shrink_to`]
- [`VecDeque::shrink_to`]
- [`HashMap::shrink_to`]
- [`HashSet::shrink_to`]
- [`task::ready!`]

These APIs are now usable in const contexts:

- [`std::mem::transmute`]
- [`[T]::first`][`slice::first`]
- [`[T]::split_first`][`slice::split_first`]
- [`[T]::last`][`slice::last`]
- [`[T]::split_last`][`slice::split_last`]

Cargo
-----

- [Cargo supports specifying a minimum supported Rust version in Cargo.toml.][`rust-version`]
This has no effect at present on dependency version selection.
We encourage crates to specify their minimum supported Rust version, and we encourage CI systems
that support Rust code to include a crate's specified minimum version in the text matrix for that
crate by default.

Compatibility notes
-------------------

- [Update to new argument parsing rules on Windows.][rust#87580]
This adjusts Rust's standard library to match the behavior of the standard
libraries for C/C++. The rules have changed slightly over time, and this PR
brings us to the latest set of rules (changed in 2008).
- [Disallow the aapcs calling convention on aarch64][rust#88399]
This was already not supported by LLVM; this change surfaces this lack of
support with a better error message.
- [Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default][rust#87385]
- [Warn when an escaped newline skips multiple lines.][rust#87671]
- [Calls to `libc::getpid` / `std::process::id` from `Command::pre_exec`
may return different values on glibc <= 2.24.][rust#81825]
Rust now invokes the `clone3` system call directly, when available, to use new functionality
available via that system call. Older versions of glibc cache the result of `getpid`, and only
update that cache when calling glibc's clone/fork functions, so a direct system call bypasses
that cache update. glibc 2.25 and newer no longer cache `getpid` for exactly this reason.

Internal changes
----------------
These changes provide no direct user facing benefits, but represent significant
improvements to the internals and overall performance of rustc
and related tools.

- [LLVM is compiled with PGO in published x86_64-unknown-linux-gnu artifacts.][rust#88069]
This improves the performance of most Rust builds.
- [Unify representation of macros in internal data structures.][rust#88019]
This change fixes a host of bugs with the handling of macros by the compiler,
as well as rustdoc.

[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
[`Iterator::intersperse`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
[`Iterator::intersperse_with`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get
[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662
[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to
[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to
[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to
[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to
[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to
[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to
[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to
[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to
[`task::ready!`]: https://doc.rust-lang.org/stable/std/task/macro.ready.html
[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first
[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first
[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last
[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last
[`rust-version`]: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
[rust#87671]: https://github.com/rust-lang/rust/pull/87671
[rust#86183]: https://github.com/rust-lang/rust/pull/86183
[rust#87385]: https://github.com/rust-lang/rust/pull/87385
[rust#88100]: https://github.com/rust-lang/rust/pull/88100
[rust#86860]: https://github.com/rust-lang/rust/pull/86860
[rust#84039]: https://github.com/rust-lang/rust/pull/84039
[rust#86492]: https://github.com/rust-lang/rust/pull/86492
[rust#88363]: https://github.com/rust-lang/rust/pull/88363
[rust#85305]: https://github.com/rust-lang/rust/pull/85305
[rust#87832]: https://github.com/rust-lang/rust/pull/87832
[rust#88069]: https://github.com/rust-lang/rust/pull/88069
[rust#87472]: https://github.com/rust-lang/rust/pull/87472
[rust#87699]: https://github.com/rust-lang/rust/pull/87699
[rust#87570]: https://github.com/rust-lang/rust/pull/87570
[rust#88023]: https://github.com/rust-lang/rust/pull/88023
[rust#87760]: https://github.com/rust-lang/rust/pull/87760
[rust#87370]: https://github.com/rust-lang/rust/pull/87370
[rust#87580]: https://github.com/rust-lang/rust/pull/87580
[rust#83342]: https://github.com/rust-lang/rust/pull/83342
[rust#83093]: https://github.com/rust-lang/rust/pull/83093
[rust#88177]: https://github.com/rust-lang/rust/pull/88177
[rust#88548]: https://github.com/rust-lang/rust/pull/88548
[rust#88551]: https://github.com/rust-lang/rust/pull/88551
[rust#88299]: https://github.com/rust-lang/rust/pull/88299
[rust#88220]: https://github.com/rust-lang/rust/pull/88220
[rust#85835]: https://github.com/rust-lang/rust/pull/85835
[rust#86879]: https://github.com/rust-lang/rust/pull/86879
[rust#86744]: https://github.com/rust-lang/rust/pull/86744
[rust#84662]: https://github.com/rust-lang/rust/pull/84662
[rust#86593]: https://github.com/rust-lang/rust/pull/86593
[rust#81050]: https://github.com/rust-lang/rust/pull/81050
[rust#81363]: https://github.com/rust-lang/rust/pull/81363
[rust#84111]: https://github.com/rust-lang/rust/pull/84111
[rust#85769]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720
[rust#88490]: https://github.com/rust-lang/rust/pull/88490
[rust#88269]: https://github.com/rust-lang/rust/pull/88269
[rust#84176]: https://github.com/rust-lang/rust/pull/84176
[rust#88399]: https://github.com/rust-lang/rust/pull/88399
[rust#88227]: https://github.com/rust-lang/rust/pull/88227
[rust#88200]: https://github.com/rust-lang/rust/pull/88200
[rust#82776]: https://github.com/rust-lang/rust/pull/82776
[rust#88077]: https://github.com/rust-lang/rust/pull/88077
[rust#87728]: https://github.com/rust-lang/rust/pull/87728
[rust#87050]: https://github.com/rust-lang/rust/pull/87050
[rust#87619]: https://github.com/rust-lang/rust/pull/87619
[rust#81825]: https://github.com/rust-lang/rust/pull/81825#issuecomment-808406918
[rust#88019]: https://github.com/rust-lang/rust/pull/88019

Version 1.55.0 (2021-09-09)
============================

4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
@@ -89,10 +89,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
category: ConstraintCategory,
) {
self.prove_predicates(
Some(ty::PredicateKind::Trait(ty::TraitPredicate {
Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
})),
}))),
locations,
category,
);
10 changes: 7 additions & 3 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
@@ -1080,7 +1080,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}

self.prove_predicate(
ty::PredicateKind::WellFormed(inferred_ty.into()).to_predicate(self.tcx()),
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into()))
.to_predicate(self.tcx()),
Locations::All(span),
ConstraintCategory::TypeAnnotation,
);
@@ -1316,7 +1317,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
obligations.obligations.push(traits::Obligation::new(
ObligationCause::dummy(),
param_env,
ty::PredicateKind::WellFormed(revealed_ty.into()).to_predicate(infcx.tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(revealed_ty.into()))
.to_predicate(infcx.tcx),
));
obligations.add(
infcx
@@ -1599,7 +1601,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.check_call_dest(body, term, &sig, destination, term_location);

self.prove_predicates(
sig.inputs_and_output.iter().map(|ty| ty::PredicateKind::WellFormed(ty.into())),
sig.inputs_and_output
.iter()
.map(|ty| ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))),
term_location.to_locations(),
ConstraintCategory::Boring,
);
15 changes: 9 additions & 6 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
@@ -96,7 +96,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
let arg_tys = sig.inputs();
let ret_ty = sig.output();
let name = tcx.item_name(def_id);
let name_str = &*name.as_str();

let llret_ty = self.layout_of(ret_ty).llvm_type(self);
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
@@ -230,9 +229,14 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
&[args[0].immediate(), y],
)
}
sym::ctlz_nonzero | sym::cttz_nonzero => {
sym::ctlz_nonzero => {
let y = self.const_bool(true);
let llvm_name = &format!("llvm.{}.i{}", &name_str[..4], width);
let llvm_name = &format!("llvm.ctlz.i{}", width);
self.call_intrinsic(llvm_name, &[args[0].immediate(), y])
}
sym::cttz_nonzero => {
let y = self.const_bool(true);
let llvm_name = &format!("llvm.cttz.i{}", width);
self.call_intrinsic(llvm_name, &[args[0].immediate(), y])
}
sym::ctpop => self.call_intrinsic(
@@ -353,7 +357,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
return;
}

_ if name_str.starts_with("simd_") => {
_ if name.as_str().starts_with("simd_") => {
match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
Ok(llval) => llval,
Err(()) => return,
@@ -843,7 +847,6 @@ fn generic_simd_intrinsic(
let sig =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
let arg_tys = sig.inputs();
let name_str = &*name.as_str();

if name == sym::simd_select_bitmask {
let in_ty = arg_tys[0];
@@ -917,7 +920,7 @@ fn generic_simd_intrinsic(
));
}

if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
if let Some(stripped) = name.as_str().strip_prefix("simd_shuffle") {
// If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
// If there is no suffix, use the index array length.
let n: u64 = if stripped.is_empty() {
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
@@ -577,7 +577,7 @@ impl server::Literal for Rustc<'_> {
}

// Synthesize a new symbol that includes the minus sign.
let symbol = Symbol::intern(&s[..1 + lit.symbol.len()]);
let symbol = Symbol::intern(&s[..1 + lit.symbol.as_str().len()]);
lit = token::Lit::new(lit.kind, symbol, lit.suffix);
}

6 changes: 4 additions & 2 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
@@ -669,8 +669,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
self.obligations.push(Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
predicate: ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(sup, sub))
.to_predicate(self.infcx.tcx),
predicate: ty::Binder::dummy(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
sup, sub,
)))
.to_predicate(self.infcx.tcx),
recursion_depth: 0,
});
}
5 changes: 3 additions & 2 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
@@ -360,7 +360,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
ty::PredicateKind::WellFormed(b_ty.into()).to_predicate(self.infcx.tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into()))
.to_predicate(self.infcx.tcx),
));
}

@@ -463,7 +464,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
predicate.to_predicate(self.tcx()),
ty::Binder::dummy(predicate).to_predicate(self.tcx()),
));
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/sub.rs
Original file line number Diff line number Diff line change
@@ -97,11 +97,11 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
self.fields.obligations.push(Obligation::new(
self.fields.trace.cause.clone(),
self.fields.param_env,
ty::PredicateKind::Subtype(ty::SubtypePredicate {
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: self.a_is_expected,
a,
b,
})
}))
.to_predicate(self.tcx()),
));

2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/engine.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
cause,
recursion_depth: 0,
param_env,
predicate: trait_ref.without_const().to_predicate(infcx.tcx),
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx),
},
);
}
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
@@ -231,6 +231,7 @@ impl Elaborator<'tcx> {
None
}
})
.map(ty::Binder::dummy)
.map(|predicate_kind| predicate_kind.to_predicate(tcx))
.filter(|&predicate| visited.insert(predicate))
.map(|predicate| {
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(nll)]
#![feature(once_cell)]
#![recursion_limit = "256"]
24 changes: 5 additions & 19 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
@@ -115,25 +115,11 @@ fn get_stack_size() -> Option<usize> {
/// for `'static` bounds.
#[cfg(not(parallel_compiler))]
pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
struct Ptr(*mut ());
unsafe impl Send for Ptr {}
unsafe impl Sync for Ptr {}

let mut f = Some(f);
let run = Ptr(&mut f as *mut _ as *mut ());
let mut result = None;
let result_ptr = Ptr(&mut result as *mut _ as *mut ());

let thread = cfg.spawn(move || {
let _ = (&run, &result_ptr);
let run = unsafe { (*(run.0 as *mut Option<F>)).take().unwrap() };
let result = unsafe { &mut *(result_ptr.0 as *mut Option<R>) };
*result = Some(run());
});

match thread.unwrap().join() {
Ok(()) => result.unwrap(),
Err(p) => panic::resume_unwind(p),
// SAFETY: join() is called immediately, so any closure captures are still
// alive.
match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() {
Ok(v) => v,
Err(e) => panic::resume_unwind(e),
}
}

23 changes: 0 additions & 23 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -769,12 +769,6 @@ pub trait ToPolyTraitRef<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}

impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
ty::Binder::dummy(*self)
}
}

impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
@@ -792,23 +786,6 @@ impl ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
}
}

impl ToPredicate<'tcx> for PredicateKind<'tcx> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
tcx.mk_predicate(Binder::dummy(self))
}
}

impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateKind::Trait(ty::TraitPredicate {
trait_ref: self.value,
constness: self.constness,
})
.to_predicate(tcx)
}
}

impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value
7 changes: 5 additions & 2 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -844,8 +844,11 @@ impl<'tcx> TraitRef<'tcx> {

/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
/// are the parameters defined on trait.
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) }
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
ty::Binder::dummy(TraitRef {
def_id,
substs: InternalSubsts::identity_for_item(tcx, def_id),
})
}

#[inline]
14 changes: 14 additions & 0 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
@@ -1547,6 +1547,20 @@ impl<'a> Parser<'a> {
self.expect(&token::Not)?; // `!`

let ident = self.parse_ident()?;

if self.eat(&token::Not) {
// Handle macro_rules! foo!
let span = self.prev_token.span;
self.struct_span_err(span, "macro names aren't followed by a `!`")
.span_suggestion(
span,
"remove the `!`",
"".to_owned(),
Applicability::MachineApplicable,
)
.emit();
}

let body = self.parse_mac_args()?;
self.eat_semi_for_macro_if_needed(&body);
self.complain_if_pub_macro(vis, true);
6 changes: 1 addition & 5 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -1618,7 +1618,7 @@ impl fmt::Display for MacroRulesNormalizedIdent {
pub struct Symbol(SymbolIndex);

rustc_index::newtype_index! {
pub struct SymbolIndex { .. }
struct SymbolIndex { .. }
}

impl Symbol {
@@ -1644,10 +1644,6 @@ impl Symbol {
self.0.as_u32()
}

pub fn len(self) -> usize {
with_session_globals(|session_globals| session_globals.symbol_interner.get(self).len())
}

pub fn is_empty(self) -> bool {
self == kw::Empty
}
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/autoderef.rs
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
let obligation = traits::Obligation::new(
cause.clone(),
self.param_env,
trait_ref.without_const().to_predicate(tcx),
ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
);
if !self.infcx.predicate_may_hold(&obligation) {
debug!("overloaded_deref_ty: cannot match obligation");
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/infer.rs
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
cause: traits::ObligationCause::dummy(),
param_env,
recursion_depth: 0,
predicate: trait_ref.without_const().to_predicate(self.tcx),
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx),
};
self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
}
Original file line number Diff line number Diff line change
@@ -726,7 +726,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let new_obligation = Obligation::new(
ObligationCause::dummy(),
param_env,
new_trait_ref.without_const().to_predicate(self.tcx),
ty::Binder::dummy(new_trait_ref).without_const().to_predicate(self.tcx),
);

if self.predicate_must_hold_modulo_regions(&new_obligation) {
3 changes: 2 additions & 1 deletion compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
@@ -418,7 +418,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
| ty::PredicateKind::Coerce(_)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) => {
let pred = infcx.replace_bound_vars_with_placeholders(binder);
let pred =
ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
ProcessResult::Changed(mk_pending(vec![
obligation.with(pred.to_predicate(self.selcx.tcx())),
]))
3 changes: 2 additions & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -140,7 +140,8 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
infcx.tcx.def_path_str(def_id)
);

let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
let trait_ref =
ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) });
let obligation = Obligation {
param_env,
cause: ObligationCause::misc(span, hir::CRATE_HIR_ID),
25 changes: 13 additions & 12 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
@@ -250,7 +250,7 @@ fn predicates_reference_self(
trait_def_id: DefId,
supertraits_only: bool,
) -> SmallVec<[Span; 1]> {
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
let predicates = if supertraits_only {
tcx.super_predicates_of(trait_def_id)
} else {
@@ -554,11 +554,11 @@ fn object_ty_for_trait<'tcx>(

let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);

let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait(
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
));
let trait_predicate = trait_ref.map_bound(|trait_ref| {
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref))
});

let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref))
let mut associated_types = traits::supertraits(tcx, trait_ref)
.flat_map(|super_trait_ref| {
tcx.associated_items(super_trait_ref.def_id())
.in_definition_order()
@@ -671,10 +671,10 @@ fn receiver_is_dispatchable<'tcx>(
let param_env = tcx.param_env(method.def_id);

// Self: Unsize<U>
let unsize_predicate = ty::TraitRef {
let unsize_predicate = ty::Binder::dummy(ty::TraitRef {
def_id: unsize_did,
substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]),
}
})
.without_const()
.to_predicate(tcx);

@@ -689,7 +689,9 @@ fn receiver_is_dispatchable<'tcx>(
}
});

ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate(tcx)
ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs })
.without_const()
.to_predicate(tcx)
};

let caller_bounds: Vec<Predicate<'tcx>> = param_env
@@ -703,10 +705,10 @@ fn receiver_is_dispatchable<'tcx>(

// Receiver: DispatchFromDyn<Receiver[Self => U]>
let obligation = {
let predicate = ty::TraitRef {
let predicate = ty::Binder::dummy(ty::TraitRef {
def_id: dispatch_from_dyn_did,
substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
}
})
.without_const()
.to_predicate(tcx);

@@ -789,8 +791,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(

// Compute supertraits of current trait lazily.
if self.supertraits.is_none() {
let trait_ref =
ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id));
let trait_ref = ty::TraitRef::identity(self.tcx, self.trait_def_id);
self.supertraits = Some(
traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(),
);
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_span::symbol::sym;

use std::collections::BTreeMap;
@@ -1028,7 +1028,7 @@ fn normalize_to_error<'a, 'tcx>(
cause: ObligationCause<'tcx>,
depth: usize,
) -> NormalizedTy<'tcx> {
let trait_ref = projection_ty.trait_ref(selcx.tcx()).to_poly_trait_ref();
let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx()));
let trait_obligation = Obligation {
cause,
recursion_depth: depth,
@@ -1290,7 +1290,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(

// If we are resolving `<T as TraitRef<...>>::Item == Type`,
// start out by selecting the predicate `T as TraitRef<...>`:
let poly_trait_ref = obligation.predicate.trait_ref(selcx.tcx()).to_poly_trait_ref();
let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx()));
let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
let _ = selcx.infcx().commit_if_ok(|_| {
let impl_source = match selcx.select(&trait_obligation) {
Original file line number Diff line number Diff line change
@@ -141,6 +141,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let placeholder_trait_predicate =
self.infcx().replace_bound_vars_with_placeholders(trait_predicate);
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, substs) = match *placeholder_self_ty.kind() {
ty::Projection(proj) => (proj.item_def_id, proj.substs),
ty::Opaque(def_id, substs) => (def_id, substs),
@@ -164,7 +165,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligations.extend(self.infcx.commit_if_ok(|_| {
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(placeholder_trait_predicate.trait_ref.to_poly_trait_ref(), candidate.value)
.sup(placeholder_trait_predicate.to_poly_trait_ref(), candidate.value)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented)
})?);
@@ -646,7 +647,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligations.push(Obligation::new(
obligation.cause.clone(),
obligation.param_env,
ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
.to_predicate(self.tcx()),
));
}
@@ -898,10 +899,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);

// We can only make objects from sized types.
let tr = ty::TraitRef::new(
let tr = ty::Binder::dummy(ty::TraitRef::new(
tcx.require_lang_item(LangItem::Sized, None),
tcx.mk_substs_trait(source, &[]),
);
));
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));

// If the type is `Foo + 'a`, ensure that the type
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
@@ -248,7 +248,7 @@ pub fn predicate_for_trait_ref<'tcx>(
cause,
param_env,
recursion_depth,
predicate: trait_ref.without_const().to_predicate(tcx),
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
}
}

28 changes: 17 additions & 11 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
@@ -349,7 +349,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
new_cause,
depth,
param_env,
ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
)
}),
);
@@ -399,7 +399,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause.clone(),
depth,
param_env,
ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
)
}),
);
@@ -416,7 +416,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause,
self.recursion_depth,
self.param_env,
trait_ref.without_const().to_predicate(self.infcx.tcx),
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.infcx.tcx),
));
}
}
@@ -443,9 +443,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let obligations = self.nominal_obligations(uv.def.did, substs);
self.out.extend(obligations);

let predicate = ty::PredicateKind::ConstEvaluatable(
let predicate = ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
ty::Unevaluated::new(uv.def, substs),
)
))
.to_predicate(self.tcx());
let cause = self.cause(traits::MiscObligation);
self.out.push(traits::Obligation::with_depth(
@@ -469,8 +469,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause,
self.recursion_depth,
self.param_env,
ty::PredicateKind::WellFormed(resolved_constant.into())
.to_predicate(self.tcx()),
ty::Binder::dummy(ty::PredicateKind::WellFormed(
resolved_constant.into(),
))
.to_predicate(self.tcx()),
));
}
}
@@ -556,8 +558,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause,
depth,
param_env,
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(rty, r))
.to_predicate(self.tcx()),
ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
ty::OutlivesPredicate(rty, r),
))
.to_predicate(self.tcx()),
));
}
}
@@ -646,7 +650,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause.clone(),
depth,
param_env,
ty::PredicateKind::ObjectSafe(did).to_predicate(tcx),
ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did))
.to_predicate(tcx),
)
}));
}
@@ -673,7 +678,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause,
self.recursion_depth,
param_env,
ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()),
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))
.to_predicate(self.tcx()),
));
} else {
// Yes, resolved, proceed with the result.
5 changes: 3 additions & 2 deletions compiler/rustc_traits/src/type_op.rs
Original file line number Diff line number Diff line change
@@ -156,7 +156,8 @@ impl AscribeUserTypeCx<'me, 'tcx> {
self.relate(self_ty, Variance::Invariant, impl_self_ty)?;

self.prove_predicate(
ty::PredicateKind::WellFormed(impl_self_ty.into()).to_predicate(self.tcx()),
ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()))
.to_predicate(self.tcx()),
span,
);
}
@@ -173,7 +174,7 @@ impl AscribeUserTypeCx<'me, 'tcx> {
// type were ill-formed but did not appear in `ty`,
// which...could happen with normalization...
self.prove_predicate(
ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()),
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(self.tcx()),
span,
);
Ok(())
15 changes: 8 additions & 7 deletions compiler/rustc_typeck/src/check/_match.rs
Original file line number Diff line number Diff line change
@@ -524,13 +524,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for o in obligations {
match o.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(t) => {
let pred = ty::PredicateKind::Trait(ty::TraitPredicate {
trait_ref: ty::TraitRef {
def_id: t.def_id(),
substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
},
constness: t.constness,
});
let pred =
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
trait_ref: ty::TraitRef {
def_id: t.def_id(),
substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
},
constness: t.constness,
}));
let obl = Obligation::new(
o.cause.clone(),
self.param_env,
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
@@ -256,10 +256,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
obligations.push(Obligation::new(
self.cause.clone(),
self.param_env,
ty::PredicateKind::Coerce(ty::CoercePredicate {
ty::Binder::dummy(ty::PredicateKind::Coerce(ty::CoercePredicate {
a: source_ty,
b: target_ty,
})
}))
.to_predicate(self.tcx()),
));
}
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -585,7 +585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_predicate(traits::Obligation::new(
cause,
self.param_env,
ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx),
));
}

6 changes: 3 additions & 3 deletions compiler/rustc_typeck/src/check/method/mod.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ use rustc_infer::infer::{self, InferOk};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness};
use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable, WithConstness};
use rustc_span::symbol::Ident;
use rustc_span::Span;
use rustc_trait_selection::traits;
@@ -331,7 +331,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let trait_ref = ty::TraitRef::new(trait_def_id, substs);

// Construct an obligation
let poly_trait_ref = trait_ref.to_poly_trait_ref();
let poly_trait_ref = ty::Binder::dummy(trait_ref);
let obligation = traits::Obligation::misc(
span,
self.body_id,
@@ -413,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
obligations.push(traits::Obligation::new(
cause,
self.param_env,
ty::PredicateKind::WellFormed(method_ty.into()).to_predicate(tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())).to_predicate(tcx),
));

let callee = MethodCallee { def_id, substs: trait_ref.substs, sig: fn_sig };
11 changes: 5 additions & 6 deletions compiler/rustc_typeck/src/check/method/probe.rs
Original file line number Diff line number Diff line change
@@ -21,9 +21,7 @@ use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_middle::middle::stability;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{
self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
};
use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_session::lint;
use rustc_span::def_id::LocalDefId;
use rustc_span::lev_distance::{find_best_match_for_name, lev_distance};
@@ -967,7 +965,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {

if self.tcx.is_trait_alias(trait_def_id) {
// For trait aliases, assume all super-traits are relevant.
let bounds = iter::once(trait_ref.to_poly_trait_ref());
let bounds = iter::once(ty::Binder::dummy(trait_ref));
self.elaborate_bounds(bounds, |this, new_trait_ref, item| {
let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);

@@ -1372,7 +1370,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
trait_ref: ty::TraitRef<'tcx>,
) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
let cause = traits::ObligationCause::misc(self.span, self.body_id);
let predicate = trait_ref.to_poly_trait_ref().to_poly_trait_predicate();
let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate();
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
traits::SelectionContext::new(self).select(&obligation)
}
@@ -1470,7 +1468,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}
}
let predicate = trait_ref.without_const().to_predicate(self.tcx);
let predicate =
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
if !self.predicate_may_hold(&obligation) {
result = ProbeResult::NoMatch;
6 changes: 2 additions & 4 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
@@ -12,9 +12,7 @@ use rustc_hir::{ExprKind, Node, QPath};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty::fast_reject::simplify_type;
use rustc_middle::ty::print::with_crate_prefix;
use rustc_middle::ty::{
self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_span::lev_distance;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{source_map, FileName, Span};
@@ -53,7 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.into()],
);
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
let poly_trait_ref = trait_ref.to_poly_trait_ref();
let poly_trait_ref = ty::Binder::dummy(trait_ref);
let obligation = Obligation::misc(
span,
self.body_id,
73 changes: 72 additions & 1 deletion compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
@@ -602,7 +602,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

debug!("For closure={:?}, min_captures={:#?}", closure_def_id, root_var_min_capture_list);
debug!(
"For closure={:?}, min_captures before sorting={:?}",
closure_def_id, root_var_min_capture_list
);

// Now that we have the minimized list of captures, sort the captures by field id.
// This causes the closure to capture the upvars in the same order as the fields are
// declared which is also the drop order. Thus, in situations where we capture all the
// fields of some type, the obserable drop order will remain the same as it previously
// was even though we're dropping each capture individually.
// See https://github.com/rust-lang/project-rfc-2229/issues/42 and
// `src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs`.
for (_, captures) in &mut root_var_min_capture_list {
captures.sort_by(|capture1, capture2| {
for (p1, p2) in capture1.place.projections.iter().zip(&capture2.place.projections) {
// We do not need to look at the `Projection.ty` fields here because at each
// step of the iteration, the projections will either be the same and therefore
// the types must be as well or the current projection will be different and
// we will return the result of comparing the field indexes.
match (p1.kind, p2.kind) {
// Paths are the same, continue to next loop.
(ProjectionKind::Deref, ProjectionKind::Deref) => {}
(ProjectionKind::Field(i1, _), ProjectionKind::Field(i2, _))
if i1 == i2 => {}

// Fields are different, compare them.
(ProjectionKind::Field(i1, _), ProjectionKind::Field(i2, _)) => {
return i1.cmp(&i2);
}

// We should have either a pair of `Deref`s or a pair of `Field`s.
// Anything else is a bug.
(
l @ (ProjectionKind::Deref | ProjectionKind::Field(..)),
r @ (ProjectionKind::Deref | ProjectionKind::Field(..)),
) => bug!(
"ProjectionKinds Deref and Field were mismatched: ({:?}, {:?})",
l,
r
),
(
l
@
(ProjectionKind::Index
| ProjectionKind::Subslice
| ProjectionKind::Deref
| ProjectionKind::Field(..)),
r
@
(ProjectionKind::Index
| ProjectionKind::Subslice
| ProjectionKind::Deref
| ProjectionKind::Field(..)),
) => bug!(
"ProjectionKinds Index or Subslice were unexpected: ({:?}, {:?})",
l,
r
),
}
}

unreachable!(
"we captured two identical projections: capture1 = {:?}, capture2 = {:?}",
capture1, capture2
);
});
}

debug!(
"For closure={:?}, min_captures after sorting={:#?}",
closure_def_id, root_var_min_capture_list
);
typeck_results.closure_min_captures.insert(closure_def_id, root_var_min_capture_list);
}

8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -540,10 +540,10 @@ fn check_type_defn<'tcx, F>(
fcx.register_predicate(traits::Obligation::new(
cause,
fcx.param_env,
ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
discr_substs,
))
)))
.to_predicate(tcx),
));
}
@@ -1151,10 +1151,10 @@ fn receiver_is_implemented(
cause: ObligationCause<'tcx>,
receiver_ty: Ty<'tcx>,
) -> bool {
let trait_ref = ty::TraitRef {
let trait_ref = ty::Binder::dummy(ty::TraitRef {
def_id: receiver_trait_def_id,
substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
};
});

let obligation = traits::Obligation::new(
cause,
20 changes: 11 additions & 9 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::Discr;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, Ty, TyCtxt};
use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
use rustc_session::lint;
use rustc_session::parse::feature_err;
@@ -2042,7 +2042,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
match item.kind {
ItemKind::Impl(ref impl_) => {
if impl_.defaultness.is_default() {
is_default_impl_trait = tcx.impl_trait_ref(def_id);
is_default_impl_trait = tcx
.impl_trait_ref(def_id)
.map(|trait_ref| ty::Binder::dummy(trait_ref));
}
&impl_.generics
}
@@ -2122,10 +2124,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
// (see below). Recall that a default impl is not itself an impl, but rather a
// set of defaults that can be incorporated into another impl.
if let Some(trait_ref) = is_default_impl_trait {
predicates.insert((
trait_ref.to_poly_trait_ref().without_const().to_predicate(tcx),
tcx.def_span(def_id),
));
predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
}

// Collect the region predicates that were declared inline as
@@ -2238,8 +2237,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
}
_ => bug!(),
};
let pred = ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
.to_predicate(icx.tcx);
let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
ty::OutlivesPredicate(r1, r2),
))
.to_predicate(icx.tcx);

(pred, span)
}))
@@ -2304,7 +2305,8 @@ fn const_evaluatable_predicates_of<'tcx>(
assert_eq!(uv.promoted, None);
let span = self.tcx.hir().span(c.hir_id);
self.preds.insert((
ty::PredicateKind::ConstEvaluatable(uv.shrink()).to_predicate(self.tcx),
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
.to_predicate(self.tcx),
span,
));
}
3 changes: 2 additions & 1 deletion compiler/rustc_typeck/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
@@ -83,7 +83,8 @@ fn diagnostic_hir_wf_check<'tcx>(
traits::Obligation::new(
cause,
self.param_env,
ty::PredicateKind::WellFormed(tcx_ty.into()).to_predicate(self.tcx),
ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into()))
.to_predicate(self.tcx),
),
);

10 changes: 6 additions & 4 deletions compiler/rustc_typeck/src/outlives/mod.rs
Original file line number Diff line number Diff line change
@@ -104,13 +104,15 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|(ty::OutlivesPredicate(kind1, region2), &span)| {
match kind1.unpack() {
GenericArgKind::Type(ty1) => Some((
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty1, region2))
.to_predicate(tcx),
ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
ty::OutlivesPredicate(ty1, region2),
))
.to_predicate(tcx),
span,
)),
GenericArgKind::Lifetime(region1) => Some((
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
region1, region2,
ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
ty::OutlivesPredicate(region1, region2),
))
.to_predicate(tcx),
span,
10 changes: 10 additions & 0 deletions library/alloc/src/collections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -631,6 +631,8 @@ impl<T> LinkedList<T> {
/// Returns `true` if the `LinkedList` contains an element equal to the
/// given value.
///
/// This operation should compute in *O*(*n*) time.
///
/// # Examples
///
/// ```
@@ -656,6 +658,8 @@ impl<T> LinkedList<T> {
/// Provides a reference to the front element, or `None` if the list is
/// empty.
///
/// This operation should compute in *O*(1) time.
///
/// # Examples
///
/// ```
@@ -676,6 +680,8 @@ impl<T> LinkedList<T> {
/// Provides a mutable reference to the front element, or `None` if the list
/// is empty.
///
/// This operation should compute in *O*(1) time.
///
/// # Examples
///
/// ```
@@ -702,6 +708,8 @@ impl<T> LinkedList<T> {
/// Provides a reference to the back element, or `None` if the list is
/// empty.
///
/// This operation should compute in *O*(1) time.
///
/// # Examples
///
/// ```
@@ -722,6 +730,8 @@ impl<T> LinkedList<T> {
/// Provides a mutable reference to the back element, or `None` if the list
/// is empty.
///
/// This operation should compute in *O*(1) time.
///
/// # Examples
///
/// ```
1 change: 1 addition & 0 deletions src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
@@ -743,6 +743,7 @@ macro_rules! tool_doc {
cargo.rustdocflag("--document-private-items");
cargo.rustdocflag("--enable-index-page");
cargo.rustdocflag("--show-type-layout");
cargo.rustdocflag("--generate-link-to-definition");
cargo.rustdocflag("-Zunstable-options");
builder.run(&mut cargo.into());
}
6 changes: 5 additions & 1 deletion src/librustdoc/clean/blanket_impl.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.instantiate(self.cx.tcx, impl_substs)
.predicates
.into_iter()
.chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
.chain(Some(
ty::Binder::dummy(trait_ref)
.without_const()
.to_predicate(infcx.tcx),
));
for predicate in predicates {
debug!("testing predicate {:?}", predicate);
let obligation = traits::Obligation::new(
2 changes: 1 addition & 1 deletion src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
let def_id = cx.tcx.require_lang_item(lang_item, Some(span));

let trait_ref = ty::TraitRef::identity(cx.tcx, def_id);
let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder();

let generic_args = generic_args.clean(cx);
let bindings = match generic_args {
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// edition:2021

// Tests that in cases where we individually capture all the fields of a type,
// we still drop them in the order they would have been dropped in the 2018 edition.

#![feature(rustc_attrs)]

#[derive(Debug)]
struct HasDrop;
impl Drop for HasDrop {
fn drop(&mut self) {
println!("dropped");
}
}

fn test_one() {
let a = (HasDrop, HasDrop);
let b = (HasDrop, HasDrop);

let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ ERROR: First Pass analysis includes:
//~| ERROR: Min Capture analysis includes:
println!("{:?}", a.0);
//~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow
println!("{:?}", a.1);
//~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow
//~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow

println!("{:?}", b.0);
//~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow
println!("{:?}", b.1);
//~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow
//~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow
};
}

fn test_two() {
let a = (HasDrop, HasDrop);
let b = (HasDrop, HasDrop);

let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ ERROR: First Pass analysis includes:
//~| ERROR: Min Capture analysis includes:
println!("{:?}", a.1);
//~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow
//~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow
println!("{:?}", a.0);
//~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow

println!("{:?}", b.1);
//~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow
//~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow
println!("{:?}", b.0);
//~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow
};
}

fn test_three() {
let a = (HasDrop, HasDrop);
let b = (HasDrop, HasDrop);

let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ ERROR: First Pass analysis includes:
//~| ERROR: Min Capture analysis includes:
println!("{:?}", b.1);
//~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow
//~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow
println!("{:?}", a.1);
//~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow
//~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow
println!("{:?}", a.0);
//~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow

println!("{:?}", b.0);
//~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow
};
}

fn main() {
test_one();
test_two();
test_three();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
error[E0658]: attributes on expressions are experimental
--> $DIR/preserve_field_drop_order.rs:20:13
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable

error[E0658]: attributes on expressions are experimental
--> $DIR/preserve_field_drop_order.rs:46:13
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable

error[E0658]: attributes on expressions are experimental
--> $DIR/preserve_field_drop_order.rs:72:13
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable

error: First Pass analysis includes:
--> $DIR/preserve_field_drop_order.rs:23:5
|
LL | / || {
LL | |
LL | |
LL | | println!("{:?}", a.0);
... |
LL | |
LL | | };
| |_____^
|
note: Capturing a[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:26:26
|
LL | println!("{:?}", a.0);
| ^^^
note: Capturing a[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:29:26
|
LL | println!("{:?}", a.1);
| ^^^
note: Capturing b[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:33:26
|
LL | println!("{:?}", b.0);
| ^^^
note: Capturing b[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:36:26
|
LL | println!("{:?}", b.1);
| ^^^

error: Min Capture analysis includes:
--> $DIR/preserve_field_drop_order.rs:23:5
|
LL | / || {
LL | |
LL | |
LL | | println!("{:?}", a.0);
... |
LL | |
LL | | };
| |_____^
|
note: Min Capture a[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:26:26
|
LL | println!("{:?}", a.0);
| ^^^
note: Min Capture a[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:29:26
|
LL | println!("{:?}", a.1);
| ^^^
note: Min Capture b[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:33:26
|
LL | println!("{:?}", b.0);
| ^^^
note: Min Capture b[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:36:26
|
LL | println!("{:?}", b.1);
| ^^^

error: First Pass analysis includes:
--> $DIR/preserve_field_drop_order.rs:49:5
|
LL | / || {
LL | |
LL | |
LL | | println!("{:?}", a.1);
... |
LL | |
LL | | };
| |_____^
|
note: Capturing a[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:52:26
|
LL | println!("{:?}", a.1);
| ^^^
note: Capturing a[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:55:26
|
LL | println!("{:?}", a.0);
| ^^^
note: Capturing b[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:59:26
|
LL | println!("{:?}", b.1);
| ^^^
note: Capturing b[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:62:26
|
LL | println!("{:?}", b.0);
| ^^^

error: Min Capture analysis includes:
--> $DIR/preserve_field_drop_order.rs:49:5
|
LL | / || {
LL | |
LL | |
LL | | println!("{:?}", a.1);
... |
LL | |
LL | | };
| |_____^
|
note: Min Capture a[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:55:26
|
LL | println!("{:?}", a.0);
| ^^^
note: Min Capture a[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:52:26
|
LL | println!("{:?}", a.1);
| ^^^
note: Min Capture b[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:62:26
|
LL | println!("{:?}", b.0);
| ^^^
note: Min Capture b[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:59:26
|
LL | println!("{:?}", b.1);
| ^^^

error: First Pass analysis includes:
--> $DIR/preserve_field_drop_order.rs:75:5
|
LL | / || {
LL | |
LL | |
LL | | println!("{:?}", b.1);
... |
LL | |
LL | | };
| |_____^
|
note: Capturing b[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:78:26
|
LL | println!("{:?}", b.1);
| ^^^
note: Capturing a[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:81:26
|
LL | println!("{:?}", a.1);
| ^^^
note: Capturing a[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:84:26
|
LL | println!("{:?}", a.0);
| ^^^
note: Capturing b[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:88:26
|
LL | println!("{:?}", b.0);
| ^^^

error: Min Capture analysis includes:
--> $DIR/preserve_field_drop_order.rs:75:5
|
LL | / || {
LL | |
LL | |
LL | | println!("{:?}", b.1);
... |
LL | |
LL | | };
| |_____^
|
note: Min Capture b[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:88:26
|
LL | println!("{:?}", b.0);
| ^^^
note: Min Capture b[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:78:26
|
LL | println!("{:?}", b.1);
| ^^^
note: Min Capture a[(0, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:84:26
|
LL | println!("{:?}", a.0);
| ^^^
note: Min Capture a[(1, 0)] -> ImmBorrow
--> $DIR/preserve_field_drop_order.rs:81:26
|
LL | println!("{:?}", a.1);
| ^^^

error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0658`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// run-pass
// check-run-results
// revisions: twenty_eighteen twenty_twentyone
// [twenty_eighteen]compile-flags: --edition 2018
// [twenty_twentyone]compile-flags: --edition 2021

#[derive(Debug)]
struct Dropable(String);

impl Drop for Dropable {
fn drop(&mut self) {
println!("Dropping {}", self.0)
}
}

#[derive(Debug)]
struct A {
x: Dropable,
y: Dropable,
}

fn main() {
let a = A { x: Dropable(format!("x")), y: Dropable(format!("y")) };

let c = move || println!("{:?} {:?}", a.y, a.x);

c();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Dropable("y") Dropable("x")
Dropping x
Dropping y
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Dropable("y") Dropable("x")
Dropping x
Dropping y
8 changes: 8 additions & 0 deletions src/test/ui/macros/bang-after-name.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-rustfix
#[allow(unused_macros)]

macro_rules! foo { //~ ERROR macro names aren't followed by a `!`
() => {};
}

fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/macros/bang-after-name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-rustfix
#[allow(unused_macros)]

macro_rules! foo! { //~ ERROR macro names aren't followed by a `!`
() => {};
}

fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/macros/bang-after-name.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: macro names aren't followed by a `!`
--> $DIR/bang-after-name.rs:4:17
|
LL | macro_rules! foo! {
| ^ help: remove the `!`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/escape.rs
Original file line number Diff line number Diff line change
@@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
// be sure we have `self` parameter in this function
if let AssocItemKind::Fn { has_self: true } = trait_item.kind {
trait_self_ty =
Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty());
Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty().skip_binder());
}
}
}
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/methods/mod.rs
Original file line number Diff line number Diff line change
@@ -2061,7 +2061,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
then {
let first_arg_span = first_arg_ty.span;
let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty();
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
wrong_self_convention::check(
cx,
&item.ident.name.as_str(),
@@ -2078,7 +2078,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if item.ident.name == sym::new;
if let TraitItemKind::Fn(_, _) = item.kind;
let ret_ty = return_ty(cx, item.hir_id());
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty();
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
if !contains_ty(cx.tcx, ret_ty, self_ty);

then {