diff options
Diffstat (limited to 'compiler')
24 files changed, 275 insertions, 107 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 6b7d0e1f204..00d75be4399 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -72,13 +72,9 @@ impl Path { ) -> ast::Path { let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect(); let lt = mk_lifetimes(cx, span, &self.lifetime); - let tys: Vec<P<ast::Ty>> = - self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect(); - let params = lt - .into_iter() - .map(GenericArg::Lifetime) - .chain(tys.into_iter().map(GenericArg::Type)) - .collect(); + let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)); + let params = + lt.into_iter().map(GenericArg::Lifetime).chain(tys.map(GenericArg::Type)).collect(); match self.kind { PathKind::Global => cx.path_all(span, true, idents, params), diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index df162f8dce0..1aa5f995974 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -418,6 +418,7 @@ E0716: include_str!("./error_codes/E0716.md"), E0718: include_str!("./error_codes/E0718.md"), E0719: include_str!("./error_codes/E0719.md"), E0720: include_str!("./error_codes/E0720.md"), +E0722: include_str!("./error_codes/E0722.md"), E0724: include_str!("./error_codes/E0724.md"), E0725: include_str!("./error_codes/E0725.md"), E0727: include_str!("./error_codes/E0727.md"), @@ -449,6 +450,7 @@ E0753: include_str!("./error_codes/E0753.md"), E0754: include_str!("./error_codes/E0754.md"), E0755: include_str!("./error_codes/E0755.md"), E0756: include_str!("./error_codes/E0756.md"), +E0757: include_str!("./error_codes/E0757.md"), E0758: include_str!("./error_codes/E0758.md"), E0759: include_str!("./error_codes/E0759.md"), E0760: include_str!("./error_codes/E0760.md"), @@ -634,10 +636,8 @@ E0783: include_str!("./error_codes/E0783.md"), E0711, // a feature has been declared with conflicting stability attributes E0717, // rustc_promotable without stability attribute // E0721, // `await` keyword - E0722, // Malformed `#[optimize]` attribute // E0723, unstable feature in `const` context E0726, // non-explicit (not `'_`) elided lifetime in unsupported position // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. - E0757, // `#[ffi_const]` functions cannot be `#[ffi_pure]` E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`. } diff --git a/compiler/rustc_error_codes/src/error_codes/E0722.md b/compiler/rustc_error_codes/src/error_codes/E0722.md new file mode 100644 index 00000000000..570717a92bd --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0722.md @@ -0,0 +1,31 @@ +The `optimize` attribute was malformed. + +Erroneous code example: + +```compile_fail,E0722 +#![feature(optimize_attribute)] + +#[optimize(something)] // error: invalid argument +pub fn something() {} +``` + +The `#[optimize]` attribute should be used as follows: + +- `#[optimize(size)]` -- instructs the optimization pipeline to generate code + that's smaller rather than faster + +- `#[optimize(speed)]` -- instructs the optimization pipeline to generate code + that's faster rather than smaller + +For example: + +``` +#![feature(optimize_attribute)] + +#[optimize(size)] +pub fn something() {} +``` + +See [RFC 2412] for more details. + +[RFC 2412]: https://rust-lang.github.io/rfcs/2412-optimize-attr.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0757.md b/compiler/rustc_error_codes/src/error_codes/E0757.md new file mode 100644 index 00000000000..41b06b23c4f --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0757.md @@ -0,0 +1,33 @@ +A function was given both the `ffi_const` and `ffi_pure` attributes. + +Erroneous code example: + +```compile_fail,E0757 +#![feature(ffi_const, ffi_pure)] + +extern "C" { + #[ffi_const] + #[ffi_pure] // error: `#[ffi_const]` function cannot be `#[ffi_pure]` + pub fn square(num: i32) -> i32; +} +``` + +As `ffi_const` provides stronger guarantees than `ffi_pure`, remove the +`ffi_pure` attribute: + +``` +#![feature(ffi_const)] + +extern "C" { + #[ffi_const] + pub fn square(num: i32) -> i32; +} +``` + +You can get more information about `const` and `pure` in the [GCC documentation +on Common Function Attributes]. The unstable Rust Book has more information +about [`ffi_const`] and [`ffi_pure`]. + +[GCC documentation on Common Function Attributes]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html +[`ffi_const`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/ffi-const.html +[`ffi_pure`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/ffi-pure.html diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5c7d10560ca..6aff2fdbd1f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3060,6 +3060,27 @@ impl<'hir> Node<'hir> { Node::Crate(_) | Node::Visibility(_) => None, } } + + /// Returns `Constness::Const` when this node is a const fn/impl. + pub fn constness(&self) -> Constness { + match self { + Node::Item(Item { + kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::TraitItem(TraitItem { + kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::ImplItem(ImplItem { + kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness, + + _ => Constness::NotConst, + } + } } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index ac953f4305c..448dd662348 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -102,20 +102,11 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { ) } - /// A hacky variant of `canonicalize_query` that does not - /// canonicalize `'static`. Unfortunately, the existing leak - /// check treats `'static` differently in some cases (see also - /// #33684), so if we are performing an operation that may need to - /// prove "leak-check" related things, we leave `'static` - /// alone. - /// - /// `'static` is also special cased when winnowing candidates when - /// selecting implementation candidates, so we also have to leave `'static` - /// alone for queries that do selection. - // - // FIXME(#48536): once the above issues are resolved, we can remove this - // and just use `canonicalize_query`. - pub fn canonicalize_hr_query_hack<V>( + /// A variant of `canonicalize_query` that does not + /// canonicalize `'static`. This is useful when + /// the query implementation can perform more efficient + /// handling of `'static` regions (e.g. trait evaluation). + pub fn canonicalize_query_keep_static<V>( &self, value: V, query_state: &mut OriginalQueryValues<'tcx>, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 670129937be..f885c0a4b87 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -995,7 +995,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let get_lifetimes = |sig| { use rustc_hir::def::Namespace; let mut s = String::new(); - let (_, (sig, reg)) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS) + let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS) .name_all_regions(sig) .unwrap(); let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect(); @@ -2130,7 +2130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let new_lt = generics .as_ref() .and_then(|(parent_g, g)| { - let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect(); + let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char)); let mut lts_names = g .params .iter() @@ -2146,7 +2146,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::<Vec<_>>(); - possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str())) + possible.find(|candidate| !lts.contains(&candidate.as_str())) }) .unwrap_or("'lt".to_string()); let add_lt_sugg = generics diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index b3d7876c6e8..4af1bdf97a7 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -47,16 +47,18 @@ pub struct TypeFreshener<'a, 'tcx> { const_freshen_count: u32, ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>, const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>, + keep_static: bool, } impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> TypeFreshener<'a, 'tcx> { + pub fn new(infcx: &'a InferCtxt<'a, 'tcx>, keep_static: bool) -> TypeFreshener<'a, 'tcx> { TypeFreshener { infcx, ty_freshen_count: 0, const_freshen_count: 0, ty_freshen_map: Default::default(), const_freshen_map: Default::default(), + keep_static, } } @@ -124,8 +126,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { r } - ty::ReStatic - | ty::ReEarlyBound(..) + ty::ReEarlyBound(..) | ty::ReFree(_) | ty::ReVar(_) | ty::RePlaceholder(..) @@ -134,6 +135,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { // replace all free regions with 'erased self.tcx().lifetimes.re_erased } + ty::ReStatic => { + if self.keep_static { + r + } else { + self.tcx().lifetimes.re_erased + } + } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f39431f2494..d3bfb2b2e44 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -646,7 +646,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { - freshen::TypeFreshener::new(self) + freshen::TypeFreshener::new(self, false) + } + + /// Like `freshener`, but does not replace `'static` regions. + pub fn freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { + freshen::TypeFreshener::new(self, true) } pub fn type_is_unconstrained_numeric(&'a self, ty: Ty<'_>) -> UnconstrainedNumeric { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c16d46efb88..f448acd24fc 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -370,7 +370,7 @@ impl LintStore { match level { Level::Allow => "-A", Level::Warn => "-W", - Level::ForceWarn => "--force-warns", + Level::ForceWarn => "--force-warn", Level::Deny => "-D", Level::Forbid => "-F", }, diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 4d85bf6b499..4190e769976 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -64,7 +64,7 @@ impl Level { match self { Level::Allow => "allow", Level::Warn => "warn", - Level::ForceWarn => "force-warns", + Level::ForceWarn => "force-warn", Level::Deny => "deny", Level::Forbid => "forbid", } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 848e60fe134..6ad68877235 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -288,7 +288,7 @@ pub fn struct_lint_level<'s, 'd>( Level::Deny => "-D", Level::Forbid => "-F", Level::Allow => "-A", - Level::ForceWarn => "--force-warns", + Level::ForceWarn => "--force-warn", }; let hyphen_case_lint_name = name.replace("_", "-"); if lint_flag_val.as_str() == name { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6dfbd28f776..b5733bd2edc 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1776,13 +1776,73 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> { } } +/// Folds through bound vars and placeholders, naming them +struct RegionFolder<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + current_index: ty::DebruijnIndex, + region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>, + name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a), +} + +impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_binder<T: TypeFoldable<'tcx>>( + &mut self, + t: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { + self.current_index.shift_in(1); + let t = t.super_fold_with(self); + self.current_index.shift_out(1); + t + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match *t.kind() { + _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => { + return t.super_fold_with(self); + } + _ => {} + } + t + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + let name = &mut self.name; + let region = match *r { + ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)), + ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => { + // If this is an anonymous placeholder, don't rename. Otherwise, in some + // async fns, we get a `for<'r> Send` bound + match kind { + ty::BrAnon(_) | ty::BrEnv => r, + _ => { + // Index doesn't matter, since this is just for naming and these never get bound + let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind }; + self.region_map.entry(br).or_insert_with(|| name(br)) + } + } + } + _ => return r, + }; + if let ty::ReLateBound(debruijn1, br) = *region { + assert_eq!(debruijn1, ty::INNERMOST); + self.tcx.mk_region(ty::ReLateBound(self.current_index, br)) + } else { + region + } + } +} + // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, // `region_index` and `used_region_names`. impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { pub fn name_all_regions<T>( mut self, value: &ty::Binder<'tcx, T>, - ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error> + ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error> where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, { @@ -1805,16 +1865,16 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - write!( - cx, - "{}", - if empty { - empty = false; - start - } else { - cont - } - ) + let w = if empty { + empty = false; + start + } else { + cont + }; + let _ = write!(cx, "{}", w); + }; + let do_continue = |cx: &mut Self, cont: Symbol| { + let _ = write!(cx, "{}", cont); }; define_scoped_cx!(self); @@ -1824,18 +1884,18 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { // aren't named. Eventually, we might just want this as the default, but // this is not *quite* right and changes the ordering of some output // anyways. - let new_value = if self.tcx().sess.verbose() { + let (new_value, map) = if self.tcx().sess.verbose() { // anon index + 1 (BrEnv takes 0) -> name let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default(); let bound_vars = value.bound_vars(); for var in bound_vars { match var { ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => { - let _ = start_or_continue(&mut self, "for<", ", "); - let _ = write!(self, "{}", name); + start_or_continue(&mut self, "for<", ", "); + do_continue(&mut self, name); } ty::BoundVariableKind::Region(ty::BrAnon(i)) => { - let _ = start_or_continue(&mut self, "for<", ", "); + start_or_continue(&mut self, "for<", ", "); let name = loop { let name = name_by_region_index(region_index); region_index += 1; @@ -1843,11 +1903,11 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { break name; } }; - let _ = write!(self, "{}", name); + do_continue(&mut self, name); region_map.insert(i + 1, name); } ty::BoundVariableKind::Region(ty::BrEnv) => { - let _ = start_or_continue(&mut self, "for<", ", "); + start_or_continue(&mut self, "for<", ", "); let name = loop { let name = name_by_region_index(region_index); region_index += 1; @@ -1855,13 +1915,13 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { break name; } }; - let _ = write!(self, "{}", name); + do_continue(&mut self, name); region_map.insert(0, name); } _ => continue, } } - start_or_continue(&mut self, "", "> ")?; + start_or_continue(&mut self, "", "> "); self.tcx.replace_late_bound_regions(value.clone(), |br| { let kind = match br.kind { @@ -1881,11 +1941,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { )) }) } else { - let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| { - let _ = start_or_continue(&mut self, "for<", ", "); + let tcx = self.tcx; + let mut name = |br: ty::BoundRegion| { + start_or_continue(&mut self, "for<", ", "); let kind = match br.kind { ty::BrNamed(_, name) => { - let _ = write!(self, "{}", name); + do_continue(&mut self, name); br.kind } ty::BrAnon(_) | ty::BrEnv => { @@ -1896,22 +1957,27 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { break name; } }; - let _ = write!(self, "{}", name); + do_continue(&mut self, name); ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) } }; - self.tcx.mk_region(ty::ReLateBound( - ty::INNERMOST, - ty::BoundRegion { var: br.var, kind }, - )) - }); - start_or_continue(&mut self, "", "> ")?; - new_value + tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })) + }; + let mut folder = RegionFolder { + tcx, + current_index: ty::INNERMOST, + name: &mut name, + region_map: BTreeMap::new(), + }; + let new_value = value.clone().skip_binder().fold_with(&mut folder); + let region_map = folder.region_map; + start_or_continue(&mut self, "", "> "); + (new_value, region_map) }; self.binder_depth += 1; self.region_index = region_index; - Ok((self, new_value)) + Ok((self, new_value, map)) } pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error> @@ -1919,8 +1985,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, { let old_region_index = self.region_index; - let (new, new_value) = self.name_all_regions(value)?; - let mut inner = new_value.0.print(new)?; + let (new, new_value, _) = self.name_all_regions(value)?; + let mut inner = new_value.print(new)?; inner.region_index = old_region_index; inner.binder_depth -= 1; Ok(inner) @@ -1935,8 +2001,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, { let old_region_index = self.region_index; - let (new, new_value) = self.name_all_regions(value)?; - let mut inner = f(&new_value.0, new)?; + let (new, new_value, _) = self.name_all_regions(value)?; + let mut inner = f(&new_value, new)?; inner.region_index = old_region_index; inner.binder_depth -= 1; Ok(inner) @@ -1960,6 +2026,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r); if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r { self.used_region_names.insert(name); + } else if let ty::RePlaceholder(ty::PlaceholderRegion { + name: ty::BrNamed(_, name), + .. + }) = *r + { + self.used_region_names.insert(name); } r.super_visit_with(self) } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs index feb7672f650..1460c2378d1 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::symbol::{kw, sym}; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use crate::util::borrowck_errors; @@ -641,12 +641,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { "'_".to_string() }; - let suggestion = if snippet.ends_with(';') { + let span = if snippet.ends_with(';') { // `type X = impl Trait;` - format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name) + span.with_hi(span.hi() - BytePos(1)) } else { - format!("{} + {}", snippet, suggestable_fr_name) + span }; + let suggestion = format!(" + {}", suggestable_fr_name); + let span = span.shrink_to_hi(); diag.span_suggestion( span, &format!( diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 646ae8ced7e..cfc538ef500 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -897,16 +897,19 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { permitted = true; } } - let mut const_impls = true; - tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| { - if const_impls { - if let hir::Constness::NotConst = tcx.impl_constness(imp) { - const_impls = false; + if !permitted { + // if trait's impls are all const, permit the call. + let mut const_impls = true; + tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| { + if const_impls { + if let hir::Constness::NotConst = tcx.impl_constness(imp) { + const_impls = false; + } } + }); + if const_impls { + permitted = true; } - }); - if const_impls { - permitted = true; } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 9e5a38b8dc0..2d7f5f9b321 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1101,7 +1101,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> { ), opt::multi_s( "", - "force-warns", + "force-warn", "Specifiy lints that should warn even if \ they are allowed somewhere else", "LINT", @@ -1175,11 +1175,11 @@ pub fn get_cmd_lint_options( let mut lint_opts_with_position = vec![]; let mut describe_lints = false; - if !debugging_opts.unstable_options && matches.opt_present("force-warns") { + if !debugging_opts.unstable_options && matches.opt_present("force-warn") { early_error( error_format, "the `-Z unstable-options` flag must also be passed to enable \ - the flag `--force-warns=lints`", + the flag `--force-warn=lints`", ); } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index dfe2909498d..9ec1dd5c2ee 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -365,6 +365,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let project_obligation = obligation.with(binder.rebind(data)); self.process_projection_obligation( + obligation, project_obligation, &mut pending_obligation.stalled_on, ) @@ -419,6 +420,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let project_obligation = obligation.with(Binder::dummy(*data)); self.process_projection_obligation( + obligation, project_obligation, &mut pending_obligation.stalled_on, ) @@ -666,10 +668,22 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { fn process_projection_obligation( &mut self, + obligation: &PredicateObligation<'tcx>, project_obligation: PolyProjectionObligation<'tcx>, stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>, ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> { let tcx = self.selcx.tcx(); + + if obligation.predicate.is_global() { + // no type variables present, can use evaluation for better caching. + // FIXME: consider caching errors too. + if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) { + return ProcessResult::Changed(vec![]); + } else { + tracing::debug!("Does NOT hold: {:?}", obligation); + } + } + match project::poly_project_and_unify_type(self.selcx, &project_obligation) { Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)), Ok(Ok(None)) => { diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index b83a4cd1e57..2dc48e47efc 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -64,8 +64,10 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError> { let mut _orig_values = OriginalQueryValues::default(); - let c_pred = self - .canonicalize_query(obligation.param_env.and(obligation.predicate), &mut _orig_values); + let c_pred = self.canonicalize_query_keep_static( + obligation.param_env.and(obligation.predicate), + &mut _orig_values, + ); // Run canonical query. If overflow occurs, rerun from scratch but this time // in standard trait query mode so that overflow is handled appropriately // within `SelectionContext`. diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index d65a378b1ed..3f6efa03b3a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -180,7 +180,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // so we cannot canonicalize it. let c_data = self .infcx - .canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values); + .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); match tcx.normalize_projection_ty(c_data) { @@ -249,7 +249,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // so we cannot canonicalize it. let c_data = self .infcx - .canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values); + .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); let normalized_ty = match tcx.normalize_projection_ty(c_data) { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 130ffa1a33a..fbff86618ad 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -77,12 +77,13 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx { } // FIXME(#33684) -- We need to use - // `canonicalize_hr_query_hack` here because of things + // `canonicalize_query_keep_static` here because of things // like the subtype query, which go awry around // `'static` otherwise. let mut canonical_var_values = OriginalQueryValues::default(); let old_param_env = query_key.param_env; - let canonical_self = infcx.canonicalize_hr_query_hack(query_key, &mut canonical_var_values); + let canonical_self = + infcx.canonicalize_query_keep_static(query_key, &mut canonical_var_values); let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?; let InferOk { value, obligations } = infcx diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1bdc8b34cf6..95611ebc818 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -216,7 +216,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, - freshener: infcx.freshener(), + freshener: infcx.freshener_keep_static(), intercrate: false, intercrate_ambiguity_causes: None, allow_negative_impls: false, @@ -227,7 +227,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, - freshener: infcx.freshener(), + freshener: infcx.freshener_keep_static(), intercrate: true, intercrate_ambiguity_causes: None, allow_negative_impls: false, @@ -242,7 +242,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?allow_negative_impls, "with_negative"); SelectionContext { infcx, - freshener: infcx.freshener(), + freshener: infcx.freshener_keep_static(), intercrate: false, intercrate_ambiguity_causes: None, allow_negative_impls, @@ -257,7 +257,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?query_mode, "with_query_mode"); SelectionContext { infcx, - freshener: infcx.freshener(), + freshener: infcx.freshener_keep_static(), intercrate: false, intercrate_ambiguity_causes: None, allow_negative_impls: false, diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 2e42d65cce2..f55e274ef8e 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -838,6 +838,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { this does nothing because the given bound is not \ a default; only `?Sized` is supported", ); + return false; } } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 4da4835f7cf..13686cfec80 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -15,7 +15,6 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; @@ -175,13 +174,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } fn default_constness_for_trait_bounds(&self) -> hir::Constness { - // FIXME: refactor this into a method - let node = self.tcx.hir().get(self.body_id); - if let Some(fn_like) = FnLikeNode::from_node(node) { - fn_like.constness() - } else { - hir::Constness::NotConst - } + self.tcx.hir().get(self.body_id).constness() } fn get_type_parameter_bounds( diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 506ca98b960..1a4c2eb5155 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -35,7 +35,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::weak_lang_items; use rustc_hir::{GenericParamKind, HirId, Node}; -use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::hir::map::Map; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::Linkage; @@ -358,11 +357,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn default_constness_for_trait_bounds(&self) -> hir::Constness { - if let Some(fn_like) = FnLikeNode::from_node(self.node()) { - fn_like.constness() - } else { - hir::Constness::NotConst - } + self.node().constness() } fn get_type_parameter_bounds( |
