authorbors <bors@rust-lang.org> 2020-01-20 23:35:50 UTC
committerbors <bors@rust-lang.org> 2020-01-20 23:35:50 UTC
log06b945049b6e6795bcfb9fb8007a46c44a93c0aa
treee5ac89eda26500d49ee52698ed3d9b033cd2e05a
parentb5a3341f1b8b475990e9d1b071b88d3c280936b4
parentf6406f7f680d4f77144d22e1f74064e878213f5c

Auto merge of #68405 - JohnTitor:rollup-kj0x4za, r=JohnTitor

Rollup of 8 pull requests Successful merges: - #67734 (Remove appendix from Apache license) - #67795 (Cleanup formatting code) - #68290 (Fix some tests failing in `--pass check` mode) - #68297 ( Filter and test predicates using `normalize_and_test_predicates` for const-prop) - #68302 (Fix #[track_caller] and function pointers) - #68339 (Add `riscv64gc-unknown-linux-gnu` into target list in build-manifest) - #68381 (Added minor clarification to specification of GlobalAlloc::realloc.) - #68397 (rustdoc: Correct order of `async` and `unsafe` in `async unsafe fn`s) Failed merges: r? @ghost

27 files changed, 266 insertions(+), 242 deletions(-)

LICENSE-APACHE-25
......@@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
174174 of your accepting any such warranty or additional liability.
175175
176176END OF TERMS AND CONDITIONS
177
178APPENDIX: How to apply the Apache License to your work.
179
180 To apply the Apache License to your work, attach the following
181 boilerplate notice, with the fields enclosed by brackets "[]"
182 replaced with your own identifying information. (Don't include
183 the brackets!) The text should be enclosed in the appropriate
184 comment syntax for the file format. We also recommend that a
185 file or class name and description of purpose be included on the
186 same "printed page" as the copyright notice for easier
187 identification within third-party archives.
188
189Copyright [yyyy] [name of copyright owner]
190
191Licensed under the Apache License, Version 2.0 (the "License");
192you may not use this file except in compliance with the License.
193You may obtain a copy of the License at
194
195 http://www.apache.org/licenses/LICENSE-2.0
196
197Unless required by applicable law or agreed to in writing, software
198distributed under the License is distributed on an "AS IS" BASIS,
199WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200See the License for the specific language governing permissions and
201limitations under the License.
src/libcore/alloc.rs+2-1
......@@ -525,7 +525,8 @@ pub unsafe trait GlobalAlloc {
525525 /// The memory may or may not have been deallocated,
526526 /// and should be considered unusable (unless of course it was
527527 /// transferred back to the caller again via the return value of
528 /// this method).
528 /// this method). The new memory block is allocated with `layout`, but
529 /// with the `size` updated to `new_size`.
529530 ///
530531 /// If this method returns null, then ownership of the memory
531532 /// block has not been transferred to this allocator, and the
src/libcore/fmt/mod.rs+34-41
......@@ -10,7 +10,6 @@ use crate::mem;
1010use crate::num::flt2dec;
1111use crate::ops::Deref;
1212use crate::result;
13use crate::slice;
1413use crate::str;
1514
1615mod builders;
......@@ -234,8 +233,6 @@ pub struct Formatter<'a> {
234233 precision: Option<usize>,
235234
236235 buf: &'a mut (dyn Write + 'a),
237 curarg: slice::Iter<'a, ArgumentV1<'a>>,
238 args: &'a [ArgumentV1<'a>],
239236}
240237
241238// NB. Argument is essentially an optimized partially applied formatting function,
......@@ -1043,8 +1040,6 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
10431040 buf: output,
10441041 align: rt::v1::Alignment::Unknown,
10451042 fill: ' ',
1046 args: args.args,
1047 curarg: args.args.iter(),
10481043 };
10491044
10501045 let mut idx = 0;
......@@ -1063,7 +1058,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
10631058 // a string piece.
10641059 for (arg, piece) in fmt.iter().zip(args.pieces.iter()) {
10651060 formatter.buf.write_str(*piece)?;
1066 formatter.run(arg)?;
1061 run(&mut formatter, arg, &args.args)?;
10671062 idx += 1;
10681063 }
10691064 }
......@@ -1077,6 +1072,39 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
10771072 Ok(())
10781073}
10791074
1075fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result {
1076 fmt.fill = arg.format.fill;
1077 fmt.align = arg.format.align;
1078 fmt.flags = arg.format.flags;
1079 fmt.width = getcount(args, &arg.format.width);
1080 fmt.precision = getcount(args, &arg.format.precision);
1081
1082 // Extract the correct argument
1083 let value = {
1084 #[cfg(bootstrap)]
1085 {
1086 match arg.position {
1087 rt::v1::Position::At(i) => args[i],
1088 }
1089 }
1090 #[cfg(not(bootstrap))]
1091 {
1092 args[arg.position]
1093 }
1094 };
1095
1096 // Then actually do some printing
1097 (value.formatter)(value.value, fmt)
1098}
1099
1100fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> {
1101 match *cnt {
1102 rt::v1::Count::Is(n) => Some(n),
1103 rt::v1::Count::Implied => None,
1104 rt::v1::Count::Param(i) => args[i].as_usize(),
1105 }
1106}
1107
10801108/// Padding after the end of something. Returned by `Formatter::padding`.
10811109#[must_use = "don't forget to write the post padding"]
10821110struct PostPadding {
......@@ -1114,41 +1142,6 @@ impl<'a> Formatter<'a> {
11141142 align: self.align,
11151143 width: self.width,
11161144 precision: self.precision,
1117
1118 // These only exist in the struct for the `run` method,
1119 // which won’t be used together with this method.
1120 curarg: self.curarg.clone(),
1121 args: self.args,
1122 }
1123 }
1124
1125 // First up is the collection of functions used to execute a format string
1126 // at runtime. This consumes all of the compile-time statics generated by
1127 // the format! syntax extension.
1128 fn run(&mut self, arg: &rt::v1::Argument) -> Result {
1129 // Fill in the format parameters into the formatter
1130 self.fill = arg.format.fill;
1131 self.align = arg.format.align;
1132 self.flags = arg.format.flags;
1133 self.width = self.getcount(&arg.format.width);
1134 self.precision = self.getcount(&arg.format.precision);
1135
1136 // Extract the correct argument
1137 let value = match arg.position {
1138 rt::v1::Position::Next => *self.curarg.next().unwrap(),
1139 rt::v1::Position::At(i) => self.args[i],
1140 };
1141
1142 // Then actually do some printing
1143 (value.formatter)(value.value, self)
1144 }
1145
1146 fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<usize> {
1147 match *cnt {
1148 rt::v1::Count::Is(n) => Some(n),
1149 rt::v1::Count::Implied => None,
1150 rt::v1::Count::Param(i) => self.args[i].as_usize(),
1151 rt::v1::Count::NextParam => self.curarg.next()?.as_usize(),
11521145 }
11531146 }
11541147
src/libcore/fmt/rt/v1.rs+4-2
......@@ -7,7 +7,10 @@
77
88#[derive(Copy, Clone)]
99pub struct Argument {
10 #[cfg(bootstrap)]
1011 pub position: Position,
12 #[cfg(not(bootstrap))]
13 pub position: usize,
1114 pub format: FormatSpec,
1215}
1316
......@@ -37,12 +40,11 @@ pub enum Alignment {
3740pub enum Count {
3841 Is(usize),
3942 Param(usize),
40 NextParam,
4143 Implied,
4244}
4345
46#[cfg(bootstrap)]
4447#[derive(Copy, Clone)]
4548pub enum Position {
46 Next,
4749 At(usize),
4850}
src/librustc/mir/mono.rs+1-4
......@@ -1,7 +1,6 @@
11use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId};
22use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
33use crate::session::config::OptLevel;
4use crate::traits::TraitQueryMode;
54use crate::ty::print::obsolete::DefPathBasedNames;
65use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
76use rustc_data_structures::base_n;
......@@ -168,9 +167,7 @@ impl<'tcx> MonoItem<'tcx> {
168167 MonoItem::GlobalAsm(..) => return true,
169168 };
170169
171 // We shouldn't encounter any overflow here, so we use TraitQueryMode::Standard\
172 // to report an error if overflow somehow occurs.
173 tcx.substitute_normalize_and_test_predicates((def_id, &substs, TraitQueryMode::Standard))
170 tcx.substitute_normalize_and_test_predicates((def_id, &substs))
174171 }
175172
176173 pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
src/librustc/query/mod.rs+3-3
......@@ -1156,11 +1156,11 @@ rustc_queries! {
11561156 desc { "normalizing `{:?}`", goal }
11571157 }
11581158
1159 query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>, traits::TraitQueryMode)) -> bool {
1159 query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
11601160 no_force
11611161 desc { |tcx|
1162 "testing substituted normalized predicates in mode {:?}:`{}`",
1163 key.2, tcx.def_path_str(key.0)
1162 "testing substituted normalized predicates:`{}`",
1163 tcx.def_path_str(key.0)
11641164 }
11651165 }
11661166
src/librustc/traits/fulfill.rs+2-22
......@@ -16,7 +16,6 @@ use super::CodeSelectionError;
1616use super::{ConstEvalFailure, Unimplemented};
1717use super::{FulfillmentError, FulfillmentErrorCode};
1818use super::{ObligationCause, PredicateObligation};
19use crate::traits::TraitQueryMode;
2019
2120impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
2221 type Predicate = ty::Predicate<'tcx>;
......@@ -63,9 +62,6 @@ pub struct FulfillmentContext<'tcx> {
6362 // a snapshot (they don't *straddle* a snapshot, so there
6463 // is no trouble there).
6564 usable_in_snapshot: bool,
66
67 // The `TraitQueryMode` used when constructing a `SelectionContext`
68 query_mode: TraitQueryMode,
6965}
7066
7167#[derive(Clone, Debug)]
......@@ -79,26 +75,12 @@ pub struct PendingPredicateObligation<'tcx> {
7975static_assert_size!(PendingPredicateObligation<'_>, 136);
8076
8177impl<'a, 'tcx> FulfillmentContext<'tcx> {
82 /// Creates a new fulfillment context with `TraitQueryMode::Standard`
83 /// You almost always want to use this instead of `with_query_mode`
78 /// Creates a new fulfillment context.
8479 pub fn new() -> FulfillmentContext<'tcx> {
8580 FulfillmentContext {
8681 predicates: ObligationForest::new(),
8782 register_region_obligations: true,
8883 usable_in_snapshot: false,
89 query_mode: TraitQueryMode::Standard,
90 }
91 }
92
93 /// Creates a new fulfillment context with the specified query mode.
94 /// This should only be used when you want to ignore overflow,
95 /// rather than reporting it as an error.
96 pub fn with_query_mode(query_mode: TraitQueryMode) -> FulfillmentContext<'tcx> {
97 FulfillmentContext {
98 predicates: ObligationForest::new(),
99 register_region_obligations: true,
100 usable_in_snapshot: false,
101 query_mode,
10284 }
10385 }
10486
......@@ -107,7 +89,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
10789 predicates: ObligationForest::new(),
10890 register_region_obligations: true,
10991 usable_in_snapshot: true,
110 query_mode: TraitQueryMode::Standard,
11192 }
11293 }
11394
......@@ -116,7 +97,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
11697 predicates: ObligationForest::new(),
11798 register_region_obligations: false,
11899 usable_in_snapshot: false,
119 query_mode: TraitQueryMode::Standard,
120100 }
121101 }
122102
......@@ -237,7 +217,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
237217 &mut self,
238218 infcx: &InferCtxt<'_, 'tcx>,
239219 ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
240 let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode);
220 let mut selcx = SelectionContext::new(infcx);
241221 self.select(&mut selcx)
242222 }
243223
src/librustc/traits/mod.rs+8-12
......@@ -95,7 +95,7 @@ pub enum IntercrateMode {
9595}
9696
9797/// The mode that trait queries run in.
98#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)]
98#[derive(Copy, Clone, PartialEq, Eq, Debug)]
9999pub enum TraitQueryMode {
100100 // Standard/un-canonicalized queries get accurate
101101 // spans etc. passed in and hence can do reasonable
......@@ -1014,17 +1014,16 @@ where
10141014/// environment. If this returns false, then either normalize
10151015/// encountered an error or one of the predicates did not hold. Used
10161016/// when creating vtables to check for unsatisfiable methods.
1017fn normalize_and_test_predicates<'tcx>(
1017pub fn normalize_and_test_predicates<'tcx>(
10181018 tcx: TyCtxt<'tcx>,
10191019 predicates: Vec<ty::Predicate<'tcx>>,
1020 mode: TraitQueryMode,
10211020) -> bool {
1022 debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode);
1021 debug!("normalize_and_test_predicates(predicates={:?})", predicates);
10231022
10241023 let result = tcx.infer_ctxt().enter(|infcx| {
10251024 let param_env = ty::ParamEnv::reveal_all();
1026 let mut selcx = SelectionContext::with_query_mode(&infcx, mode);
1027 let mut fulfill_cx = FulfillmentContext::with_query_mode(mode);
1025 let mut selcx = SelectionContext::new(&infcx);
1026 let mut fulfill_cx = FulfillmentContext::new();
10281027 let cause = ObligationCause::dummy();
10291028 let Normalized { value: predicates, obligations } =
10301029 normalize(&mut selcx, param_env, cause.clone(), &predicates);
......@@ -1044,12 +1043,12 @@ fn normalize_and_test_predicates<'tcx>(
10441043
10451044fn substitute_normalize_and_test_predicates<'tcx>(
10461045 tcx: TyCtxt<'tcx>,
1047 key: (DefId, SubstsRef<'tcx>, TraitQueryMode),
1046 key: (DefId, SubstsRef<'tcx>),
10481047) -> bool {
10491048 debug!("substitute_normalize_and_test_predicates(key={:?})", key);
10501049
10511050 let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
1052 let result = normalize_and_test_predicates(tcx, predicates, key.2);
1051 let result = normalize_and_test_predicates(tcx, predicates);
10531052
10541053 debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result);
10551054 result
......@@ -1102,10 +1101,7 @@ fn vtable_methods<'tcx>(
11021101 // Note that this method could then never be called, so we
11031102 // do not want to try and codegen it, in that case (see #23435).
11041103 let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
1105 // We don't expect overflow here, so report an error if it somehow ends
1106 // up happening.
1107 if !normalize_and_test_predicates(tcx, predicates.predicates, TraitQueryMode::Standard)
1108 {
1104 if !normalize_and_test_predicates(tcx, predicates.predicates) {
11091105 debug!("vtable_methods: predicates do not hold");
11101106 return None;
11111107 }
src/librustc/ty/instance.rs+6-1
......@@ -141,7 +141,12 @@ impl<'tcx> InstanceDef<'tcx> {
141141 }
142142
143143 pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
144 tcx.codegen_fn_attrs(self.def_id()).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
144 match *self {
145 InstanceDef::Item(def_id) => {
146 tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
147 }
148 _ => false,
149 }
145150 }
146151}
147152
src/librustc/ty/query/keys.rs-9
......@@ -125,15 +125,6 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
125125 }
126126}
127127
128impl<'tcx> Key for (DefId, SubstsRef<'tcx>, traits::TraitQueryMode) {
129 fn query_crate(&self) -> CrateNum {
130 self.0.krate
131 }
132 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
133 self.0.default_span(tcx)
134 }
135}
136
137128impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
138129 fn query_crate(&self) -> CrateNum {
139130 self.1.def_id().krate
src/librustc_builtin_macros/format.rs+1-12
......@@ -590,17 +590,6 @@ impl<'a, 'b> Context<'a, 'b> {
590590 parse::NextArgument(ref arg) => {
591591 // Build the position
592592 let pos = {
593 let pos = |c, arg| {
594 let mut path = Context::rtpath(self.ecx, "Position");
595 path.push(self.ecx.ident_of(c, sp));
596 match arg {
597 Some(i) => {
598 let arg = self.ecx.expr_usize(sp, i);
599 self.ecx.expr_call_global(sp, path, vec![arg])
600 }
601 None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
602 }
603 };
604593 match arg.position {
605594 parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => {
606595 // Map to index in final generated argument array
......@@ -615,7 +604,7 @@ impl<'a, 'b> Context<'a, 'b> {
615604 arg_idx
616605 }
617606 };
618 pos("At", Some(arg_idx))
607 self.ecx.expr_usize(sp, arg_idx)
619608 }
620609
621610 // should never be the case, because names are already
src/librustc_mir/shim.rs+53-27
......@@ -31,9 +31,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
3131
3232 let mut result = match instance {
3333 ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
34 ty::InstanceDef::VtableShim(def_id) => {
35 build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None)
36 }
34 ty::InstanceDef::VtableShim(def_id) => build_call_shim(
35 tcx,
36 instance,
37 Some(Adjustment::DerefMove),
38 CallKind::Direct(def_id),
39 None,
40 ),
3741 ty::InstanceDef::FnPtrShim(def_id, ty) => {
3842 let trait_ = tcx.trait_of_item(def_id).unwrap();
3943 let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
......@@ -50,7 +54,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
5054 let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
5155 let arg_tys = sig.inputs();
5256
53 build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys))
57 build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect, Some(arg_tys))
5458 }
5559 // We are generating a call back to our def-id, which the
5660 // codegen backend knows to turn to an actual call, be it
......@@ -58,7 +62,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
5862 // indirect calls must be codegen'd differently than direct ones
5963 // (such as `#[track_caller]`).
6064 ty::InstanceDef::ReifyShim(def_id) => {
61 build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None)
65 build_call_shim(tcx, instance, None, CallKind::Direct(def_id), None)
6266 }
6367 ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
6468 let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
......@@ -68,7 +72,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
6872 .unwrap()
6973 .def_id;
7074
71 build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None)
75 build_call_shim(
76 tcx,
77 instance,
78 Some(Adjustment::RefMut),
79 CallKind::Direct(call_mut),
80 None,
81 )
7282 }
7383 ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty),
7484 ty::InstanceDef::CloneShim(def_id, ty) => {
......@@ -648,7 +658,7 @@ impl CloneShimBuilder<'tcx> {
648658fn build_call_shim<'tcx>(
649659 tcx: TyCtxt<'tcx>,
650660 instance: ty::InstanceDef<'tcx>,
651 rcvr_adjustment: Adjustment,
661 rcvr_adjustment: Option<Adjustment>,
652662 call_kind: CallKind,
653663 untuple_args: Option<&[Ty<'tcx>]>,
654664) -> BodyAndCache<'tcx> {
......@@ -680,14 +690,16 @@ fn build_call_shim<'tcx>(
680690 let mut local_decls = local_decls_for_sig(&sig, span);
681691 let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
682692
683 let rcvr_arg = Local::new(1 + 0);
684 let rcvr_l = Place::from(rcvr_arg);
693 let rcvr_place = || {
694 assert!(rcvr_adjustment.is_some());
695 Place::from(Local::new(1 + 0))
696 };
685697 let mut statements = vec![];
686698
687 let rcvr = match rcvr_adjustment {
688 Adjustment::Identity => Operand::Move(rcvr_l),
689 Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)),
690 Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_l)),
699 let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
700 Adjustment::Identity => Operand::Move(rcvr_place()),
701 Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_place())),
702 Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())),
691703 Adjustment::RefMut => {
692704 // let rcvr = &mut rcvr;
693705 let ref_rcvr = local_decls.push(temp_decl(
......@@ -703,15 +715,15 @@ fn build_call_shim<'tcx>(
703715 source_info,
704716 kind: StatementKind::Assign(box (
705717 Place::from(ref_rcvr),
706 Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l),
718 Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()),
707719 )),
708720 });
709721 Operand::Move(Place::from(ref_rcvr))
710722 }
711 };
723 });
712724
713725 let (callee, mut args) = match call_kind {
714 CallKind::Indirect => (rcvr, vec![]),
726 CallKind::Indirect => (rcvr.unwrap(), vec![]),
715727 CallKind::Direct(def_id) => {
716728 let ty = tcx.type_of(def_id);
717729 (
......@@ -720,21 +732,35 @@ fn build_call_shim<'tcx>(
720732 user_ty: None,
721733 literal: ty::Const::zero_sized(tcx, ty),
722734 }),
723 vec![rcvr],
735 rcvr.into_iter().collect::<Vec<_>>(),
724736 )
725737 }
726738 };
727739
740 let mut arg_range = 0..sig.inputs().len();
741
742 // Take the `self` ("receiver") argument out of the range (it's adjusted above).
743 if rcvr_adjustment.is_some() {
744 arg_range.start += 1;
745 }
746
747 // Take the last argument, if we need to untuple it (handled below).
748 if untuple_args.is_some() {
749 arg_range.end -= 1;
750 }
751
752 // Pass all of the non-special arguments directly.
753 args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
754
755 // Untuple the last argument, if we have to.
728756 if let Some(untuple_args) = untuple_args {
757 let tuple_arg = Local::new(1 + (sig.inputs().len() - 1));
729758 args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
730 let arg_place = Place::from(Local::new(1 + 1));
731 Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity))
759 Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity))
732760 }));
733 } else {
734 args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
735761 }
736762
737 let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
763 let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 };
738764 let mut blocks = IndexVec::with_capacity(n_blocks);
739765 let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
740766 blocks.push(BasicBlockData {
......@@ -752,7 +778,7 @@ fn build_call_shim<'tcx>(
752778 func: callee,
753779 args,
754780 destination: Some((Place::return_place(), BasicBlock::new(1))),
755 cleanup: if let Adjustment::RefMut = rcvr_adjustment {
781 cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment {
756782 Some(BasicBlock::new(3))
757783 } else {
758784 None
......@@ -762,13 +788,13 @@ fn build_call_shim<'tcx>(
762788 false,
763789 );
764790
765 if let Adjustment::RefMut = rcvr_adjustment {
791 if let Some(Adjustment::RefMut) = rcvr_adjustment {
766792 // BB #1 - drop for Self
767793 block(
768794 &mut blocks,
769795 vec![],
770796 TerminatorKind::Drop {
771 location: Place::from(rcvr_arg),
797 location: rcvr_place(),
772798 target: BasicBlock::new(2),
773799 unwind: None,
774800 },
......@@ -777,13 +803,13 @@ fn build_call_shim<'tcx>(
777803 }
778804 // BB #1/#2 - return
779805 block(&mut blocks, vec![], TerminatorKind::Return, false);
780 if let Adjustment::RefMut = rcvr_adjustment {
806 if let Some(Adjustment::RefMut) = rcvr_adjustment {
781807 // BB #3 - drop if closure panics
782808 block(
783809 &mut blocks,
784810 vec![],
785811 TerminatorKind::Drop {
786 location: Place::from(rcvr_arg),
812 location: rcvr_place(),
787813 target: BasicBlock::new(4),
788814 unwind: None,
789815 },
src/librustc_mir/transform/const_prop.rs+22-22
......@@ -14,7 +14,7 @@ use rustc::mir::{
1414 SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind,
1515 UnOp, RETURN_PLACE,
1616};
17use rustc::traits::TraitQueryMode;
17use rustc::traits;
1818use rustc::ty::layout::{
1919 HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout,
2020};
......@@ -90,28 +90,28 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
9090 // If there are unsatisfiable where clauses, then all bets are
9191 // off, and we just give up.
9292 //
93 // Note that we use TraitQueryMode::Canonical here, which causes
94 // us to treat overflow like any other error. This is because we
95 // are "speculatively" evaluating this item with the default substs.
96 // While this usually succeeds, it may fail with tricky impls
97 // (e.g. the typenum crate). Const-propagation is fundamentally
98 // "best-effort", and does not affect correctness in any way.
99 // Therefore, it's perfectly fine to just "give up" if we're
100 // unable to check the bounds with the default substs.
93 // We manually filter the predicates, skipping anything that's not
94 // "global". We are in a potentially generic context
95 // (e.g. we are evaluating a function without substituting generic
96 // parameters, so this filtering serves two purposes:
10197 //
102 // False negatives (failing to run const-prop on something when we actually
103 // could) are fine. However, false positives (running const-prop on
104 // an item with unsatisfiable bounds) can lead to us generating invalid
105 // MIR.
106 if !tcx.substitute_normalize_and_test_predicates((
107 source.def_id(),
108 InternalSubsts::identity_for_item(tcx, source.def_id()),
109 TraitQueryMode::Canonical,
110 )) {
111 trace!(
112 "ConstProp skipped for item with unsatisfiable predicates: {:?}",
113 source.def_id()
114 );
98 // 1. We skip evaluating any predicates that we would
99 // never be able prove are unsatisfiable (e.g. `<T as Foo>`
100 // 2. We avoid trying to normalize predicates involving generic
101 // parameters (e.g. `<T as Foo>::MyItem`). This can confuse
102 // the normalization code (leading to cycle errors), since
103 // it's usually never invoked in this way.
104 let predicates = tcx
105 .predicates_of(source.def_id())
106 .predicates
107 .iter()
108 .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None })
109 .collect();
110 if !traits::normalize_and_test_predicates(
111 tcx,
112 traits::elaborate_predicates(tcx, predicates).collect(),
113 ) {
114 trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", source.def_id());
115115 return;
116116 }
117117
src/librustdoc/html/render.rs+5-5
......@@ -2321,8 +2321,8 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
23212321 "{}{}{}{}{:#}fn {}{:#}",
23222322 it.visibility.print_with_space(),
23232323 f.header.constness.print_with_space(),
2324 f.header.unsafety.print_with_space(),
23252324 f.header.asyncness.print_with_space(),
2325 f.header.unsafety.print_with_space(),
23262326 print_abi_with_space(f.header.abi),
23272327 it.name.as_ref().unwrap(),
23282328 f.generics.print()
......@@ -2332,12 +2332,12 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
23322332 render_attributes(w, it, false);
23332333 write!(
23342334 w,
2335 "{vis}{constness}{unsafety}{asyncness}{abi}fn \
2335 "{vis}{constness}{asyncness}{unsafety}{abi}fn \
23362336 {name}{generics}{decl}{where_clause}</pre>",
23372337 vis = it.visibility.print_with_space(),
23382338 constness = f.header.constness.print_with_space(),
2339 unsafety = f.header.unsafety.print_with_space(),
23402339 asyncness = f.header.asyncness.print_with_space(),
2340 unsafety = f.header.unsafety.print_with_space(),
23412341 abi = print_abi_with_space(f.header.abi),
23422342 name = it.name.as_ref().unwrap(),
23432343 generics = f.generics.print(),
......@@ -2832,8 +2832,8 @@ fn render_assoc_item(
28322832 "{}{}{}{}{}{:#}fn {}{:#}",
28332833 meth.visibility.print_with_space(),
28342834 header.constness.print_with_space(),
2835 header.unsafety.print_with_space(),
28362835 header.asyncness.print_with_space(),
2836 header.unsafety.print_with_space(),
28372837 print_default_space(meth.is_default()),
28382838 print_abi_with_space(header.abi),
28392839 name,
......@@ -2854,8 +2854,8 @@ fn render_assoc_item(
28542854 if parent == ItemType::Trait { " " } else { "" },
28552855 meth.visibility.print_with_space(),
28562856 header.constness.print_with_space(),
2857 header.unsafety.print_with_space(),
28582857 header.asyncness.print_with_space(),
2858 header.unsafety.print_with_space(),
28592859 print_default_space(meth.is_default()),
28602860 print_abi_with_space(header.abi),
28612861 href = href,
src/test/rustdoc/async-fn.rs+7
......@@ -15,6 +15,11 @@ pub async fn baz<T>(a: T) -> T {
1515 a
1616}
1717
18// @has async_fn/fn.qux.html '//pre[@class="rust fn"]' 'pub async unsafe fn qux() -> char'
19pub async unsafe fn qux() -> char {
20 '⚠'
21}
22
1823trait Bar {}
1924
2025impl Bar for () {}
......@@ -26,8 +31,10 @@ pub async fn quux() -> impl Bar {
2631
2732// @has async_fn/struct.Foo.html
2833// @matches - '//code' 'pub async fn f\(\)$'
34// @matches - '//code' 'pub async unsafe fn g\(\)$'
2935pub struct Foo;
3036
3137impl Foo {
3238 pub async fn f() {}
39 pub async unsafe fn g() {}
3340}
src/test/ui/async-await/async-fn-nonsend.rs+7-8
......@@ -2,15 +2,15 @@
22// edition:2018
33// compile-flags: --crate-type lib
44
5use std::{
6 cell::RefCell,
7 fmt::Debug,
8 rc::Rc,
9};
5use std::{cell::RefCell, fmt::Debug, rc::Rc};
106
11fn non_sync() -> impl Debug { RefCell::new(()) }
7fn non_sync() -> impl Debug {
8 RefCell::new(())
9}
1210
13fn non_send() -> impl Debug { Rc::new(()) }
11fn non_send() -> impl Debug {
12 Rc::new(())
13}
1414
1515fn take_ref<T>(_: &T) {}
1616
......@@ -53,5 +53,4 @@ pub fn pass_assert() {
5353 //~^ ERROR future cannot be sent between threads safely
5454 assert_send(non_sync_with_method_call());
5555 //~^ ERROR future cannot be sent between threads safely
56 //~^^ ERROR future cannot be sent between threads safely
5756}
src/test/ui/async-await/async-fn-nonsend.stderr+1-23
......@@ -62,27 +62,5 @@ LL | }
6262LL | }
6363 | - `f` is later dropped here
6464
65error: future cannot be sent between threads safely
66 --> $DIR/async-fn-nonsend.rs:54:5
67 |
68LL | fn assert_send(_: impl Send) {}
69 | ----------- ---- required by this bound in `assert_send`
70...
71LL | assert_send(non_sync_with_method_call());
72 | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
73 |
74 = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
75note: future is not `Send` as this value is used across an await
76 --> $DIR/async-fn-nonsend.rs:43:9
77 |
78LL | let f: &mut std::fmt::Formatter = panic!();
79 | - has type `&mut std::fmt::Formatter<'_>`
80LL | if non_sync().fmt(f).unwrap() == () {
81LL | fut().await;
82 | ^^^^^^^^^^^ await occurs here, with `f` maybe used later
83LL | }
84LL | }
85 | - `f` is later dropped here
86
87error: aborting due to 4 previous errors
65error: aborting due to 3 previous errors
8866
src/test/ui/consts/array-literal-index-oob.rs+1
......@@ -1,4 +1,5 @@
11// build-pass
2// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
23
34#![warn(const_err)]
45
src/test/ui/consts/array-literal-index-oob.stderr+4-4
......@@ -1,17 +1,17 @@
11warning: index out of bounds: the len is 3 but the index is 4
2 --> $DIR/array-literal-index-oob.rs:6:8
2 --> $DIR/array-literal-index-oob.rs:7:8
33 |
44LL | &{ [1, 2, 3][4] };
55 | ^^^^^^^^^^^^
66 |
77note: lint level defined here
8 --> $DIR/array-literal-index-oob.rs:3:9
8 --> $DIR/array-literal-index-oob.rs:4:9
99 |
1010LL | #![warn(const_err)]
1111 | ^^^^^^^^^
1212
1313warning: reaching this expression at runtime will panic or abort
14 --> $DIR/array-literal-index-oob.rs:6:8
14 --> $DIR/array-literal-index-oob.rs:7:8
1515 |
1616LL | &{ [1, 2, 3][4] };
1717 | ---^^^^^^^^^^^^--
......@@ -19,7 +19,7 @@ LL | &{ [1, 2, 3][4] };
1919 | indexing out of bounds: the len is 3 but the index is 4
2020
2121warning: erroneous constant used
22 --> $DIR/array-literal-index-oob.rs:6:5
22 --> $DIR/array-literal-index-oob.rs:7:5
2323 |
2424LL | &{ [1, 2, 3][4] };
2525 | ^^^^^^^^^^^^^^^^^ referenced constant has errors
src/test/ui/consts/const-eval/promoted_errors.rs+1
......@@ -1,4 +1,5 @@
11// build-pass
2// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
23// compile-flags: -O
34
45#![warn(const_err)]
src/test/ui/consts/const-eval/promoted_errors.stderr+10-10
......@@ -1,59 +1,59 @@
11warning: this expression will panic at runtime
2 --> $DIR/promoted_errors.rs:8:14
2 --> $DIR/promoted_errors.rs:9:14
33 |
44LL | let _x = 0u32 - 1;
55 | ^^^^^^^^ attempt to subtract with overflow
66 |
77note: lint level defined here
8 --> $DIR/promoted_errors.rs:4:9
8 --> $DIR/promoted_errors.rs:5:9
99 |
1010LL | #![warn(const_err)]
1111 | ^^^^^^^^^
1212
1313warning: attempt to divide by zero
14 --> $DIR/promoted_errors.rs:10:20
14 --> $DIR/promoted_errors.rs:11:20
1515 |
1616LL | println!("{}", 1 / (1 - 1));
1717 | ^^^^^^^^^^^
1818
1919warning: reaching this expression at runtime will panic or abort
20 --> $DIR/promoted_errors.rs:10:20
20 --> $DIR/promoted_errors.rs:11:20
2121 |
2222LL | println!("{}", 1 / (1 - 1));
2323 | ^^^^^^^^^^^ dividing by zero
2424
2525warning: erroneous constant used
26 --> $DIR/promoted_errors.rs:10:20
26 --> $DIR/promoted_errors.rs:11:20
2727 |
2828LL | println!("{}", 1 / (1 - 1));
2929 | ^^^^^^^^^^^ referenced constant has errors
3030
3131warning: attempt to divide by zero
32 --> $DIR/promoted_errors.rs:14:14
32 --> $DIR/promoted_errors.rs:15:14
3333 |
3434LL | let _x = 1 / (1 - 1);
3535 | ^^^^^^^^^^^
3636
3737warning: attempt to divide by zero
38 --> $DIR/promoted_errors.rs:16:20
38 --> $DIR/promoted_errors.rs:17:20
3939 |
4040LL | println!("{}", 1 / (false as u32));
4141 | ^^^^^^^^^^^^^^^^^^
4242
4343warning: reaching this expression at runtime will panic or abort
44 --> $DIR/promoted_errors.rs:16:20
44 --> $DIR/promoted_errors.rs:17:20
4545 |
4646LL | println!("{}", 1 / (false as u32));
4747 | ^^^^^^^^^^^^^^^^^^ dividing by zero
4848
4949warning: erroneous constant used
50 --> $DIR/promoted_errors.rs:16:20
50 --> $DIR/promoted_errors.rs:17:20
5151 |
5252LL | println!("{}", 1 / (false as u32));
5353 | ^^^^^^^^^^^^^^^^^^ referenced constant has errors
5454
5555warning: attempt to divide by zero
56 --> $DIR/promoted_errors.rs:20:14
56 --> $DIR/promoted_errors.rs:21:14
5757 |
5858LL | let _x = 1 / (false as u32);
5959 | ^^^^^^^^^^^^^^^^^^
src/test/ui/consts/const-eval/promoted_errors2.rs+1
......@@ -1,4 +1,5 @@
11// build-pass
2// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
23// compile-flags: -C overflow-checks=on -O
34
45#![warn(const_err)]
src/test/ui/consts/const-eval/promoted_errors2.stderr+11-11
......@@ -1,65 +1,65 @@
11warning: attempt to subtract with overflow
2 --> $DIR/promoted_errors2.rs:7:20
2 --> $DIR/promoted_errors2.rs:8:20
33 |
44LL | println!("{}", 0u32 - 1);
55 | ^^^^^^^^
66 |
77note: lint level defined here
8 --> $DIR/promoted_errors2.rs:4:9
8 --> $DIR/promoted_errors2.rs:5:9
99 |
1010LL | #![warn(const_err)]
1111 | ^^^^^^^^^
1212
1313warning: attempt to subtract with overflow
14 --> $DIR/promoted_errors2.rs:9:14
14 --> $DIR/promoted_errors2.rs:10:14
1515 |
1616LL | let _x = 0u32 - 1;
1717 | ^^^^^^^^
1818
1919warning: attempt to divide by zero
20 --> $DIR/promoted_errors2.rs:11:20
20 --> $DIR/promoted_errors2.rs:12:20
2121 |
2222LL | println!("{}", 1 / (1 - 1));
2323 | ^^^^^^^^^^^
2424
2525warning: reaching this expression at runtime will panic or abort
26 --> $DIR/promoted_errors2.rs:11:20
26 --> $DIR/promoted_errors2.rs:12:20
2727 |
2828LL | println!("{}", 1 / (1 - 1));
2929 | ^^^^^^^^^^^ dividing by zero
3030
3131warning: erroneous constant used
32 --> $DIR/promoted_errors2.rs:11:20
32 --> $DIR/promoted_errors2.rs:12:20
3333 |
3434LL | println!("{}", 1 / (1 - 1));
3535 | ^^^^^^^^^^^ referenced constant has errors
3636
3737warning: attempt to divide by zero
38 --> $DIR/promoted_errors2.rs:15:14
38 --> $DIR/promoted_errors2.rs:16:14
3939 |
4040LL | let _x = 1 / (1 - 1);
4141 | ^^^^^^^^^^^
4242
4343warning: attempt to divide by zero
44 --> $DIR/promoted_errors2.rs:17:20
44 --> $DIR/promoted_errors2.rs:18:20
4545 |
4646LL | println!("{}", 1 / (false as u32));
4747 | ^^^^^^^^^^^^^^^^^^
4848
4949warning: reaching this expression at runtime will panic or abort
50 --> $DIR/promoted_errors2.rs:17:20
50 --> $DIR/promoted_errors2.rs:18:20
5151 |
5252LL | println!("{}", 1 / (false as u32));
5353 | ^^^^^^^^^^^^^^^^^^ dividing by zero
5454
5555warning: erroneous constant used
56 --> $DIR/promoted_errors2.rs:17:20
56 --> $DIR/promoted_errors2.rs:18:20
5757 |
5858LL | println!("{}", 1 / (false as u32));
5959 | ^^^^^^^^^^^^^^^^^^ referenced constant has errors
6060
6161warning: attempt to divide by zero
62 --> $DIR/promoted_errors2.rs:21:14
62 --> $DIR/promoted_errors2.rs:22:14
6363 |
6464LL | let _x = 1 / (false as u32);
6565 | ^^^^^^^^^^^^^^^^^^
src/test/ui/consts/issue-68264-overflow.rs created+43
......@@ -0,0 +1,43 @@
1// check-pass
2// compile-flags: --emit=mir,link
3// Regression test for issue #68264
4// Checks that we don't encounter overflow
5// when running const-prop on functions with
6// complicated bounds
7pub trait Query {}
8
9pub trait AsQuery {
10 type Query: Query;
11}
12pub trait Table: AsQuery + Sized {}
13
14pub trait LimitDsl {
15 type Output;
16}
17
18pub(crate) trait LoadQuery<Conn, U>: RunQueryDsl<Conn> {}
19
20impl<T: Query> AsQuery for T {
21 type Query = Self;
22}
23
24impl<T> LimitDsl for T
25where
26 T: Table,
27 T::Query: LimitDsl,
28{
29 type Output = <T::Query as LimitDsl>::Output;
30}
31
32pub(crate) trait RunQueryDsl<Conn>: Sized {
33 fn first<U>(self, _conn: &Conn) -> U
34 where
35 Self: LimitDsl,
36 Self::Output: LoadQuery<Conn, U>,
37 {
38 // Overflow is caused by this function body
39 unimplemented!()
40 }
41}
42
43fn main() {}
src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs created+19
......@@ -0,0 +1,19 @@
1// run-pass
2
3#![feature(track_caller)]
4
5fn pass_to_ptr_call<T>(f: fn(T), x: T) {
6 f(x);
7}
8
9#[track_caller]
10fn tracked_unit(_: ()) {
11 let expected_line = line!() - 1;
12 let location = std::panic::Location::caller();
13 assert_eq!(location.file(), file!());
14 assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
15}
16
17fn main() {
18 pass_to_ptr_call(tracked_unit, ());
19}
src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs created+19
......@@ -0,0 +1,19 @@
1// run-pass
2
3#![feature(track_caller)]
4
5fn ptr_call(f: fn()) {
6 f();
7}
8
9#[track_caller]
10fn tracked() {
11 let expected_line = line!() - 1;
12 let location = std::panic::Location::caller();
13 assert_eq!(location.file(), file!());
14 assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
15}
16
17fn main() {
18 ptr_call(tracked);
19}
src/tools/build-manifest/src/main.rs+1
......@@ -110,6 +110,7 @@ static TARGETS: &[&str] = &[
110110 "riscv32imac-unknown-none-elf",
111111 "riscv64imac-unknown-none-elf",
112112 "riscv64gc-unknown-none-elf",
113 "riscv64gc-unknown-linux-gnu",
113114 "s390x-unknown-linux-gnu",
114115 "sparc64-unknown-linux-gnu",
115116 "sparcv9-sun-solaris",