Skip to content
Permalink
Browse files

rustc: replace `GenericArgs::with_generic_args` hack with a plain get…

…ter.
  • Loading branch information...
eddyb committed Jun 12, 2019
1 parent e79b2a1 commit 887feeeaf7d40c25caa9532f2d9121cb79fca899
Showing with 91 additions and 102 deletions.
  1. +7 −11 src/librustc/hir/mod.rs
  2. +19 −30 src/librustc/hir/print.rs
  3. +50 −56 src/librustc_typeck/astconv.rs
  4. +4 −3 src/librustdoc/clean/mod.rs
  5. +2 −0 src/libsyntax/lib.rs
  6. +9 −2 src/libsyntax/ptr.rs
@@ -383,17 +383,13 @@ impl PathSegment {
}
}

// FIXME: hack required because you can't create a static
// `GenericArgs`, so you can't just return a `&GenericArgs`.
pub fn with_generic_args<F, R>(&self, f: F) -> R
where F: FnOnce(&GenericArgs) -> R
{
let dummy = GenericArgs::none();
f(if let Some(ref args) = self.args {
&args
pub fn generic_args(&self) -> &GenericArgs {
if let Some(ref args) = self.args {
args
} else {
&dummy
})
const DUMMY: &GenericArgs = &GenericArgs::none();
DUMMY
}
}
}

@@ -449,7 +445,7 @@ pub struct GenericArgs {
}

impl GenericArgs {
pub fn none() -> Self {
pub const fn none() -> Self {
Self {
args: HirVec::new(),
bindings: HirVec::new(),
@@ -1194,12 +1194,11 @@ impl<'a> State<'a> {
self.s.word(".")?;
self.print_ident(segment.ident)?;

segment.with_generic_args(|generic_args| {
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
return self.print_generic_args(&generic_args, segment.infer_args, true);
}
Ok(())
})?;
let generic_args = segment.generic_args();
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
self.print_generic_args(generic_args, segment.infer_args, true)?;
}

self.print_call_post(base_args)
}

@@ -1559,11 +1558,9 @@ impl<'a> State<'a> {
self.s.word("::")?
}
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args, segment.infer_args,
colons_before_params)
})?;
self.print_ident(segment.ident)?;
self.print_generic_args(segment.generic_args(), segment.infer_args,
colons_before_params)?;
}
}

@@ -1572,10 +1569,8 @@ impl<'a> State<'a> {

pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> {
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args, segment.infer_args, false)
})?;
self.print_ident(segment.ident)?;
self.print_generic_args(segment.generic_args(), segment.infer_args, false)?;
}
Ok(())
}
@@ -1600,35 +1595,29 @@ impl<'a> State<'a> {
}
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args,
segment.infer_args,
colons_before_params)
})?;
self.print_generic_args(segment.generic_args(),
segment.infer_args,
colons_before_params)?;
}
}

self.s.word(">")?;
self.s.word("::")?;
let item_segment = path.segments.last().unwrap();
self.print_ident(item_segment.ident)?;
item_segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args,
item_segment.infer_args,
colons_before_params)
})
self.print_generic_args(item_segment.generic_args(),
item_segment.infer_args,
colons_before_params)
}
hir::QPath::TypeRelative(ref qself, ref item_segment) => {
self.s.word("<")?;
self.print_type(qself)?;
self.s.word(">")?;
self.s.word("::")?;
self.print_ident(item_segment.ident)?;
item_segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args,
item_segment.infer_args,
colons_before_params)
})
self.print_generic_args(item_segment.generic_args(),
item_segment.infer_args,
colons_before_params)
}
}
}
@@ -191,15 +191,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
item_segment: &hir::PathSegment)
-> SubstsRef<'tcx>
{
let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| {
self.create_substs_for_ast_path(
span,
def_id,
generic_args,
item_segment.infer_args,
None,
)
});
let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
span,
def_id,
item_segment.generic_args(),
item_segment.infer_args,
None,
);

assoc_bindings.first().map(|b| Self::prohibit_assoc_ty_binding(self.tcx(), b.span));

@@ -874,8 +872,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let trait_def = self.tcx().trait_def(trait_def_id);

if !self.tcx().features().unboxed_closures &&
trait_segment.with_generic_args(|generic_args| generic_args.parenthesized)
!= trait_def.paren_sugar {
trait_segment.generic_args().parenthesized != trait_def.paren_sugar
{
// For now, require that parenthetical notation be used only with `Fn()` etc.
let msg = if trait_def.paren_sugar {
"the precise format of `Fn`-family traits' type parameters is subject to change. \
@@ -887,13 +885,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span, GateIssue::Language, msg);
}

trait_segment.with_generic_args(|generic_args| {
self.create_substs_for_ast_path(span,
trait_def_id,
generic_args,
trait_segment.infer_args,
Some(self_ty))
})
self.create_substs_for_ast_path(span,
trait_def_id,
trait_segment.generic_args(),
trait_segment.infer_args,
Some(self_ty))
}

fn trait_defines_associated_type_named(&self,
@@ -1765,47 +1761,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self, segments: T) -> bool {
let mut has_err = false;
for segment in segments {
segment.with_generic_args(|generic_args| {
let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in &generic_args.args {
let (span, kind) = match arg {
hir::GenericArg::Lifetime(lt) => {
if err_for_lt { continue }
err_for_lt = true;
has_err = true;
(lt.span, "lifetime")
}
hir::GenericArg::Type(ty) => {
if err_for_ty { continue }
err_for_ty = true;
has_err = true;
(ty.span, "type")
}
hir::GenericArg::Const(ct) => {
if err_for_ct { continue }
err_for_ct = true;
(ct.span, "const")
}
};
let mut err = struct_span_err!(
self.tcx().sess,
span,
E0109,
"{} arguments are not allowed for this type",
kind,
);
err.span_label(span, format!("{} argument not allowed", kind));
err.emit();
if err_for_lt && err_for_ty && err_for_ct {
break;
let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in &segment.generic_args().args {
let (span, kind) = match arg {
hir::GenericArg::Lifetime(lt) => {
if err_for_lt { continue }
err_for_lt = true;
has_err = true;
(lt.span, "lifetime")
}
}
for binding in &generic_args.bindings {
has_err = true;
Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
hir::GenericArg::Type(ty) => {
if err_for_ty { continue }
err_for_ty = true;
has_err = true;
(ty.span, "type")
}
hir::GenericArg::Const(ct) => {
if err_for_ct { continue }
err_for_ct = true;
(ct.span, "const")
}
};
let mut err = struct_span_err!(
self.tcx().sess,
span,
E0109,
"{} arguments are not allowed for this type",
kind,
);
err.span_label(span, format!("{} argument not allowed", kind));
err.emit();
if err_for_lt && err_for_ty && err_for_ct {
break;
}
})
}
for binding in &segment.generic_args().bindings {
has_err = true;
Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
break;
}
}
has_err
}
@@ -2809,7 +2809,8 @@ impl Clean<Type> for hir::Ty {
let mut ty_substs = FxHashMap::default();
let mut lt_substs = FxHashMap::default();
let mut ct_substs = FxHashMap::default();
provided_params.with_generic_args(|generic_args| {
let generic_args = provided_params.generic_args();
{
let mut indices: GenericParamCount = Default::default();
for param in generics.params.iter() {
match param.kind {
@@ -2884,7 +2885,7 @@ impl Clean<Type> for hir::Ty {
}
}
}
});
}
return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
}
resolve_type(cx, path.clean(cx), self.hir_id)
@@ -3537,7 +3538,7 @@ impl Clean<PathSegment> for hir::PathSegment {
fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
PathSegment {
name: self.ident.name.clean(cx),
args: self.with_generic_args(|generic_args| generic_args.clean(cx))
args: self.generic_args().clean(cx),
}
}
}
@@ -12,6 +12,8 @@
#![deny(unused_lifetimes)]

#![feature(bind_by_move_pattern_guards)]
#![feature(const_fn)]
#![feature(const_transmute)]
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]
#![feature(nll)]
@@ -133,8 +133,15 @@ impl<T: Encodable> Encodable for P<T> {
}

impl<T> P<[T]> {
pub fn new() -> P<[T]> {
P { ptr: Default::default() }
pub const fn new() -> P<[T]> {
// HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>`
// (as trait methods, `default` in this case, can't be `const fn` yet).
P {
ptr: unsafe {
use std::ptr::NonNull;
std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>)
},
}
}

#[inline(never)]

0 comments on commit 887feee

Please sign in to comment.
You can’t perform that action at this time.