| author | bors <bors@rust-lang.org> 2020-01-20 23:35:50 UTC |
| committer | bors <bors@rust-lang.org> 2020-01-20 23:35:50 UTC |
| log | 06b945049b6e6795bcfb9fb8007a46c44a93c0aa |
| tree | e5ac89eda26500d49ee52698ed3d9b033cd2e05a |
| parent | b5a3341f1b8b475990e9d1b071b88d3c280936b4 |
| parent | f6406f7f680d4f77144d22e1f74064e878213f5c |
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? @ghost27 files changed, 266 insertions(+), 242 deletions(-)
LICENSE-APACHE-25| ... | ... | @@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
| 174 | 174 | of your accepting any such warranty or additional liability. |
| 175 | 175 | |
| 176 | 176 | END OF TERMS AND CONDITIONS |
| 177 | ||
| 178 | APPENDIX: 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 | ||
| 189 | Copyright [yyyy] [name of copyright owner] | |
| 190 | ||
| 191 | Licensed under the Apache License, Version 2.0 (the "License"); | |
| 192 | you may not use this file except in compliance with the License. | |
| 193 | You may obtain a copy of the License at | |
| 194 | ||
| 195 | 	http://www.apache.org/licenses/LICENSE-2.0 | |
| 196 | ||
| 197 | Unless required by applicable law or agreed to in writing, software | |
| 198 | distributed under the License is distributed on an "AS IS" BASIS, | |
| 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 200 | See the License for the specific language governing permissions and | |
| 201 | limitations under the License. |
src/libcore/alloc.rs+2-1| ... | ... | @@ -525,7 +525,8 @@ pub unsafe trait GlobalAlloc { |
| 525 | 525 | /// The memory may or may not have been deallocated, |
| 526 | 526 | /// and should be considered unusable (unless of course it was |
| 527 | 527 | /// 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`. | |
| 529 | 530 | /// |
| 530 | 531 | /// If this method returns null, then ownership of the memory |
| 531 | 532 | /// block has not been transferred to this allocator, and the |
src/libcore/fmt/mod.rs+34-41| ... | ... | @@ -10,7 +10,6 @@ use crate::mem; |
| 10 | 10 | use crate::num::flt2dec; |
| 11 | 11 | use crate::ops::Deref; |
| 12 | 12 | use crate::result; |
| 13 | use crate::slice; | |
| 14 | 13 | use crate::str; |
| 15 | 14 | |
| 16 | 15 | mod builders; |
| ... | ... | @@ -234,8 +233,6 @@ pub struct Formatter<'a> { |
| 234 | 233 | precision: Option<usize>, |
| 235 | 234 | |
| 236 | 235 | buf: &'a mut (dyn Write + 'a), |
| 237 | curarg: slice::Iter<'a, ArgumentV1<'a>>, | |
| 238 | args: &'a [ArgumentV1<'a>], | |
| 239 | 236 | } |
| 240 | 237 | |
| 241 | 238 | // NB. Argument is essentially an optimized partially applied formatting function, |
| ... | ... | @@ -1043,8 +1040,6 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { |
| 1043 | 1040 | buf: output, |
| 1044 | 1041 | align: rt::v1::Alignment::Unknown, |
| 1045 | 1042 | fill: ' ', |
| 1046 | args: args.args, | |
| 1047 | curarg: args.args.iter(), | |
| 1048 | 1043 | }; |
| 1049 | 1044 | |
| 1050 | 1045 | let mut idx = 0; |
| ... | ... | @@ -1063,7 +1058,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { |
| 1063 | 1058 | // a string piece. |
| 1064 | 1059 | for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { |
| 1065 | 1060 | formatter.buf.write_str(*piece)?; |
| 1066 | formatter.run(arg)?; | |
| 1061 | run(&mut formatter, arg, &args.args)?; | |
| 1067 | 1062 | idx += 1; |
| 1068 | 1063 | } |
| 1069 | 1064 | } |
| ... | ... | @@ -1077,6 +1072,39 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { |
| 1077 | 1072 | Ok(()) |
| 1078 | 1073 | } |
| 1079 | 1074 | |
| 1075 | fn 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 | ||
| 1100 | fn 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 | ||
| 1080 | 1108 | /// Padding after the end of something. Returned by `Formatter::padding`. |
| 1081 | 1109 | #[must_use = "don't forget to write the post padding"] |
| 1082 | 1110 | struct PostPadding { |
| ... | ... | @@ -1114,41 +1142,6 @@ impl<'a> Formatter<'a> { |
| 1114 | 1142 | align: self.align, |
| 1115 | 1143 | width: self.width, |
| 1116 | 1144 | 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(), | |
| 1152 | 1145 | } |
| 1153 | 1146 | } |
| 1154 | 1147 |
src/libcore/fmt/rt/v1.rs+4-2| ... | ... | @@ -7,7 +7,10 @@ |
| 7 | 7 | |
| 8 | 8 | #[derive(Copy, Clone)] |
| 9 | 9 | pub struct Argument { |
| 10 | #[cfg(bootstrap)] | |
| 10 | 11 | pub position: Position, |
| 12 | #[cfg(not(bootstrap))] | |
| 13 | pub position: usize, | |
| 11 | 14 | pub format: FormatSpec, |
| 12 | 15 | } |
| 13 | 16 | |
| ... | ... | @@ -37,12 +40,11 @@ pub enum Alignment { |
| 37 | 40 | pub enum Count { |
| 38 | 41 | Is(usize), |
| 39 | 42 | Param(usize), |
| 40 | NextParam, | |
| 41 | 43 | Implied, |
| 42 | 44 | } |
| 43 | 45 | |
| 46 | #[cfg(bootstrap)] | |
| 44 | 47 | #[derive(Copy, Clone)] |
| 45 | 48 | pub enum Position { |
| 46 | Next, | |
| 47 | 49 | At(usize), |
| 48 | 50 | } |
src/librustc/mir/mono.rs+1-4| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId}; |
| 2 | 2 | use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; |
| 3 | 3 | use crate::session::config::OptLevel; |
| 4 | use crate::traits::TraitQueryMode; | |
| 5 | 4 | use crate::ty::print::obsolete::DefPathBasedNames; |
| 6 | 5 | use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; |
| 7 | 6 | use rustc_data_structures::base_n; |
| ... | ... | @@ -168,9 +167,7 @@ impl<'tcx> MonoItem<'tcx> { |
| 168 | 167 | MonoItem::GlobalAsm(..) => return true, |
| 169 | 168 | }; |
| 170 | 169 | |
| 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)) | |
| 174 | 171 | } |
| 175 | 172 | |
| 176 | 173 | pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String { |
src/librustc/query/mod.rs+3-3| ... | ... | @@ -1156,11 +1156,11 @@ rustc_queries! { |
| 1156 | 1156 | desc { "normalizing `{:?}`", goal } |
| 1157 | 1157 | } |
| 1158 | 1158 | |
| 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 { | |
| 1160 | 1160 | no_force |
| 1161 | 1161 | 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) | |
| 1164 | 1164 | } |
| 1165 | 1165 | } |
| 1166 | 1166 |
src/librustc/traits/fulfill.rs+2-22| ... | ... | @@ -16,7 +16,6 @@ use super::CodeSelectionError; |
| 16 | 16 | use super::{ConstEvalFailure, Unimplemented}; |
| 17 | 17 | use super::{FulfillmentError, FulfillmentErrorCode}; |
| 18 | 18 | use super::{ObligationCause, PredicateObligation}; |
| 19 | use crate::traits::TraitQueryMode; | |
| 20 | 19 | |
| 21 | 20 | impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { |
| 22 | 21 | type Predicate = ty::Predicate<'tcx>; |
| ... | ... | @@ -63,9 +62,6 @@ pub struct FulfillmentContext<'tcx> { |
| 63 | 62 | // a snapshot (they don't *straddle* a snapshot, so there |
| 64 | 63 | // is no trouble there). |
| 65 | 64 | usable_in_snapshot: bool, |
| 66 | ||
| 67 | // The `TraitQueryMode` used when constructing a `SelectionContext` | |
| 68 | query_mode: TraitQueryMode, | |
| 69 | 65 | } |
| 70 | 66 | |
| 71 | 67 | #[derive(Clone, Debug)] |
| ... | ... | @@ -79,26 +75,12 @@ pub struct PendingPredicateObligation<'tcx> { |
| 79 | 75 | static_assert_size!(PendingPredicateObligation<'_>, 136); |
| 80 | 76 | |
| 81 | 77 | impl<'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. | |
| 84 | 79 | pub fn new() -> FulfillmentContext<'tcx> { |
| 85 | 80 | FulfillmentContext { |
| 86 | 81 | predicates: ObligationForest::new(), |
| 87 | 82 | register_region_obligations: true, |
| 88 | 83 | 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, | |
| 102 | 84 | } |
| 103 | 85 | } |
| 104 | 86 | |
| ... | ... | @@ -107,7 +89,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { |
| 107 | 89 | predicates: ObligationForest::new(), |
| 108 | 90 | register_region_obligations: true, |
| 109 | 91 | usable_in_snapshot: true, |
| 110 | query_mode: TraitQueryMode::Standard, | |
| 111 | 92 | } |
| 112 | 93 | } |
| 113 | 94 | |
| ... | ... | @@ -116,7 +97,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { |
| 116 | 97 | predicates: ObligationForest::new(), |
| 117 | 98 | register_region_obligations: false, |
| 118 | 99 | usable_in_snapshot: false, |
| 119 | query_mode: TraitQueryMode::Standard, | |
| 120 | 100 | } |
| 121 | 101 | } |
| 122 | 102 | |
| ... | ... | @@ -237,7 +217,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { |
| 237 | 217 | &mut self, |
| 238 | 218 | infcx: &InferCtxt<'_, 'tcx>, |
| 239 | 219 | ) -> Result<(), Vec<FulfillmentError<'tcx>>> { |
| 240 | let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode); | |
| 220 | let mut selcx = SelectionContext::new(infcx); | |
| 241 | 221 | self.select(&mut selcx) |
| 242 | 222 | } |
| 243 | 223 |
src/librustc/traits/mod.rs+8-12| ... | ... | @@ -95,7 +95,7 @@ pub enum IntercrateMode { |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | /// The mode that trait queries run in. |
| 98 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)] | |
| 98 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | |
| 99 | 99 | pub enum TraitQueryMode { |
| 100 | 100 | // Standard/un-canonicalized queries get accurate |
| 101 | 101 | // spans etc. passed in and hence can do reasonable |
| ... | ... | @@ -1014,17 +1014,16 @@ where |
| 1014 | 1014 | /// environment. If this returns false, then either normalize |
| 1015 | 1015 | /// encountered an error or one of the predicates did not hold. Used |
| 1016 | 1016 | /// when creating vtables to check for unsatisfiable methods. |
| 1017 | fn normalize_and_test_predicates<'tcx>( | |
| 1017 | pub fn normalize_and_test_predicates<'tcx>( | |
| 1018 | 1018 | tcx: TyCtxt<'tcx>, |
| 1019 | 1019 | predicates: Vec<ty::Predicate<'tcx>>, |
| 1020 | mode: TraitQueryMode, | |
| 1021 | 1020 | ) -> bool { |
| 1022 | debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode); | |
| 1021 | debug!("normalize_and_test_predicates(predicates={:?})", predicates); | |
| 1023 | 1022 | |
| 1024 | 1023 | let result = tcx.infer_ctxt().enter(|infcx| { |
| 1025 | 1024 | 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(); | |
| 1028 | 1027 | let cause = ObligationCause::dummy(); |
| 1029 | 1028 | let Normalized { value: predicates, obligations } = |
| 1030 | 1029 | normalize(&mut selcx, param_env, cause.clone(), &predicates); |
| ... | ... | @@ -1044,12 +1043,12 @@ fn normalize_and_test_predicates<'tcx>( |
| 1044 | 1043 | |
| 1045 | 1044 | fn substitute_normalize_and_test_predicates<'tcx>( |
| 1046 | 1045 | tcx: TyCtxt<'tcx>, |
| 1047 | key: (DefId, SubstsRef<'tcx>, TraitQueryMode), | |
| 1046 | key: (DefId, SubstsRef<'tcx>), | |
| 1048 | 1047 | ) -> bool { |
| 1049 | 1048 | debug!("substitute_normalize_and_test_predicates(key={:?})", key); |
| 1050 | 1049 | |
| 1051 | 1050 | 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); | |
| 1053 | 1052 | |
| 1054 | 1053 | debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result); |
| 1055 | 1054 | result |
| ... | ... | @@ -1102,10 +1101,7 @@ fn vtable_methods<'tcx>( |
| 1102 | 1101 | // Note that this method could then never be called, so we |
| 1103 | 1102 | // do not want to try and codegen it, in that case (see #23435). |
| 1104 | 1103 | 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) { | |
| 1109 | 1105 | debug!("vtable_methods: predicates do not hold"); |
| 1110 | 1106 | return None; |
| 1111 | 1107 | } |
src/librustc/ty/instance.rs+6-1| ... | ... | @@ -141,7 +141,12 @@ impl<'tcx> InstanceDef<'tcx> { |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | 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 | } | |
| 145 | 150 | } |
| 146 | 151 | } |
| 147 | 152 |
src/librustc/ty/query/keys.rs-9| ... | ... | @@ -125,15 +125,6 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { |
| 125 | 125 | } |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | impl<'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 | ||
| 137 | 128 | impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { |
| 138 | 129 | fn query_crate(&self) -> CrateNum { |
| 139 | 130 | self.1.def_id().krate |
src/librustc_builtin_macros/format.rs+1-12| ... | ... | @@ -590,17 +590,6 @@ impl<'a, 'b> Context<'a, 'b> { |
| 590 | 590 | parse::NextArgument(ref arg) => { |
| 591 | 591 | // Build the position |
| 592 | 592 | 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 | }; | |
| 604 | 593 | match arg.position { |
| 605 | 594 | parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => { |
| 606 | 595 | // Map to index in final generated argument array |
| ... | ... | @@ -615,7 +604,7 @@ impl<'a, 'b> Context<'a, 'b> { |
| 615 | 604 | arg_idx |
| 616 | 605 | } |
| 617 | 606 | }; |
| 618 | pos("At", Some(arg_idx)) | |
| 607 | self.ecx.expr_usize(sp, arg_idx) | |
| 619 | 608 | } |
| 620 | 609 | |
| 621 | 610 | // 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 |
| 31 | 31 | |
| 32 | 32 | let mut result = match instance { |
| 33 | 33 | 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 | ), | |
| 37 | 41 | ty::InstanceDef::FnPtrShim(def_id, ty) => { |
| 38 | 42 | let trait_ = tcx.trait_of_item(def_id).unwrap(); |
| 39 | 43 | 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 |
| 50 | 54 | let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx)); |
| 51 | 55 | let arg_tys = sig.inputs(); |
| 52 | 56 | |
| 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)) | |
| 54 | 58 | } |
| 55 | 59 | // We are generating a call back to our def-id, which the |
| 56 | 60 | // 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 |
| 58 | 62 | // indirect calls must be codegen'd differently than direct ones |
| 59 | 63 | // (such as `#[track_caller]`). |
| 60 | 64 | 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) | |
| 62 | 66 | } |
| 63 | 67 | ty::InstanceDef::ClosureOnceShim { call_once: _ } => { |
| 64 | 68 | 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 |
| 68 | 72 | .unwrap() |
| 69 | 73 | .def_id; |
| 70 | 74 | |
| 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 | ) | |
| 72 | 82 | } |
| 73 | 83 | ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty), |
| 74 | 84 | ty::InstanceDef::CloneShim(def_id, ty) => { |
| ... | ... | @@ -648,7 +658,7 @@ impl CloneShimBuilder<'tcx> { |
| 648 | 658 | fn build_call_shim<'tcx>( |
| 649 | 659 | tcx: TyCtxt<'tcx>, |
| 650 | 660 | instance: ty::InstanceDef<'tcx>, |
| 651 | rcvr_adjustment: Adjustment, | |
| 661 | rcvr_adjustment: Option<Adjustment>, | |
| 652 | 662 | call_kind: CallKind, |
| 653 | 663 | untuple_args: Option<&[Ty<'tcx>]>, |
| 654 | 664 | ) -> BodyAndCache<'tcx> { |
| ... | ... | @@ -680,14 +690,16 @@ fn build_call_shim<'tcx>( |
| 680 | 690 | let mut local_decls = local_decls_for_sig(&sig, span); |
| 681 | 691 | let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }; |
| 682 | 692 | |
| 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 | }; | |
| 685 | 697 | let mut statements = vec![]; |
| 686 | 698 | |
| 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())), | |
| 691 | 703 | Adjustment::RefMut => { |
| 692 | 704 | // let rcvr = &mut rcvr; |
| 693 | 705 | let ref_rcvr = local_decls.push(temp_decl( |
| ... | ... | @@ -703,15 +715,15 @@ fn build_call_shim<'tcx>( |
| 703 | 715 | source_info, |
| 704 | 716 | kind: StatementKind::Assign(box ( |
| 705 | 717 | 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()), | |
| 707 | 719 | )), |
| 708 | 720 | }); |
| 709 | 721 | Operand::Move(Place::from(ref_rcvr)) |
| 710 | 722 | } |
| 711 | }; | |
| 723 | }); | |
| 712 | 724 | |
| 713 | 725 | let (callee, mut args) = match call_kind { |
| 714 | CallKind::Indirect => (rcvr, vec![]), | |
| 726 | CallKind::Indirect => (rcvr.unwrap(), vec![]), | |
| 715 | 727 | CallKind::Direct(def_id) => { |
| 716 | 728 | let ty = tcx.type_of(def_id); |
| 717 | 729 | ( |
| ... | ... | @@ -720,21 +732,35 @@ fn build_call_shim<'tcx>( |
| 720 | 732 | user_ty: None, |
| 721 | 733 | literal: ty::Const::zero_sized(tcx, ty), |
| 722 | 734 | }), |
| 723 | vec![rcvr], | |
| 735 | rcvr.into_iter().collect::<Vec<_>>(), | |
| 724 | 736 | ) |
| 725 | 737 | } |
| 726 | 738 | }; |
| 727 | 739 | |
| 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. | |
| 728 | 756 | if let Some(untuple_args) = untuple_args { |
| 757 | let tuple_arg = Local::new(1 + (sig.inputs().len() - 1)); | |
| 729 | 758 | 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)) | |
| 732 | 760 | })); |
| 733 | } else { | |
| 734 | args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i))))); | |
| 735 | 761 | } |
| 736 | 762 | |
| 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 }; | |
| 738 | 764 | let mut blocks = IndexVec::with_capacity(n_blocks); |
| 739 | 765 | let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| { |
| 740 | 766 | blocks.push(BasicBlockData { |
| ... | ... | @@ -752,7 +778,7 @@ fn build_call_shim<'tcx>( |
| 752 | 778 | func: callee, |
| 753 | 779 | args, |
| 754 | 780 | 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 { | |
| 756 | 782 | Some(BasicBlock::new(3)) |
| 757 | 783 | } else { |
| 758 | 784 | None |
| ... | ... | @@ -762,13 +788,13 @@ fn build_call_shim<'tcx>( |
| 762 | 788 | false, |
| 763 | 789 | ); |
| 764 | 790 | |
| 765 | if let Adjustment::RefMut = rcvr_adjustment { | |
| 791 | if let Some(Adjustment::RefMut) = rcvr_adjustment { | |
| 766 | 792 | // BB #1 - drop for Self |
| 767 | 793 | block( |
| 768 | 794 | &mut blocks, |
| 769 | 795 | vec![], |
| 770 | 796 | TerminatorKind::Drop { |
| 771 | location: Place::from(rcvr_arg), | |
| 797 | location: rcvr_place(), | |
| 772 | 798 | target: BasicBlock::new(2), |
| 773 | 799 | unwind: None, |
| 774 | 800 | }, |
| ... | ... | @@ -777,13 +803,13 @@ fn build_call_shim<'tcx>( |
| 777 | 803 | } |
| 778 | 804 | // BB #1/#2 - return |
| 779 | 805 | block(&mut blocks, vec![], TerminatorKind::Return, false); |
| 780 | if let Adjustment::RefMut = rcvr_adjustment { | |
| 806 | if let Some(Adjustment::RefMut) = rcvr_adjustment { | |
| 781 | 807 | // BB #3 - drop if closure panics |
| 782 | 808 | block( |
| 783 | 809 | &mut blocks, |
| 784 | 810 | vec![], |
| 785 | 811 | TerminatorKind::Drop { |
| 786 | location: Place::from(rcvr_arg), | |
| 812 | location: rcvr_place(), | |
| 787 | 813 | target: BasicBlock::new(4), |
| 788 | 814 | unwind: None, |
| 789 | 815 | }, |
src/librustc_mir/transform/const_prop.rs+22-22| ... | ... | @@ -14,7 +14,7 @@ use rustc::mir::{ |
| 14 | 14 | SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, |
| 15 | 15 | UnOp, RETURN_PLACE, |
| 16 | 16 | }; |
| 17 | use rustc::traits::TraitQueryMode; | |
| 17 | use rustc::traits; | |
| 18 | 18 | use rustc::ty::layout::{ |
| 19 | 19 | HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, |
| 20 | 20 | }; |
| ... | ... | @@ -90,28 +90,28 @@ impl<'tcx> MirPass<'tcx> for ConstProp { |
| 90 | 90 | // If there are unsatisfiable where clauses, then all bets are |
| 91 | 91 | // off, and we just give up. |
| 92 | 92 | // |
| 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: | |
| 101 | 97 | // |
| 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()); | |
| 115 | 115 | return; |
| 116 | 116 | } |
| 117 | 117 |
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 |
| 2321 | 2321 | "{}{}{}{}{:#}fn {}{:#}", |
| 2322 | 2322 | it.visibility.print_with_space(), |
| 2323 | 2323 | f.header.constness.print_with_space(), |
| 2324 | f.header.unsafety.print_with_space(), | |
| 2325 | 2324 | f.header.asyncness.print_with_space(), |
| 2325 | f.header.unsafety.print_with_space(), | |
| 2326 | 2326 | print_abi_with_space(f.header.abi), |
| 2327 | 2327 | it.name.as_ref().unwrap(), |
| 2328 | 2328 | f.generics.print() |
| ... | ... | @@ -2332,12 +2332,12 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func |
| 2332 | 2332 | render_attributes(w, it, false); |
| 2333 | 2333 | write!( |
| 2334 | 2334 | w, |
| 2335 | "{vis}{constness}{unsafety}{asyncness}{abi}fn \ | |
| 2335 | "{vis}{constness}{asyncness}{unsafety}{abi}fn \ | |
| 2336 | 2336 | {name}{generics}{decl}{where_clause}</pre>", |
| 2337 | 2337 | vis = it.visibility.print_with_space(), |
| 2338 | 2338 | constness = f.header.constness.print_with_space(), |
| 2339 | unsafety = f.header.unsafety.print_with_space(), | |
| 2340 | 2339 | asyncness = f.header.asyncness.print_with_space(), |
| 2340 | unsafety = f.header.unsafety.print_with_space(), | |
| 2341 | 2341 | abi = print_abi_with_space(f.header.abi), |
| 2342 | 2342 | name = it.name.as_ref().unwrap(), |
| 2343 | 2343 | generics = f.generics.print(), |
| ... | ... | @@ -2832,8 +2832,8 @@ fn render_assoc_item( |
| 2832 | 2832 | "{}{}{}{}{}{:#}fn {}{:#}", |
| 2833 | 2833 | meth.visibility.print_with_space(), |
| 2834 | 2834 | header.constness.print_with_space(), |
| 2835 | header.unsafety.print_with_space(), | |
| 2836 | 2835 | header.asyncness.print_with_space(), |
| 2836 | header.unsafety.print_with_space(), | |
| 2837 | 2837 | print_default_space(meth.is_default()), |
| 2838 | 2838 | print_abi_with_space(header.abi), |
| 2839 | 2839 | name, |
| ... | ... | @@ -2854,8 +2854,8 @@ fn render_assoc_item( |
| 2854 | 2854 | if parent == ItemType::Trait { " " } else { "" }, |
| 2855 | 2855 | meth.visibility.print_with_space(), |
| 2856 | 2856 | header.constness.print_with_space(), |
| 2857 | header.unsafety.print_with_space(), | |
| 2858 | 2857 | header.asyncness.print_with_space(), |
| 2858 | header.unsafety.print_with_space(), | |
| 2859 | 2859 | print_default_space(meth.is_default()), |
| 2860 | 2860 | print_abi_with_space(header.abi), |
| 2861 | 2861 | href = href, |
src/test/rustdoc/async-fn.rs+7| ... | ... | @@ -15,6 +15,11 @@ pub async fn baz<T>(a: T) -> T { |
| 15 | 15 | a |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | // @has async_fn/fn.qux.html '//pre[@class="rust fn"]' 'pub async unsafe fn qux() -> char' | |
| 19 | pub async unsafe fn qux() -> char { | |
| 20 | '⚠' | |
| 21 | } | |
| 22 | ||
| 18 | 23 | trait Bar {} |
| 19 | 24 | |
| 20 | 25 | impl Bar for () {} |
| ... | ... | @@ -26,8 +31,10 @@ pub async fn quux() -> impl Bar { |
| 26 | 31 | |
| 27 | 32 | // @has async_fn/struct.Foo.html |
| 28 | 33 | // @matches - '//code' 'pub async fn f\(\)$' |
| 34 | // @matches - '//code' 'pub async unsafe fn g\(\)$' | |
| 29 | 35 | pub struct Foo; |
| 30 | 36 | |
| 31 | 37 | impl Foo { |
| 32 | 38 | pub async fn f() {} |
| 39 | pub async unsafe fn g() {} | |
| 33 | 40 | } |
src/test/ui/async-await/async-fn-nonsend.rs+7-8| ... | ... | @@ -2,15 +2,15 @@ |
| 2 | 2 | // edition:2018 |
| 3 | 3 | // compile-flags: --crate-type lib |
| 4 | 4 | |
| 5 | use std::{ | |
| 6 | cell::RefCell, | |
| 7 | fmt::Debug, | |
| 8 | rc::Rc, | |
| 9 | }; | |
| 5 | use std::{cell::RefCell, fmt::Debug, rc::Rc}; | |
| 10 | 6 | |
| 11 | fn non_sync() -> impl Debug { RefCell::new(()) } | |
| 7 | fn non_sync() -> impl Debug { | |
| 8 | RefCell::new(()) | |
| 9 | } | |
| 12 | 10 | |
| 13 | fn non_send() -> impl Debug { Rc::new(()) } | |
| 11 | fn non_send() -> impl Debug { | |
| 12 | Rc::new(()) | |
| 13 | } | |
| 14 | 14 | |
| 15 | 15 | fn take_ref<T>(_: &T) {} |
| 16 | 16 | |
| ... | ... | @@ -53,5 +53,4 @@ pub fn pass_assert() { |
| 53 | 53 | //~^ ERROR future cannot be sent between threads safely |
| 54 | 54 | assert_send(non_sync_with_method_call()); |
| 55 | 55 | //~^ ERROR future cannot be sent between threads safely |
| 56 | //~^^ ERROR future cannot be sent between threads safely | |
| 57 | 56 | } |
src/test/ui/async-await/async-fn-nonsend.stderr+1-23| ... | ... | @@ -62,27 +62,5 @@ LL | } |
| 62 | 62 | LL | } |
| 63 | 63 | | - `f` is later dropped here |
| 64 | 64 | |
| 65 | error: future cannot be sent between threads safely | |
| 66 | --> $DIR/async-fn-nonsend.rs:54:5 | |
| 67 | | | |
| 68 | LL | fn assert_send(_: impl Send) {} | |
| 69 | | ----------- ---- required by this bound in `assert_send` | |
| 70 | ... | |
| 71 | LL | 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)` | |
| 75 | note: future is not `Send` as this value is used across an await | |
| 76 | --> $DIR/async-fn-nonsend.rs:43:9 | |
| 77 | | | |
| 78 | LL | let f: &mut std::fmt::Formatter = panic!(); | |
| 79 | | - has type `&mut std::fmt::Formatter<'_>` | |
| 80 | LL | if non_sync().fmt(f).unwrap() == () { | |
| 81 | LL | fut().await; | |
| 82 | | ^^^^^^^^^^^ await occurs here, with `f` maybe used later | |
| 83 | LL | } | |
| 84 | LL | } | |
| 85 | | - `f` is later dropped here | |
| 86 | ||
| 87 | error: aborting due to 4 previous errors | |
| 65 | error: aborting due to 3 previous errors | |
| 88 | 66 |
src/test/ui/consts/array-literal-index-oob.rs+1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | // build-pass |
| 2 | // ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors) | |
| 2 | 3 | |
| 3 | 4 | #![warn(const_err)] |
| 4 | 5 |
src/test/ui/consts/array-literal-index-oob.stderr+4-4| ... | ... | @@ -1,17 +1,17 @@ |
| 1 | 1 | warning: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | &{ [1, 2, 3][4] }; |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | 7 | note: lint level defined here |
| 8 | --> $DIR/array-literal-index-oob.rs:3:9 | |
| 8 | --> $DIR/array-literal-index-oob.rs:4:9 | |
| 9 | 9 | | |
| 10 | 10 | LL | #![warn(const_err)] |
| 11 | 11 | | ^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | warning: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | &{ [1, 2, 3][4] }; |
| 17 | 17 | | ---^^^^^^^^^^^^-- |
| ... | ... | @@ -19,7 +19,7 @@ LL | &{ [1, 2, 3][4] }; |
| 19 | 19 | | indexing out of bounds: the len is 3 but the index is 4 |
| 20 | 20 | |
| 21 | 21 | warning: erroneous constant used |
| 22 | --> $DIR/array-literal-index-oob.rs:6:5 | |
| 22 | --> $DIR/array-literal-index-oob.rs:7:5 | |
| 23 | 23 | | |
| 24 | 24 | LL | &{ [1, 2, 3][4] }; |
| 25 | 25 | | ^^^^^^^^^^^^^^^^^ referenced constant has errors |
src/test/ui/consts/const-eval/promoted_errors.rs+1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | // build-pass |
| 2 | // ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors) | |
| 2 | 3 | // compile-flags: -O |
| 3 | 4 | |
| 4 | 5 | #![warn(const_err)] |
src/test/ui/consts/const-eval/promoted_errors.stderr+10-10| ... | ... | @@ -1,59 +1,59 @@ |
| 1 | 1 | warning: this expression will panic at runtime |
| 2 | --> $DIR/promoted_errors.rs:8:14 | |
| 2 | --> $DIR/promoted_errors.rs:9:14 | |
| 3 | 3 | | |
| 4 | 4 | LL | let _x = 0u32 - 1; |
| 5 | 5 | | ^^^^^^^^ attempt to subtract with overflow |
| 6 | 6 | | |
| 7 | 7 | note: lint level defined here |
| 8 | --> $DIR/promoted_errors.rs:4:9 | |
| 8 | --> $DIR/promoted_errors.rs:5:9 | |
| 9 | 9 | | |
| 10 | 10 | LL | #![warn(const_err)] |
| 11 | 11 | | ^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | warning: attempt to divide by zero |
| 14 | --> $DIR/promoted_errors.rs:10:20 | |
| 14 | --> $DIR/promoted_errors.rs:11:20 | |
| 15 | 15 | | |
| 16 | 16 | LL | println!("{}", 1 / (1 - 1)); |
| 17 | 17 | | ^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | warning: reaching this expression at runtime will panic or abort |
| 20 | --> $DIR/promoted_errors.rs:10:20 | |
| 20 | --> $DIR/promoted_errors.rs:11:20 | |
| 21 | 21 | | |
| 22 | 22 | LL | println!("{}", 1 / (1 - 1)); |
| 23 | 23 | | ^^^^^^^^^^^ dividing by zero |
| 24 | 24 | |
| 25 | 25 | warning: erroneous constant used |
| 26 | --> $DIR/promoted_errors.rs:10:20 | |
| 26 | --> $DIR/promoted_errors.rs:11:20 | |
| 27 | 27 | | |
| 28 | 28 | LL | println!("{}", 1 / (1 - 1)); |
| 29 | 29 | | ^^^^^^^^^^^ referenced constant has errors |
| 30 | 30 | |
| 31 | 31 | warning: attempt to divide by zero |
| 32 | --> $DIR/promoted_errors.rs:14:14 | |
| 32 | --> $DIR/promoted_errors.rs:15:14 | |
| 33 | 33 | | |
| 34 | 34 | LL | let _x = 1 / (1 - 1); |
| 35 | 35 | | ^^^^^^^^^^^ |
| 36 | 36 | |
| 37 | 37 | warning: attempt to divide by zero |
| 38 | --> $DIR/promoted_errors.rs:16:20 | |
| 38 | --> $DIR/promoted_errors.rs:17:20 | |
| 39 | 39 | | |
| 40 | 40 | LL | println!("{}", 1 / (false as u32)); |
| 41 | 41 | | ^^^^^^^^^^^^^^^^^^ |
| 42 | 42 | |
| 43 | 43 | warning: reaching this expression at runtime will panic or abort |
| 44 | --> $DIR/promoted_errors.rs:16:20 | |
| 44 | --> $DIR/promoted_errors.rs:17:20 | |
| 45 | 45 | | |
| 46 | 46 | LL | println!("{}", 1 / (false as u32)); |
| 47 | 47 | | ^^^^^^^^^^^^^^^^^^ dividing by zero |
| 48 | 48 | |
| 49 | 49 | warning: erroneous constant used |
| 50 | --> $DIR/promoted_errors.rs:16:20 | |
| 50 | --> $DIR/promoted_errors.rs:17:20 | |
| 51 | 51 | | |
| 52 | 52 | LL | println!("{}", 1 / (false as u32)); |
| 53 | 53 | | ^^^^^^^^^^^^^^^^^^ referenced constant has errors |
| 54 | 54 | |
| 55 | 55 | warning: attempt to divide by zero |
| 56 | --> $DIR/promoted_errors.rs:20:14 | |
| 56 | --> $DIR/promoted_errors.rs:21:14 | |
| 57 | 57 | | |
| 58 | 58 | LL | let _x = 1 / (false as u32); |
| 59 | 59 | | ^^^^^^^^^^^^^^^^^^ |
src/test/ui/consts/const-eval/promoted_errors2.rs+1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | // build-pass |
| 2 | // ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors) | |
| 2 | 3 | // compile-flags: -C overflow-checks=on -O |
| 3 | 4 | |
| 4 | 5 | #![warn(const_err)] |
src/test/ui/consts/const-eval/promoted_errors2.stderr+11-11| ... | ... | @@ -1,65 +1,65 @@ |
| 1 | 1 | warning: attempt to subtract with overflow |
| 2 | --> $DIR/promoted_errors2.rs:7:20 | |
| 2 | --> $DIR/promoted_errors2.rs:8:20 | |
| 3 | 3 | | |
| 4 | 4 | LL | println!("{}", 0u32 - 1); |
| 5 | 5 | | ^^^^^^^^ |
| 6 | 6 | | |
| 7 | 7 | note: lint level defined here |
| 8 | --> $DIR/promoted_errors2.rs:4:9 | |
| 8 | --> $DIR/promoted_errors2.rs:5:9 | |
| 9 | 9 | | |
| 10 | 10 | LL | #![warn(const_err)] |
| 11 | 11 | | ^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | warning: attempt to subtract with overflow |
| 14 | --> $DIR/promoted_errors2.rs:9:14 | |
| 14 | --> $DIR/promoted_errors2.rs:10:14 | |
| 15 | 15 | | |
| 16 | 16 | LL | let _x = 0u32 - 1; |
| 17 | 17 | | ^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | warning: attempt to divide by zero |
| 20 | --> $DIR/promoted_errors2.rs:11:20 | |
| 20 | --> $DIR/promoted_errors2.rs:12:20 | |
| 21 | 21 | | |
| 22 | 22 | LL | println!("{}", 1 / (1 - 1)); |
| 23 | 23 | | ^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | warning: reaching this expression at runtime will panic or abort |
| 26 | --> $DIR/promoted_errors2.rs:11:20 | |
| 26 | --> $DIR/promoted_errors2.rs:12:20 | |
| 27 | 27 | | |
| 28 | 28 | LL | println!("{}", 1 / (1 - 1)); |
| 29 | 29 | | ^^^^^^^^^^^ dividing by zero |
| 30 | 30 | |
| 31 | 31 | warning: erroneous constant used |
| 32 | --> $DIR/promoted_errors2.rs:11:20 | |
| 32 | --> $DIR/promoted_errors2.rs:12:20 | |
| 33 | 33 | | |
| 34 | 34 | LL | println!("{}", 1 / (1 - 1)); |
| 35 | 35 | | ^^^^^^^^^^^ referenced constant has errors |
| 36 | 36 | |
| 37 | 37 | warning: attempt to divide by zero |
| 38 | --> $DIR/promoted_errors2.rs:15:14 | |
| 38 | --> $DIR/promoted_errors2.rs:16:14 | |
| 39 | 39 | | |
| 40 | 40 | LL | let _x = 1 / (1 - 1); |
| 41 | 41 | | ^^^^^^^^^^^ |
| 42 | 42 | |
| 43 | 43 | warning: attempt to divide by zero |
| 44 | --> $DIR/promoted_errors2.rs:17:20 | |
| 44 | --> $DIR/promoted_errors2.rs:18:20 | |
| 45 | 45 | | |
| 46 | 46 | LL | println!("{}", 1 / (false as u32)); |
| 47 | 47 | | ^^^^^^^^^^^^^^^^^^ |
| 48 | 48 | |
| 49 | 49 | warning: reaching this expression at runtime will panic or abort |
| 50 | --> $DIR/promoted_errors2.rs:17:20 | |
| 50 | --> $DIR/promoted_errors2.rs:18:20 | |
| 51 | 51 | | |
| 52 | 52 | LL | println!("{}", 1 / (false as u32)); |
| 53 | 53 | | ^^^^^^^^^^^^^^^^^^ dividing by zero |
| 54 | 54 | |
| 55 | 55 | warning: erroneous constant used |
| 56 | --> $DIR/promoted_errors2.rs:17:20 | |
| 56 | --> $DIR/promoted_errors2.rs:18:20 | |
| 57 | 57 | | |
| 58 | 58 | LL | println!("{}", 1 / (false as u32)); |
| 59 | 59 | | ^^^^^^^^^^^^^^^^^^ referenced constant has errors |
| 60 | 60 | |
| 61 | 61 | warning: attempt to divide by zero |
| 62 | --> $DIR/promoted_errors2.rs:21:14 | |
| 62 | --> $DIR/promoted_errors2.rs:22:14 | |
| 63 | 63 | | |
| 64 | 64 | LL | let _x = 1 / (false as u32); |
| 65 | 65 | | ^^^^^^^^^^^^^^^^^^ |
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 | |
| 7 | pub trait Query {} | |
| 8 | ||
| 9 | pub trait AsQuery { | |
| 10 | type Query: Query; | |
| 11 | } | |
| 12 | pub trait Table: AsQuery + Sized {} | |
| 13 | ||
| 14 | pub trait LimitDsl { | |
| 15 | type Output; | |
| 16 | } | |
| 17 | ||
| 18 | pub(crate) trait LoadQuery<Conn, U>: RunQueryDsl<Conn> {} | |
| 19 | ||
| 20 | impl<T: Query> AsQuery for T { | |
| 21 | type Query = Self; | |
| 22 | } | |
| 23 | ||
| 24 | impl<T> LimitDsl for T | |
| 25 | where | |
| 26 | T: Table, | |
| 27 | T::Query: LimitDsl, | |
| 28 | { | |
| 29 | type Output = <T::Query as LimitDsl>::Output; | |
| 30 | } | |
| 31 | ||
| 32 | pub(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 | ||
| 43 | fn 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 | ||
| 5 | fn pass_to_ptr_call<T>(f: fn(T), x: T) { | |
| 6 | f(x); | |
| 7 | } | |
| 8 | ||
| 9 | #[track_caller] | |
| 10 | fn 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 | ||
| 17 | fn 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 | ||
| 5 | fn ptr_call(f: fn()) { | |
| 6 | f(); | |
| 7 | } | |
| 8 | ||
| 9 | #[track_caller] | |
| 10 | fn 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 | ||
| 17 | fn main() { | |
| 18 | ptr_call(tracked); | |
| 19 | } |
src/tools/build-manifest/src/main.rs+1| ... | ... | @@ -110,6 +110,7 @@ static TARGETS: &[&str] = &[ |
| 110 | 110 | "riscv32imac-unknown-none-elf", |
| 111 | 111 | "riscv64imac-unknown-none-elf", |
| 112 | 112 | "riscv64gc-unknown-none-elf", |
| 113 | "riscv64gc-unknown-linux-gnu", | |
| 113 | 114 | "s390x-unknown-linux-gnu", |
| 114 | 115 | "sparc64-unknown-linux-gnu", |
| 115 | 116 | "sparcv9-sun-solaris", |